xref: /freebsd/contrib/tcpdump/print-sll.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
1685295f4SBill Fenner /*
2685295f4SBill Fenner  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3685295f4SBill Fenner  *	The Regents of the University of California.  All rights reserved.
4685295f4SBill Fenner  *
5685295f4SBill Fenner  * Redistribution and use in source and binary forms, with or without
6685295f4SBill Fenner  * modification, are permitted provided that: (1) source code distributions
7685295f4SBill Fenner  * retain the above copyright notice and this paragraph in its entirety, (2)
8685295f4SBill Fenner  * distributions including binary code include the above copyright notice and
9685295f4SBill Fenner  * this paragraph in its entirety in the documentation or other materials
10685295f4SBill Fenner  * provided with the distribution, and (3) all advertising materials mentioning
11685295f4SBill Fenner  * features or use of this software display the following acknowledgement:
12685295f4SBill Fenner  * ``This product includes software developed by the University of California,
13685295f4SBill Fenner  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14685295f4SBill Fenner  * the University nor the names of its contributors may be used to endorse
15685295f4SBill Fenner  * or promote products derived from this software without specific prior
16685295f4SBill Fenner  * written permission.
17685295f4SBill Fenner  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18685295f4SBill Fenner  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19685295f4SBill Fenner  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20685295f4SBill Fenner  */
21685295f4SBill Fenner 
223340d773SGleb Smirnoff /* \summary: Linux cooked sockets capture printer */
233340d773SGleb Smirnoff 
24*ee67461eSJoseph Mingrone #include <config.h>
25685295f4SBill Fenner 
26*ee67461eSJoseph Mingrone #ifdef HAVE_NET_IF_H
27*ee67461eSJoseph Mingrone /*
28*ee67461eSJoseph Mingrone  * Include diag-control.h before <net/if.h>, which too defines a macro
29*ee67461eSJoseph Mingrone  * named ND_UNREACHABLE.
30*ee67461eSJoseph Mingrone  */
31*ee67461eSJoseph Mingrone #include "diag-control.h"
32*ee67461eSJoseph Mingrone #include <net/if.h>
33*ee67461eSJoseph Mingrone #endif
34685295f4SBill Fenner 
35*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
36*ee67461eSJoseph Mingrone 
37*ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK
383340d773SGleb Smirnoff #include "netdissect.h"
39685295f4SBill Fenner #include "addrtoname.h"
40685295f4SBill Fenner #include "ethertype.h"
411de50e9fSSam Leffler #include "extract.h"
42685295f4SBill Fenner 
433c602fabSXin LI /*
443c602fabSXin LI  * For captures on Linux cooked sockets, we construct a fake header
453c602fabSXin LI  * that includes:
463c602fabSXin LI  *
473c602fabSXin LI  *	a 2-byte "packet type" which is one of:
483c602fabSXin LI  *
493c602fabSXin LI  *		LINUX_SLL_HOST		packet was sent to us
503c602fabSXin LI  *		LINUX_SLL_BROADCAST	packet was broadcast
513c602fabSXin LI  *		LINUX_SLL_MULTICAST	packet was multicast
523c602fabSXin LI  *		LINUX_SLL_OTHERHOST	packet was sent to somebody else
533c602fabSXin LI  *		LINUX_SLL_OUTGOING	packet was sent *by* us;
543c602fabSXin LI  *
553c602fabSXin LI  *	a 2-byte Ethernet protocol field;
563c602fabSXin LI  *
573c602fabSXin LI  *	a 2-byte link-layer type;
583c602fabSXin LI  *
593c602fabSXin LI  *	a 2-byte link-layer address length;
603c602fabSXin LI  *
613c602fabSXin LI  *	an 8-byte source link-layer address, whose actual length is
623c602fabSXin LI  *	specified by the previous value.
633c602fabSXin LI  *
643c602fabSXin LI  * All fields except for the link-layer address are in network byte order.
653c602fabSXin LI  *
663c602fabSXin LI  * DO NOT change the layout of this structure, or change any of the
673c602fabSXin LI  * LINUX_SLL_ values below.  If you must change the link-layer header
683c602fabSXin LI  * for a "cooked" Linux capture, introduce a new DLT_ type (ask
693c602fabSXin LI  * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
703c602fabSXin LI  * a value that collides with a value already being used), and use the
713c602fabSXin LI  * new header in captures of that type, so that programs that can
723c602fabSXin LI  * handle DLT_LINUX_SLL captures will continue to handle them correctly
733c602fabSXin LI  * without any change, and so that capture files with different headers
743c602fabSXin LI  * can be told apart and programs that read them can dissect the
753c602fabSXin LI  * packets in them.
763c602fabSXin LI  *
773c602fabSXin LI  * This structure, and the #defines below, must be the same in the
783c602fabSXin LI  * libpcap and tcpdump versions of "sll.h".
793c602fabSXin LI  */
803c602fabSXin LI 
813c602fabSXin LI /*
823c602fabSXin LI  * A DLT_LINUX_SLL fake link-layer header.
833c602fabSXin LI  */
843c602fabSXin LI #define SLL_HDR_LEN	16		/* total header length */
853c602fabSXin LI #define SLL_ADDRLEN	8		/* length of address field */
863c602fabSXin LI 
873c602fabSXin LI struct sll_header {
88*ee67461eSJoseph Mingrone 	nd_uint16_t	sll_pkttype;	/* packet type */
89*ee67461eSJoseph Mingrone 	nd_uint16_t	sll_hatype;	/* link-layer address type */
90*ee67461eSJoseph Mingrone 	nd_uint16_t	sll_halen;	/* link-layer address length */
91*ee67461eSJoseph Mingrone 	nd_byte		sll_addr[SLL_ADDRLEN];	/* link-layer address */
92*ee67461eSJoseph Mingrone 	nd_uint16_t	sll_protocol;	/* protocol */
93*ee67461eSJoseph Mingrone };
94*ee67461eSJoseph Mingrone 
95*ee67461eSJoseph Mingrone /*
96*ee67461eSJoseph Mingrone  * A DLT_LINUX_SLL2 fake link-layer header.
97*ee67461eSJoseph Mingrone  */
98*ee67461eSJoseph Mingrone #define SLL2_HDR_LEN	20		/* total header length */
99*ee67461eSJoseph Mingrone 
100*ee67461eSJoseph Mingrone struct sll2_header {
101*ee67461eSJoseph Mingrone 	nd_uint16_t	sll2_protocol;		/* protocol */
102*ee67461eSJoseph Mingrone 	nd_uint16_t	sll2_reserved_mbz;	/* reserved - must be zero */
103*ee67461eSJoseph Mingrone 	nd_uint32_t	sll2_if_index;		/* 1-based interface index */
104*ee67461eSJoseph Mingrone 	nd_uint16_t	sll2_hatype;		/* link-layer address type */
105*ee67461eSJoseph Mingrone 	nd_uint8_t	sll2_pkttype;		/* packet type */
106*ee67461eSJoseph Mingrone 	nd_uint8_t	sll2_halen;		/* link-layer address length */
107*ee67461eSJoseph Mingrone 	nd_byte		sll2_addr[SLL_ADDRLEN];	/* link-layer address */
1083c602fabSXin LI };
1093c602fabSXin LI 
1103c602fabSXin LI /*
1113c602fabSXin LI  * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
1123c602fabSXin LI  * PACKET_ values on Linux, but are defined here so that they're
1133c602fabSXin LI  * available even on systems other than Linux, and so that they
1143c602fabSXin LI  * don't change even if the PACKET_ values change.
1153c602fabSXin LI  */
1163c602fabSXin LI #define LINUX_SLL_HOST		0
1173c602fabSXin LI #define LINUX_SLL_BROADCAST	1
1183c602fabSXin LI #define LINUX_SLL_MULTICAST	2
1193c602fabSXin LI #define LINUX_SLL_OTHERHOST	3
1203c602fabSXin LI #define LINUX_SLL_OUTGOING	4
1213c602fabSXin LI 
1223c602fabSXin LI /*
1233c602fabSXin LI  * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
1243c602fabSXin LI  * ETH_P_ values on Linux, but are defined here so that they're
1253c602fabSXin LI  * available even on systems other than Linux.  We assume, for now,
1263c602fabSXin LI  * that the ETH_P_ values won't change in Linux; if they do, then:
1273c602fabSXin LI  *
1283c602fabSXin LI  *	if we don't translate them in "pcap-linux.c", capture files
1293c602fabSXin LI  *	won't necessarily be readable if captured on a system that
1303c602fabSXin LI  *	defines ETH_P_ values that don't match these values;
1313c602fabSXin LI  *
1323c602fabSXin LI  *	if we do translate them in "pcap-linux.c", that makes life
1333c602fabSXin LI  *	unpleasant for the BPF code generator, as the values you test
1343c602fabSXin LI  *	for in the kernel aren't the values that you test for when
1353c602fabSXin LI  *	reading a capture file, so the fixup code run on BPF programs
1363c602fabSXin LI  *	handed to the kernel ends up having to do more work.
1373c602fabSXin LI  *
1383c602fabSXin LI  * Add other values here as necessary, for handling packet types that
1393c602fabSXin LI  * might show up on non-Ethernet, non-802.x networks.  (Not all the ones
1403c602fabSXin LI  * in the Linux "if_ether.h" will, I suspect, actually show up in
1413c602fabSXin LI  * captures.)
1423c602fabSXin LI  */
1433c602fabSXin LI #define LINUX_SLL_P_802_3	0x0001	/* Novell 802.3 frames without 802.2 LLC header */
1443c602fabSXin LI #define LINUX_SLL_P_802_2	0x0004	/* 802.2 frames (not D/I/X Ethernet) */
1453c602fabSXin LI 
1463c602fabSXin LI static const struct tok sll_pkttype_values[] = {
1471de50e9fSSam Leffler     { LINUX_SLL_HOST, "In" },
1481de50e9fSSam Leffler     { LINUX_SLL_BROADCAST, "B" },
1491de50e9fSSam Leffler     { LINUX_SLL_MULTICAST, "M" },
1501de50e9fSSam Leffler     { LINUX_SLL_OTHERHOST, "P" },
1511de50e9fSSam Leffler     { LINUX_SLL_OUTGOING, "Out" },
1521de50e9fSSam Leffler     { 0, NULL}
1531de50e9fSSam Leffler };
1541de50e9fSSam Leffler 
155*ee67461eSJoseph Mingrone static void
sll_print(netdissect_options * ndo,const struct sll_header * sllp,u_int length)156*ee67461eSJoseph Mingrone sll_print(netdissect_options *ndo, const struct sll_header *sllp, u_int length)
157685295f4SBill Fenner {
158f4d0c64aSSam Leffler 	u_short ether_type;
159f4d0c64aSSam Leffler 
160*ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "sll";
161*ee67461eSJoseph Mingrone         ND_PRINT("%3s ",
162*ee67461eSJoseph Mingrone 		 tok2str(sll_pkttype_values,"?",GET_BE_U_2(sllp->sll_pkttype)));
163685295f4SBill Fenner 
164685295f4SBill Fenner 	/*
165685295f4SBill Fenner 	 * XXX - check the link-layer address type value?
166685295f4SBill Fenner 	 * For now, we just assume 6 means Ethernet.
167685295f4SBill Fenner 	 * XXX - print others as strings of hex?
168685295f4SBill Fenner 	 */
169*ee67461eSJoseph Mingrone 	if (GET_BE_U_2(sllp->sll_halen) == MAC_ADDR_LEN)
170*ee67461eSJoseph Mingrone 		ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll_addr));
171685295f4SBill Fenner 
1723c602fabSXin LI 	if (!ndo->ndo_qflag) {
173*ee67461eSJoseph Mingrone 		ether_type = GET_BE_U_2(sllp->sll_protocol);
174f4d0c64aSSam Leffler 
175*ee67461eSJoseph Mingrone 		if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
176f4d0c64aSSam Leffler 			/*
177f4d0c64aSSam Leffler 			 * Not an Ethernet type; what type is it?
178f4d0c64aSSam Leffler 			 */
179f4d0c64aSSam Leffler 			switch (ether_type) {
180f4d0c64aSSam Leffler 
181f4d0c64aSSam Leffler 			case LINUX_SLL_P_802_3:
182f4d0c64aSSam Leffler 				/*
183f4d0c64aSSam Leffler 				 * Ethernet_802.3 IPX frame.
184f4d0c64aSSam Leffler 				 */
185*ee67461eSJoseph Mingrone 				ND_PRINT("802.3");
186f4d0c64aSSam Leffler 				break;
187f4d0c64aSSam Leffler 
188f4d0c64aSSam Leffler 			case LINUX_SLL_P_802_2:
189f4d0c64aSSam Leffler 				/*
190f4d0c64aSSam Leffler 				 * 802.2.
191f4d0c64aSSam Leffler 				 */
192*ee67461eSJoseph Mingrone 				ND_PRINT("802.2");
193f4d0c64aSSam Leffler 				break;
194f4d0c64aSSam Leffler 
195f4d0c64aSSam Leffler 			default:
196f4d0c64aSSam Leffler 				/*
197f4d0c64aSSam Leffler 				 * What is it?
198f4d0c64aSSam Leffler 				 */
199*ee67461eSJoseph Mingrone 				ND_PRINT("ethertype Unknown (0x%04x)",
200*ee67461eSJoseph Mingrone 				    ether_type);
201f4d0c64aSSam Leffler 				break;
202f4d0c64aSSam Leffler 			}
203f4d0c64aSSam Leffler 		} else {
204*ee67461eSJoseph Mingrone 			ND_PRINT("ethertype %s (0x%04x)",
205f4d0c64aSSam Leffler 			    tok2str(ethertype_values, "Unknown", ether_type),
206*ee67461eSJoseph Mingrone 			    ether_type);
207f4d0c64aSSam Leffler 		}
208*ee67461eSJoseph Mingrone 		ND_PRINT(", length %u: ", length);
209f4d0c64aSSam Leffler 	}
210685295f4SBill Fenner }
211685295f4SBill Fenner 
212685295f4SBill Fenner /*
2135b0fe478SBruce M Simpson  * This is the top level routine of the printer.  'p' points to the
2145b0fe478SBruce M Simpson  * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
2151de50e9fSSam Leffler  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
216685295f4SBill Fenner  * is the number of bytes actually captured.
217685295f4SBill Fenner  */
218*ee67461eSJoseph Mingrone void
sll_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)2193c602fabSXin LI sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
220685295f4SBill Fenner {
221685295f4SBill Fenner 	u_int caplen = h->caplen;
222685295f4SBill Fenner 	u_int length = h->len;
223*ee67461eSJoseph Mingrone 	const struct sll_header *sllp;
22439e421e8SCy Schubert 	u_short hatype;
225685295f4SBill Fenner 	u_short ether_type;
2263340d773SGleb Smirnoff 	int llc_hdrlen;
2273340d773SGleb Smirnoff 	u_int hdrlen;
228685295f4SBill Fenner 
229*ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "sll";
230*ee67461eSJoseph Mingrone 	ND_TCHECK_LEN(p, SLL_HDR_LEN);
231685295f4SBill Fenner 
232685295f4SBill Fenner 	sllp = (const struct sll_header *)p;
233685295f4SBill Fenner 
2343c602fabSXin LI 	if (ndo->ndo_eflag)
2353c602fabSXin LI 		sll_print(ndo, sllp, length);
236685295f4SBill Fenner 
237685295f4SBill Fenner 	/*
2385b0fe478SBruce M Simpson 	 * Go past the cooked-mode header.
239685295f4SBill Fenner 	 */
240685295f4SBill Fenner 	length -= SLL_HDR_LEN;
241685295f4SBill Fenner 	caplen -= SLL_HDR_LEN;
242685295f4SBill Fenner 	p += SLL_HDR_LEN;
2433340d773SGleb Smirnoff 	hdrlen = SLL_HDR_LEN;
244685295f4SBill Fenner 
245*ee67461eSJoseph Mingrone 	hatype = GET_BE_U_2(sllp->sll_hatype);
24639e421e8SCy Schubert 	switch (hatype) {
24739e421e8SCy Schubert 
24839e421e8SCy Schubert 	case 803:
24939e421e8SCy Schubert 		/*
25039e421e8SCy Schubert 		 * This is an packet with a radiotap header;
25139e421e8SCy Schubert 		 * just dissect the payload as such.
25239e421e8SCy Schubert 		 */
253*ee67461eSJoseph Mingrone 		ndo->ndo_ll_hdr_len += SLL_HDR_LEN;
254*ee67461eSJoseph Mingrone 		ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
255*ee67461eSJoseph Mingrone 		return;
25639e421e8SCy Schubert 	}
257*ee67461eSJoseph Mingrone 	ether_type = GET_BE_U_2(sllp->sll_protocol);
258685295f4SBill Fenner 
25927df3f5dSRui Paulo recurse:
260685295f4SBill Fenner 	/*
261685295f4SBill Fenner 	 * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
262685295f4SBill Fenner 	 * packet type?
263685295f4SBill Fenner 	 */
264*ee67461eSJoseph Mingrone 	if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
265685295f4SBill Fenner 		/*
266685295f4SBill Fenner 		 * Yes - what type is it?
267685295f4SBill Fenner 		 */
268685295f4SBill Fenner 		switch (ether_type) {
269685295f4SBill Fenner 
270a90e161bSBill Fenner 		case LINUX_SLL_P_802_3:
271a90e161bSBill Fenner 			/*
272a90e161bSBill Fenner 			 * Ethernet_802.3 IPX frame.
273a90e161bSBill Fenner 			 */
2743c602fabSXin LI 			ipx_print(ndo, p, length);
275a90e161bSBill Fenner 			break;
276a90e161bSBill Fenner 
277685295f4SBill Fenner 		case LINUX_SLL_P_802_2:
278685295f4SBill Fenner 			/*
279685295f4SBill Fenner 			 * 802.2.
280685295f4SBill Fenner 			 * Try to print the LLC-layer header & higher layers.
281685295f4SBill Fenner 			 */
2823340d773SGleb Smirnoff 			llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
2833340d773SGleb Smirnoff 			if (llc_hdrlen < 0)
284685295f4SBill Fenner 				goto unknown;	/* unknown LLC type */
2853340d773SGleb Smirnoff 			hdrlen += llc_hdrlen;
286685295f4SBill Fenner 			break;
287685295f4SBill Fenner 
288685295f4SBill Fenner 		default:
289b5bfcb5dSMax Laier 			/*FALLTHROUGH*/
290b5bfcb5dSMax Laier 
291685295f4SBill Fenner 		unknown:
2923340d773SGleb Smirnoff 			/* packet type not known, print raw packet */
2933c602fabSXin LI 			if (!ndo->ndo_suppress_default_print)
2943c602fabSXin LI 				ND_DEFAULTPRINT(p, caplen);
295685295f4SBill Fenner 			break;
296685295f4SBill Fenner 		}
29727df3f5dSRui Paulo 	} else if (ether_type == ETHERTYPE_8021Q) {
29827df3f5dSRui Paulo 		/*
29927df3f5dSRui Paulo 		 * Print VLAN information, and then go back and process
30027df3f5dSRui Paulo 		 * the enclosed type field.
30127df3f5dSRui Paulo 		 */
3023340d773SGleb Smirnoff 		if (caplen < 4) {
303*ee67461eSJoseph Mingrone 			ndo->ndo_protocol = "vlan";
304*ee67461eSJoseph Mingrone 			nd_print_trunc(ndo);
305*ee67461eSJoseph Mingrone 			ndo->ndo_ll_hdr_len += hdrlen + caplen;
306*ee67461eSJoseph Mingrone 			return;
30727df3f5dSRui Paulo 		}
3083c602fabSXin LI 	        if (ndo->ndo_eflag) {
309*ee67461eSJoseph Mingrone 			uint16_t tag = GET_BE_U_2(p);
31027df3f5dSRui Paulo 
311*ee67461eSJoseph Mingrone 			ND_PRINT("%s, ", ieee8021q_tci_string(tag));
31227df3f5dSRui Paulo 		}
31327df3f5dSRui Paulo 
314*ee67461eSJoseph Mingrone 		ether_type = GET_BE_U_2(p + 2);
315*ee67461eSJoseph Mingrone 		if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
31627df3f5dSRui Paulo 			ether_type = LINUX_SLL_P_802_2;
3173c602fabSXin LI 		if (!ndo->ndo_qflag) {
318*ee67461eSJoseph Mingrone 			ND_PRINT("ethertype %s, ",
319*ee67461eSJoseph Mingrone 			    tok2str(ethertype_values, "Unknown", ether_type));
32027df3f5dSRui Paulo 		}
32127df3f5dSRui Paulo 		p += 4;
32227df3f5dSRui Paulo 		length -= 4;
32327df3f5dSRui Paulo 		caplen -= 4;
3243340d773SGleb Smirnoff 		hdrlen += 4;
32527df3f5dSRui Paulo 		goto recurse;
32627df3f5dSRui Paulo 	} else {
3273340d773SGleb Smirnoff 		if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
328685295f4SBill Fenner 			/* ether_type not known, print raw packet */
3293c602fabSXin LI 			if (!ndo->ndo_eflag)
3303c602fabSXin LI 				sll_print(ndo, sllp, length + SLL_HDR_LEN);
3313c602fabSXin LI 			if (!ndo->ndo_suppress_default_print)
3323c602fabSXin LI 				ND_DEFAULTPRINT(p, caplen);
333685295f4SBill Fenner 		}
33427df3f5dSRui Paulo 	}
3355b0fe478SBruce M Simpson 
336*ee67461eSJoseph Mingrone 	ndo->ndo_ll_hdr_len += hdrlen;
337*ee67461eSJoseph Mingrone }
338*ee67461eSJoseph Mingrone 
339*ee67461eSJoseph Mingrone static void
sll2_print(netdissect_options * ndo,const struct sll2_header * sllp,u_int length)340*ee67461eSJoseph Mingrone sll2_print(netdissect_options *ndo, const struct sll2_header *sllp, u_int length)
341*ee67461eSJoseph Mingrone {
342*ee67461eSJoseph Mingrone 	u_short ether_type;
343*ee67461eSJoseph Mingrone 
344*ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "sll2";
345*ee67461eSJoseph Mingrone 	ND_PRINT("ifindex %u ", GET_BE_U_4(sllp->sll2_if_index));
346*ee67461eSJoseph Mingrone 
347*ee67461eSJoseph Mingrone 	/*
348*ee67461eSJoseph Mingrone 	 * XXX - check the link-layer address type value?
349*ee67461eSJoseph Mingrone 	 * For now, we just assume 6 means Ethernet.
350*ee67461eSJoseph Mingrone 	 * XXX - print others as strings of hex?
351*ee67461eSJoseph Mingrone 	 */
352*ee67461eSJoseph Mingrone 	if (GET_U_1(sllp->sll2_halen) == MAC_ADDR_LEN)
353*ee67461eSJoseph Mingrone 		ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll2_addr));
354*ee67461eSJoseph Mingrone 
355*ee67461eSJoseph Mingrone 	if (!ndo->ndo_qflag) {
356*ee67461eSJoseph Mingrone 		ether_type = GET_BE_U_2(sllp->sll2_protocol);
357*ee67461eSJoseph Mingrone 
358*ee67461eSJoseph Mingrone 		if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
359*ee67461eSJoseph Mingrone 			/*
360*ee67461eSJoseph Mingrone 			 * Not an Ethernet type; what type is it?
361*ee67461eSJoseph Mingrone 			 */
362*ee67461eSJoseph Mingrone 			switch (ether_type) {
363*ee67461eSJoseph Mingrone 
364*ee67461eSJoseph Mingrone 			case LINUX_SLL_P_802_3:
365*ee67461eSJoseph Mingrone 				/*
366*ee67461eSJoseph Mingrone 				 * Ethernet_802.3 IPX frame.
367*ee67461eSJoseph Mingrone 				 */
368*ee67461eSJoseph Mingrone 				ND_PRINT("802.3");
369*ee67461eSJoseph Mingrone 				break;
370*ee67461eSJoseph Mingrone 
371*ee67461eSJoseph Mingrone 			case LINUX_SLL_P_802_2:
372*ee67461eSJoseph Mingrone 				/*
373*ee67461eSJoseph Mingrone 				 * 802.2.
374*ee67461eSJoseph Mingrone 				 */
375*ee67461eSJoseph Mingrone 				ND_PRINT("802.2");
376*ee67461eSJoseph Mingrone 				break;
377*ee67461eSJoseph Mingrone 
378*ee67461eSJoseph Mingrone 			default:
379*ee67461eSJoseph Mingrone 				/*
380*ee67461eSJoseph Mingrone 				 * What is it?
381*ee67461eSJoseph Mingrone 				 */
382*ee67461eSJoseph Mingrone 				ND_PRINT("ethertype Unknown (0x%04x)",
383*ee67461eSJoseph Mingrone 				    ether_type);
384*ee67461eSJoseph Mingrone 				break;
385*ee67461eSJoseph Mingrone 			}
386*ee67461eSJoseph Mingrone 		} else {
387*ee67461eSJoseph Mingrone 			ND_PRINT("ethertype %s (0x%04x)",
388*ee67461eSJoseph Mingrone 			    tok2str(ethertype_values, "Unknown", ether_type),
389*ee67461eSJoseph Mingrone 			    ether_type);
390*ee67461eSJoseph Mingrone 		}
391*ee67461eSJoseph Mingrone 		ND_PRINT(", length %u: ", length);
392*ee67461eSJoseph Mingrone 	}
393*ee67461eSJoseph Mingrone }
394*ee67461eSJoseph Mingrone 
395*ee67461eSJoseph Mingrone /*
396*ee67461eSJoseph Mingrone  * This is the top level routine of the printer.  'p' points to the
397*ee67461eSJoseph Mingrone  * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
398*ee67461eSJoseph Mingrone  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
399*ee67461eSJoseph Mingrone  * is the number of bytes actually captured.
400*ee67461eSJoseph Mingrone  */
401*ee67461eSJoseph Mingrone void
sll2_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)402*ee67461eSJoseph Mingrone sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
403*ee67461eSJoseph Mingrone {
404*ee67461eSJoseph Mingrone 	u_int caplen = h->caplen;
405*ee67461eSJoseph Mingrone 	u_int length = h->len;
406*ee67461eSJoseph Mingrone 	const struct sll2_header *sllp;
407*ee67461eSJoseph Mingrone 	u_short hatype;
408*ee67461eSJoseph Mingrone 	u_short ether_type;
409*ee67461eSJoseph Mingrone 	int llc_hdrlen;
410*ee67461eSJoseph Mingrone 	u_int hdrlen;
411*ee67461eSJoseph Mingrone #ifdef HAVE_NET_IF_H
412*ee67461eSJoseph Mingrone 	uint32_t if_index;
413*ee67461eSJoseph Mingrone 	char ifname[IF_NAMESIZE];
414*ee67461eSJoseph Mingrone #endif
415*ee67461eSJoseph Mingrone 
416*ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "sll2";
417*ee67461eSJoseph Mingrone 	ND_TCHECK_LEN(p, SLL2_HDR_LEN);
418*ee67461eSJoseph Mingrone 
419*ee67461eSJoseph Mingrone 	sllp = (const struct sll2_header *)p;
420*ee67461eSJoseph Mingrone #ifdef HAVE_NET_IF_H
421*ee67461eSJoseph Mingrone 	if_index = GET_BE_U_4(sllp->sll2_if_index);
422*ee67461eSJoseph Mingrone 	if (!if_indextoname(if_index, ifname))
423*ee67461eSJoseph Mingrone 		strncpy(ifname, "?", 2);
424*ee67461eSJoseph Mingrone 	ND_PRINT("%-5s ", ifname);
425*ee67461eSJoseph Mingrone #endif
426*ee67461eSJoseph Mingrone 
427*ee67461eSJoseph Mingrone 	ND_PRINT("%-3s ",
428*ee67461eSJoseph Mingrone 		 tok2str(sll_pkttype_values, "?", GET_U_1(sllp->sll2_pkttype)));
429*ee67461eSJoseph Mingrone 
430*ee67461eSJoseph Mingrone 	if (ndo->ndo_eflag)
431*ee67461eSJoseph Mingrone 		sll2_print(ndo, sllp, length);
432*ee67461eSJoseph Mingrone 
433*ee67461eSJoseph Mingrone 	/*
434*ee67461eSJoseph Mingrone 	 * Go past the cooked-mode header.
435*ee67461eSJoseph Mingrone 	 */
436*ee67461eSJoseph Mingrone 	length -= SLL2_HDR_LEN;
437*ee67461eSJoseph Mingrone 	caplen -= SLL2_HDR_LEN;
438*ee67461eSJoseph Mingrone 	p += SLL2_HDR_LEN;
439*ee67461eSJoseph Mingrone 	hdrlen = SLL2_HDR_LEN;
440*ee67461eSJoseph Mingrone 
441*ee67461eSJoseph Mingrone 	hatype = GET_BE_U_2(sllp->sll2_hatype);
442*ee67461eSJoseph Mingrone 	switch (hatype) {
443*ee67461eSJoseph Mingrone 
444*ee67461eSJoseph Mingrone 	case 803:
445*ee67461eSJoseph Mingrone 		/*
446*ee67461eSJoseph Mingrone 		 * This is an packet with a radiotap header;
447*ee67461eSJoseph Mingrone 		 * just dissect the payload as such.
448*ee67461eSJoseph Mingrone 		 */
449*ee67461eSJoseph Mingrone 		ndo->ndo_ll_hdr_len += SLL2_HDR_LEN;
450*ee67461eSJoseph Mingrone 		ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
451*ee67461eSJoseph Mingrone 		return;
452*ee67461eSJoseph Mingrone 	}
453*ee67461eSJoseph Mingrone 	ether_type = GET_BE_U_2(sllp->sll2_protocol);
454*ee67461eSJoseph Mingrone 
455*ee67461eSJoseph Mingrone recurse:
456*ee67461eSJoseph Mingrone 	/*
457*ee67461eSJoseph Mingrone 	 * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
458*ee67461eSJoseph Mingrone 	 * packet type?
459*ee67461eSJoseph Mingrone 	 */
460*ee67461eSJoseph Mingrone 	if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
461*ee67461eSJoseph Mingrone 		/*
462*ee67461eSJoseph Mingrone 		 * Yes - what type is it?
463*ee67461eSJoseph Mingrone 		 */
464*ee67461eSJoseph Mingrone 		switch (ether_type) {
465*ee67461eSJoseph Mingrone 
466*ee67461eSJoseph Mingrone 		case LINUX_SLL_P_802_3:
467*ee67461eSJoseph Mingrone 			/*
468*ee67461eSJoseph Mingrone 			 * Ethernet_802.3 IPX frame.
469*ee67461eSJoseph Mingrone 			 */
470*ee67461eSJoseph Mingrone 			ipx_print(ndo, p, length);
471*ee67461eSJoseph Mingrone 			break;
472*ee67461eSJoseph Mingrone 
473*ee67461eSJoseph Mingrone 		case LINUX_SLL_P_802_2:
474*ee67461eSJoseph Mingrone 			/*
475*ee67461eSJoseph Mingrone 			 * 802.2.
476*ee67461eSJoseph Mingrone 			 * Try to print the LLC-layer header & higher layers.
477*ee67461eSJoseph Mingrone 			 */
478*ee67461eSJoseph Mingrone 			llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
479*ee67461eSJoseph Mingrone 			if (llc_hdrlen < 0)
480*ee67461eSJoseph Mingrone 				goto unknown;	/* unknown LLC type */
481*ee67461eSJoseph Mingrone 			hdrlen += llc_hdrlen;
482*ee67461eSJoseph Mingrone 			break;
483*ee67461eSJoseph Mingrone 
484*ee67461eSJoseph Mingrone 		default:
485*ee67461eSJoseph Mingrone 			/*FALLTHROUGH*/
486*ee67461eSJoseph Mingrone 
487*ee67461eSJoseph Mingrone 		unknown:
488*ee67461eSJoseph Mingrone 			/* packet type not known, print raw packet */
489*ee67461eSJoseph Mingrone 			if (!ndo->ndo_suppress_default_print)
490*ee67461eSJoseph Mingrone 				ND_DEFAULTPRINT(p, caplen);
491*ee67461eSJoseph Mingrone 			break;
492*ee67461eSJoseph Mingrone 		}
493*ee67461eSJoseph Mingrone 	} else if (ether_type == ETHERTYPE_8021Q) {
494*ee67461eSJoseph Mingrone 		/*
495*ee67461eSJoseph Mingrone 		 * Print VLAN information, and then go back and process
496*ee67461eSJoseph Mingrone 		 * the enclosed type field.
497*ee67461eSJoseph Mingrone 		 */
498*ee67461eSJoseph Mingrone 		if (caplen < 4) {
499*ee67461eSJoseph Mingrone 			ndo->ndo_protocol = "vlan";
500*ee67461eSJoseph Mingrone 			nd_print_trunc(ndo);
501*ee67461eSJoseph Mingrone 			ndo->ndo_ll_hdr_len += hdrlen + caplen;
502*ee67461eSJoseph Mingrone 			return;
503*ee67461eSJoseph Mingrone 		}
504*ee67461eSJoseph Mingrone 	        if (ndo->ndo_eflag) {
505*ee67461eSJoseph Mingrone 			uint16_t tag = GET_BE_U_2(p);
506*ee67461eSJoseph Mingrone 
507*ee67461eSJoseph Mingrone 			ND_PRINT("%s, ", ieee8021q_tci_string(tag));
508*ee67461eSJoseph Mingrone 		}
509*ee67461eSJoseph Mingrone 
510*ee67461eSJoseph Mingrone 		ether_type = GET_BE_U_2(p + 2);
511*ee67461eSJoseph Mingrone 		if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
512*ee67461eSJoseph Mingrone 			ether_type = LINUX_SLL_P_802_2;
513*ee67461eSJoseph Mingrone 		if (!ndo->ndo_qflag) {
514*ee67461eSJoseph Mingrone 			ND_PRINT("ethertype %s, ",
515*ee67461eSJoseph Mingrone 			    tok2str(ethertype_values, "Unknown", ether_type));
516*ee67461eSJoseph Mingrone 		}
517*ee67461eSJoseph Mingrone 		p += 4;
518*ee67461eSJoseph Mingrone 		length -= 4;
519*ee67461eSJoseph Mingrone 		caplen -= 4;
520*ee67461eSJoseph Mingrone 		hdrlen += 4;
521*ee67461eSJoseph Mingrone 		goto recurse;
522*ee67461eSJoseph Mingrone 	} else {
523*ee67461eSJoseph Mingrone 		if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
524*ee67461eSJoseph Mingrone 			/* ether_type not known, print raw packet */
525*ee67461eSJoseph Mingrone 			if (!ndo->ndo_eflag)
526*ee67461eSJoseph Mingrone 				sll2_print(ndo, sllp, length + SLL2_HDR_LEN);
527*ee67461eSJoseph Mingrone 			if (!ndo->ndo_suppress_default_print)
528*ee67461eSJoseph Mingrone 				ND_DEFAULTPRINT(p, caplen);
529*ee67461eSJoseph Mingrone 		}
530*ee67461eSJoseph Mingrone 	}
531*ee67461eSJoseph Mingrone 
532*ee67461eSJoseph Mingrone 	ndo->ndo_ll_hdr_len += hdrlen;
533685295f4SBill Fenner }
534