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