1*05b00f60SXin Li /*
2*05b00f60SXin Li * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3*05b00f60SXin Li * The Regents of the University of California. All rights reserved.
4*05b00f60SXin Li *
5*05b00f60SXin Li * Redistribution and use in source and binary forms, with or without
6*05b00f60SXin Li * modification, are permitted provided that: (1) source code distributions
7*05b00f60SXin Li * retain the above copyright notice and this paragraph in its entirety, (2)
8*05b00f60SXin Li * distributions including binary code include the above copyright notice and
9*05b00f60SXin Li * this paragraph in its entirety in the documentation or other materials
10*05b00f60SXin Li * provided with the distribution, and (3) all advertising materials mentioning
11*05b00f60SXin Li * features or use of this software display the following acknowledgement:
12*05b00f60SXin Li * ``This product includes software developed by the University of California,
13*05b00f60SXin Li * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*05b00f60SXin Li * the University nor the names of its contributors may be used to endorse
15*05b00f60SXin Li * or promote products derived from this software without specific prior
16*05b00f60SXin Li * written permission.
17*05b00f60SXin Li * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*05b00f60SXin Li * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*05b00f60SXin Li * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*05b00f60SXin Li */
21*05b00f60SXin Li
22*05b00f60SXin Li /* \summary: Linux cooked sockets capture printer */
23*05b00f60SXin Li
24*05b00f60SXin Li #ifdef HAVE_CONFIG_H
25*05b00f60SXin Li #include <config.h>
26*05b00f60SXin Li #endif
27*05b00f60SXin Li
28*05b00f60SXin Li #ifdef HAVE_NET_IF_H
29*05b00f60SXin Li /*
30*05b00f60SXin Li * Include diag-control.h before <net/if.h>, which too defines a macro
31*05b00f60SXin Li * named ND_UNREACHABLE.
32*05b00f60SXin Li */
33*05b00f60SXin Li #include "diag-control.h"
34*05b00f60SXin Li #include <net/if.h>
35*05b00f60SXin Li #endif
36*05b00f60SXin Li
37*05b00f60SXin Li #include "netdissect-stdinc.h"
38*05b00f60SXin Li
39*05b00f60SXin Li #define ND_LONGJMP_FROM_TCHECK
40*05b00f60SXin Li #include "netdissect.h"
41*05b00f60SXin Li #include "addrtoname.h"
42*05b00f60SXin Li #include "ethertype.h"
43*05b00f60SXin Li #include "extract.h"
44*05b00f60SXin Li
45*05b00f60SXin Li /*
46*05b00f60SXin Li * For captures on Linux cooked sockets, we construct a fake header
47*05b00f60SXin Li * that includes:
48*05b00f60SXin Li *
49*05b00f60SXin Li * a 2-byte "packet type" which is one of:
50*05b00f60SXin Li *
51*05b00f60SXin Li * LINUX_SLL_HOST packet was sent to us
52*05b00f60SXin Li * LINUX_SLL_BROADCAST packet was broadcast
53*05b00f60SXin Li * LINUX_SLL_MULTICAST packet was multicast
54*05b00f60SXin Li * LINUX_SLL_OTHERHOST packet was sent to somebody else
55*05b00f60SXin Li * LINUX_SLL_OUTGOING packet was sent *by* us;
56*05b00f60SXin Li *
57*05b00f60SXin Li * a 2-byte Ethernet protocol field;
58*05b00f60SXin Li *
59*05b00f60SXin Li * a 2-byte link-layer type;
60*05b00f60SXin Li *
61*05b00f60SXin Li * a 2-byte link-layer address length;
62*05b00f60SXin Li *
63*05b00f60SXin Li * an 8-byte source link-layer address, whose actual length is
64*05b00f60SXin Li * specified by the previous value.
65*05b00f60SXin Li *
66*05b00f60SXin Li * All fields except for the link-layer address are in network byte order.
67*05b00f60SXin Li *
68*05b00f60SXin Li * DO NOT change the layout of this structure, or change any of the
69*05b00f60SXin Li * LINUX_SLL_ values below. If you must change the link-layer header
70*05b00f60SXin Li * for a "cooked" Linux capture, introduce a new DLT_ type (ask
71*05b00f60SXin Li * "[email protected]" for one, so that you don't give it
72*05b00f60SXin Li * a value that collides with a value already being used), and use the
73*05b00f60SXin Li * new header in captures of that type, so that programs that can
74*05b00f60SXin Li * handle DLT_LINUX_SLL captures will continue to handle them correctly
75*05b00f60SXin Li * without any change, and so that capture files with different headers
76*05b00f60SXin Li * can be told apart and programs that read them can dissect the
77*05b00f60SXin Li * packets in them.
78*05b00f60SXin Li *
79*05b00f60SXin Li * This structure, and the #defines below, must be the same in the
80*05b00f60SXin Li * libpcap and tcpdump versions of "sll.h".
81*05b00f60SXin Li */
82*05b00f60SXin Li
83*05b00f60SXin Li /*
84*05b00f60SXin Li * A DLT_LINUX_SLL fake link-layer header.
85*05b00f60SXin Li */
86*05b00f60SXin Li #define SLL_HDR_LEN 16 /* total header length */
87*05b00f60SXin Li #define SLL_ADDRLEN 8 /* length of address field */
88*05b00f60SXin Li
89*05b00f60SXin Li struct sll_header {
90*05b00f60SXin Li nd_uint16_t sll_pkttype; /* packet type */
91*05b00f60SXin Li nd_uint16_t sll_hatype; /* link-layer address type */
92*05b00f60SXin Li nd_uint16_t sll_halen; /* link-layer address length */
93*05b00f60SXin Li nd_byte sll_addr[SLL_ADDRLEN]; /* link-layer address */
94*05b00f60SXin Li nd_uint16_t sll_protocol; /* protocol */
95*05b00f60SXin Li };
96*05b00f60SXin Li
97*05b00f60SXin Li /*
98*05b00f60SXin Li * A DLT_LINUX_SLL2 fake link-layer header.
99*05b00f60SXin Li */
100*05b00f60SXin Li #define SLL2_HDR_LEN 20 /* total header length */
101*05b00f60SXin Li
102*05b00f60SXin Li struct sll2_header {
103*05b00f60SXin Li nd_uint16_t sll2_protocol; /* protocol */
104*05b00f60SXin Li nd_uint16_t sll2_reserved_mbz; /* reserved - must be zero */
105*05b00f60SXin Li nd_uint32_t sll2_if_index; /* 1-based interface index */
106*05b00f60SXin Li nd_uint16_t sll2_hatype; /* link-layer address type */
107*05b00f60SXin Li nd_uint8_t sll2_pkttype; /* packet type */
108*05b00f60SXin Li nd_uint8_t sll2_halen; /* link-layer address length */
109*05b00f60SXin Li nd_byte sll2_addr[SLL_ADDRLEN]; /* link-layer address */
110*05b00f60SXin Li };
111*05b00f60SXin Li
112*05b00f60SXin Li /*
113*05b00f60SXin Li * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
114*05b00f60SXin Li * PACKET_ values on Linux, but are defined here so that they're
115*05b00f60SXin Li * available even on systems other than Linux, and so that they
116*05b00f60SXin Li * don't change even if the PACKET_ values change.
117*05b00f60SXin Li */
118*05b00f60SXin Li #define LINUX_SLL_HOST 0
119*05b00f60SXin Li #define LINUX_SLL_BROADCAST 1
120*05b00f60SXin Li #define LINUX_SLL_MULTICAST 2
121*05b00f60SXin Li #define LINUX_SLL_OTHERHOST 3
122*05b00f60SXin Li #define LINUX_SLL_OUTGOING 4
123*05b00f60SXin Li
124*05b00f60SXin Li /*
125*05b00f60SXin Li * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
126*05b00f60SXin Li * ETH_P_ values on Linux, but are defined here so that they're
127*05b00f60SXin Li * available even on systems other than Linux. We assume, for now,
128*05b00f60SXin Li * that the ETH_P_ values won't change in Linux; if they do, then:
129*05b00f60SXin Li *
130*05b00f60SXin Li * if we don't translate them in "pcap-linux.c", capture files
131*05b00f60SXin Li * won't necessarily be readable if captured on a system that
132*05b00f60SXin Li * defines ETH_P_ values that don't match these values;
133*05b00f60SXin Li *
134*05b00f60SXin Li * if we do translate them in "pcap-linux.c", that makes life
135*05b00f60SXin Li * unpleasant for the BPF code generator, as the values you test
136*05b00f60SXin Li * for in the kernel aren't the values that you test for when
137*05b00f60SXin Li * reading a capture file, so the fixup code run on BPF programs
138*05b00f60SXin Li * handed to the kernel ends up having to do more work.
139*05b00f60SXin Li *
140*05b00f60SXin Li * Add other values here as necessary, for handling packet types that
141*05b00f60SXin Li * might show up on non-Ethernet, non-802.x networks. (Not all the ones
142*05b00f60SXin Li * in the Linux "if_ether.h" will, I suspect, actually show up in
143*05b00f60SXin Li * captures.)
144*05b00f60SXin Li */
145*05b00f60SXin Li #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
146*05b00f60SXin Li #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
147*05b00f60SXin Li
148*05b00f60SXin Li static const struct tok sll_pkttype_values[] = {
149*05b00f60SXin Li { LINUX_SLL_HOST, "In" },
150*05b00f60SXin Li { LINUX_SLL_BROADCAST, "B" },
151*05b00f60SXin Li { LINUX_SLL_MULTICAST, "M" },
152*05b00f60SXin Li { LINUX_SLL_OTHERHOST, "P" },
153*05b00f60SXin Li { LINUX_SLL_OUTGOING, "Out" },
154*05b00f60SXin Li { 0, NULL}
155*05b00f60SXin Li };
156*05b00f60SXin Li
157*05b00f60SXin Li static void
sll_print(netdissect_options * ndo,const struct sll_header * sllp,u_int length)158*05b00f60SXin Li sll_print(netdissect_options *ndo, const struct sll_header *sllp, u_int length)
159*05b00f60SXin Li {
160*05b00f60SXin Li u_short ether_type;
161*05b00f60SXin Li
162*05b00f60SXin Li ndo->ndo_protocol = "sll";
163*05b00f60SXin Li ND_PRINT("%3s ",
164*05b00f60SXin Li tok2str(sll_pkttype_values,"?",GET_BE_U_2(sllp->sll_pkttype)));
165*05b00f60SXin Li
166*05b00f60SXin Li /*
167*05b00f60SXin Li * XXX - check the link-layer address type value?
168*05b00f60SXin Li * For now, we just assume 6 means Ethernet.
169*05b00f60SXin Li * XXX - print others as strings of hex?
170*05b00f60SXin Li */
171*05b00f60SXin Li if (GET_BE_U_2(sllp->sll_halen) == MAC_ADDR_LEN)
172*05b00f60SXin Li ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll_addr));
173*05b00f60SXin Li
174*05b00f60SXin Li if (!ndo->ndo_qflag) {
175*05b00f60SXin Li ether_type = GET_BE_U_2(sllp->sll_protocol);
176*05b00f60SXin Li
177*05b00f60SXin Li if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
178*05b00f60SXin Li /*
179*05b00f60SXin Li * Not an Ethernet type; what type is it?
180*05b00f60SXin Li */
181*05b00f60SXin Li switch (ether_type) {
182*05b00f60SXin Li
183*05b00f60SXin Li case LINUX_SLL_P_802_3:
184*05b00f60SXin Li /*
185*05b00f60SXin Li * Ethernet_802.3 IPX frame.
186*05b00f60SXin Li */
187*05b00f60SXin Li ND_PRINT("802.3");
188*05b00f60SXin Li break;
189*05b00f60SXin Li
190*05b00f60SXin Li case LINUX_SLL_P_802_2:
191*05b00f60SXin Li /*
192*05b00f60SXin Li * 802.2.
193*05b00f60SXin Li */
194*05b00f60SXin Li ND_PRINT("802.2");
195*05b00f60SXin Li break;
196*05b00f60SXin Li
197*05b00f60SXin Li default:
198*05b00f60SXin Li /*
199*05b00f60SXin Li * What is it?
200*05b00f60SXin Li */
201*05b00f60SXin Li ND_PRINT("ethertype Unknown (0x%04x)",
202*05b00f60SXin Li ether_type);
203*05b00f60SXin Li break;
204*05b00f60SXin Li }
205*05b00f60SXin Li } else {
206*05b00f60SXin Li ND_PRINT("ethertype %s (0x%04x)",
207*05b00f60SXin Li tok2str(ethertype_values, "Unknown", ether_type),
208*05b00f60SXin Li ether_type);
209*05b00f60SXin Li }
210*05b00f60SXin Li ND_PRINT(", length %u: ", length);
211*05b00f60SXin Li }
212*05b00f60SXin Li }
213*05b00f60SXin Li
214*05b00f60SXin Li /*
215*05b00f60SXin Li * This is the top level routine of the printer. 'p' points to the
216*05b00f60SXin Li * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
217*05b00f60SXin Li * 'h->len' is the length of the packet off the wire, and 'h->caplen'
218*05b00f60SXin Li * is the number of bytes actually captured.
219*05b00f60SXin Li */
220*05b00f60SXin Li void
sll_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)221*05b00f60SXin Li sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
222*05b00f60SXin Li {
223*05b00f60SXin Li u_int caplen = h->caplen;
224*05b00f60SXin Li u_int length = h->len;
225*05b00f60SXin Li const struct sll_header *sllp;
226*05b00f60SXin Li u_short hatype;
227*05b00f60SXin Li u_short ether_type;
228*05b00f60SXin Li int llc_hdrlen;
229*05b00f60SXin Li u_int hdrlen;
230*05b00f60SXin Li
231*05b00f60SXin Li ndo->ndo_protocol = "sll";
232*05b00f60SXin Li ND_TCHECK_LEN(p, SLL_HDR_LEN);
233*05b00f60SXin Li
234*05b00f60SXin Li sllp = (const struct sll_header *)p;
235*05b00f60SXin Li
236*05b00f60SXin Li if (ndo->ndo_eflag)
237*05b00f60SXin Li sll_print(ndo, sllp, length);
238*05b00f60SXin Li
239*05b00f60SXin Li /*
240*05b00f60SXin Li * Go past the cooked-mode header.
241*05b00f60SXin Li */
242*05b00f60SXin Li length -= SLL_HDR_LEN;
243*05b00f60SXin Li caplen -= SLL_HDR_LEN;
244*05b00f60SXin Li p += SLL_HDR_LEN;
245*05b00f60SXin Li hdrlen = SLL_HDR_LEN;
246*05b00f60SXin Li
247*05b00f60SXin Li hatype = GET_BE_U_2(sllp->sll_hatype);
248*05b00f60SXin Li switch (hatype) {
249*05b00f60SXin Li
250*05b00f60SXin Li case 803:
251*05b00f60SXin Li /*
252*05b00f60SXin Li * This is an packet with a radiotap header;
253*05b00f60SXin Li * just dissect the payload as such.
254*05b00f60SXin Li */
255*05b00f60SXin Li ndo->ndo_ll_hdr_len += SLL_HDR_LEN;
256*05b00f60SXin Li ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
257*05b00f60SXin Li return;
258*05b00f60SXin Li }
259*05b00f60SXin Li ether_type = GET_BE_U_2(sllp->sll_protocol);
260*05b00f60SXin Li
261*05b00f60SXin Li recurse:
262*05b00f60SXin Li /*
263*05b00f60SXin Li * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
264*05b00f60SXin Li * packet type?
265*05b00f60SXin Li */
266*05b00f60SXin Li if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
267*05b00f60SXin Li /*
268*05b00f60SXin Li * Yes - what type is it?
269*05b00f60SXin Li */
270*05b00f60SXin Li switch (ether_type) {
271*05b00f60SXin Li
272*05b00f60SXin Li case LINUX_SLL_P_802_3:
273*05b00f60SXin Li /*
274*05b00f60SXin Li * Ethernet_802.3 IPX frame.
275*05b00f60SXin Li */
276*05b00f60SXin Li ipx_print(ndo, p, length);
277*05b00f60SXin Li break;
278*05b00f60SXin Li
279*05b00f60SXin Li case LINUX_SLL_P_802_2:
280*05b00f60SXin Li /*
281*05b00f60SXin Li * 802.2.
282*05b00f60SXin Li * Try to print the LLC-layer header & higher layers.
283*05b00f60SXin Li */
284*05b00f60SXin Li llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
285*05b00f60SXin Li if (llc_hdrlen < 0)
286*05b00f60SXin Li goto unknown; /* unknown LLC type */
287*05b00f60SXin Li hdrlen += llc_hdrlen;
288*05b00f60SXin Li break;
289*05b00f60SXin Li
290*05b00f60SXin Li default:
291*05b00f60SXin Li /*FALLTHROUGH*/
292*05b00f60SXin Li
293*05b00f60SXin Li unknown:
294*05b00f60SXin Li /* packet type not known, print raw packet */
295*05b00f60SXin Li if (!ndo->ndo_suppress_default_print)
296*05b00f60SXin Li ND_DEFAULTPRINT(p, caplen);
297*05b00f60SXin Li break;
298*05b00f60SXin Li }
299*05b00f60SXin Li } else if (ether_type == ETHERTYPE_8021Q) {
300*05b00f60SXin Li /*
301*05b00f60SXin Li * Print VLAN information, and then go back and process
302*05b00f60SXin Li * the enclosed type field.
303*05b00f60SXin Li */
304*05b00f60SXin Li if (caplen < 4) {
305*05b00f60SXin Li ndo->ndo_protocol = "vlan";
306*05b00f60SXin Li nd_print_trunc(ndo);
307*05b00f60SXin Li ndo->ndo_ll_hdr_len += hdrlen + caplen;
308*05b00f60SXin Li return;
309*05b00f60SXin Li }
310*05b00f60SXin Li if (ndo->ndo_eflag) {
311*05b00f60SXin Li uint16_t tag = GET_BE_U_2(p);
312*05b00f60SXin Li
313*05b00f60SXin Li ND_PRINT("%s, ", ieee8021q_tci_string(tag));
314*05b00f60SXin Li }
315*05b00f60SXin Li
316*05b00f60SXin Li ether_type = GET_BE_U_2(p + 2);
317*05b00f60SXin Li if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
318*05b00f60SXin Li ether_type = LINUX_SLL_P_802_2;
319*05b00f60SXin Li if (!ndo->ndo_qflag) {
320*05b00f60SXin Li ND_PRINT("ethertype %s, ",
321*05b00f60SXin Li tok2str(ethertype_values, "Unknown", ether_type));
322*05b00f60SXin Li }
323*05b00f60SXin Li p += 4;
324*05b00f60SXin Li length -= 4;
325*05b00f60SXin Li caplen -= 4;
326*05b00f60SXin Li hdrlen += 4;
327*05b00f60SXin Li goto recurse;
328*05b00f60SXin Li } else {
329*05b00f60SXin Li if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
330*05b00f60SXin Li /* ether_type not known, print raw packet */
331*05b00f60SXin Li if (!ndo->ndo_eflag)
332*05b00f60SXin Li sll_print(ndo, sllp, length + SLL_HDR_LEN);
333*05b00f60SXin Li if (!ndo->ndo_suppress_default_print)
334*05b00f60SXin Li ND_DEFAULTPRINT(p, caplen);
335*05b00f60SXin Li }
336*05b00f60SXin Li }
337*05b00f60SXin Li
338*05b00f60SXin Li ndo->ndo_ll_hdr_len += hdrlen;
339*05b00f60SXin Li }
340*05b00f60SXin Li
341*05b00f60SXin Li static void
sll2_print(netdissect_options * ndo,const struct sll2_header * sllp,u_int length)342*05b00f60SXin Li sll2_print(netdissect_options *ndo, const struct sll2_header *sllp, u_int length)
343*05b00f60SXin Li {
344*05b00f60SXin Li u_short ether_type;
345*05b00f60SXin Li
346*05b00f60SXin Li ndo->ndo_protocol = "sll2";
347*05b00f60SXin Li ND_PRINT("ifindex %u ", GET_BE_U_4(sllp->sll2_if_index));
348*05b00f60SXin Li
349*05b00f60SXin Li /*
350*05b00f60SXin Li * XXX - check the link-layer address type value?
351*05b00f60SXin Li * For now, we just assume 6 means Ethernet.
352*05b00f60SXin Li * XXX - print others as strings of hex?
353*05b00f60SXin Li */
354*05b00f60SXin Li if (GET_U_1(sllp->sll2_halen) == MAC_ADDR_LEN)
355*05b00f60SXin Li ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll2_addr));
356*05b00f60SXin Li
357*05b00f60SXin Li if (!ndo->ndo_qflag) {
358*05b00f60SXin Li ether_type = GET_BE_U_2(sllp->sll2_protocol);
359*05b00f60SXin Li
360*05b00f60SXin Li if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
361*05b00f60SXin Li /*
362*05b00f60SXin Li * Not an Ethernet type; what type is it?
363*05b00f60SXin Li */
364*05b00f60SXin Li switch (ether_type) {
365*05b00f60SXin Li
366*05b00f60SXin Li case LINUX_SLL_P_802_3:
367*05b00f60SXin Li /*
368*05b00f60SXin Li * Ethernet_802.3 IPX frame.
369*05b00f60SXin Li */
370*05b00f60SXin Li ND_PRINT("802.3");
371*05b00f60SXin Li break;
372*05b00f60SXin Li
373*05b00f60SXin Li case LINUX_SLL_P_802_2:
374*05b00f60SXin Li /*
375*05b00f60SXin Li * 802.2.
376*05b00f60SXin Li */
377*05b00f60SXin Li ND_PRINT("802.2");
378*05b00f60SXin Li break;
379*05b00f60SXin Li
380*05b00f60SXin Li default:
381*05b00f60SXin Li /*
382*05b00f60SXin Li * What is it?
383*05b00f60SXin Li */
384*05b00f60SXin Li ND_PRINT("ethertype Unknown (0x%04x)",
385*05b00f60SXin Li ether_type);
386*05b00f60SXin Li break;
387*05b00f60SXin Li }
388*05b00f60SXin Li } else {
389*05b00f60SXin Li ND_PRINT("ethertype %s (0x%04x)",
390*05b00f60SXin Li tok2str(ethertype_values, "Unknown", ether_type),
391*05b00f60SXin Li ether_type);
392*05b00f60SXin Li }
393*05b00f60SXin Li ND_PRINT(", length %u: ", length);
394*05b00f60SXin Li }
395*05b00f60SXin Li }
396*05b00f60SXin Li
397*05b00f60SXin Li /*
398*05b00f60SXin Li * This is the top level routine of the printer. 'p' points to the
399*05b00f60SXin Li * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
400*05b00f60SXin Li * 'h->len' is the length of the packet off the wire, and 'h->caplen'
401*05b00f60SXin Li * is the number of bytes actually captured.
402*05b00f60SXin Li */
403*05b00f60SXin Li void
sll2_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)404*05b00f60SXin Li sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
405*05b00f60SXin Li {
406*05b00f60SXin Li u_int caplen = h->caplen;
407*05b00f60SXin Li u_int length = h->len;
408*05b00f60SXin Li const struct sll2_header *sllp;
409*05b00f60SXin Li u_short hatype;
410*05b00f60SXin Li u_short ether_type;
411*05b00f60SXin Li int llc_hdrlen;
412*05b00f60SXin Li u_int hdrlen;
413*05b00f60SXin Li #ifdef HAVE_NET_IF_H
414*05b00f60SXin Li uint32_t if_index;
415*05b00f60SXin Li char ifname[IF_NAMESIZE];
416*05b00f60SXin Li #endif
417*05b00f60SXin Li
418*05b00f60SXin Li ndo->ndo_protocol = "sll2";
419*05b00f60SXin Li ND_TCHECK_LEN(p, SLL2_HDR_LEN);
420*05b00f60SXin Li
421*05b00f60SXin Li sllp = (const struct sll2_header *)p;
422*05b00f60SXin Li #ifdef HAVE_NET_IF_H
423*05b00f60SXin Li if_index = GET_BE_U_4(sllp->sll2_if_index);
424*05b00f60SXin Li if (!if_indextoname(if_index, ifname))
425*05b00f60SXin Li strncpy(ifname, "?", 2);
426*05b00f60SXin Li ND_PRINT("%-5s ", ifname);
427*05b00f60SXin Li #endif
428*05b00f60SXin Li
429*05b00f60SXin Li ND_PRINT("%-3s ",
430*05b00f60SXin Li tok2str(sll_pkttype_values, "?", GET_U_1(sllp->sll2_pkttype)));
431*05b00f60SXin Li
432*05b00f60SXin Li if (ndo->ndo_eflag)
433*05b00f60SXin Li sll2_print(ndo, sllp, length);
434*05b00f60SXin Li
435*05b00f60SXin Li /*
436*05b00f60SXin Li * Go past the cooked-mode header.
437*05b00f60SXin Li */
438*05b00f60SXin Li length -= SLL2_HDR_LEN;
439*05b00f60SXin Li caplen -= SLL2_HDR_LEN;
440*05b00f60SXin Li p += SLL2_HDR_LEN;
441*05b00f60SXin Li hdrlen = SLL2_HDR_LEN;
442*05b00f60SXin Li
443*05b00f60SXin Li hatype = GET_BE_U_2(sllp->sll2_hatype);
444*05b00f60SXin Li switch (hatype) {
445*05b00f60SXin Li
446*05b00f60SXin Li case 803:
447*05b00f60SXin Li /*
448*05b00f60SXin Li * This is an packet with a radiotap header;
449*05b00f60SXin Li * just dissect the payload as such.
450*05b00f60SXin Li */
451*05b00f60SXin Li ndo->ndo_ll_hdr_len += SLL2_HDR_LEN;
452*05b00f60SXin Li ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
453*05b00f60SXin Li return;
454*05b00f60SXin Li }
455*05b00f60SXin Li ether_type = GET_BE_U_2(sllp->sll2_protocol);
456*05b00f60SXin Li
457*05b00f60SXin Li recurse:
458*05b00f60SXin Li /*
459*05b00f60SXin Li * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
460*05b00f60SXin Li * packet type?
461*05b00f60SXin Li */
462*05b00f60SXin Li if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
463*05b00f60SXin Li /*
464*05b00f60SXin Li * Yes - what type is it?
465*05b00f60SXin Li */
466*05b00f60SXin Li switch (ether_type) {
467*05b00f60SXin Li
468*05b00f60SXin Li case LINUX_SLL_P_802_3:
469*05b00f60SXin Li /*
470*05b00f60SXin Li * Ethernet_802.3 IPX frame.
471*05b00f60SXin Li */
472*05b00f60SXin Li ipx_print(ndo, p, length);
473*05b00f60SXin Li break;
474*05b00f60SXin Li
475*05b00f60SXin Li case LINUX_SLL_P_802_2:
476*05b00f60SXin Li /*
477*05b00f60SXin Li * 802.2.
478*05b00f60SXin Li * Try to print the LLC-layer header & higher layers.
479*05b00f60SXin Li */
480*05b00f60SXin Li llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
481*05b00f60SXin Li if (llc_hdrlen < 0)
482*05b00f60SXin Li goto unknown; /* unknown LLC type */
483*05b00f60SXin Li hdrlen += llc_hdrlen;
484*05b00f60SXin Li break;
485*05b00f60SXin Li
486*05b00f60SXin Li default:
487*05b00f60SXin Li /*FALLTHROUGH*/
488*05b00f60SXin Li
489*05b00f60SXin Li unknown:
490*05b00f60SXin Li /* packet type not known, print raw packet */
491*05b00f60SXin Li if (!ndo->ndo_suppress_default_print)
492*05b00f60SXin Li ND_DEFAULTPRINT(p, caplen);
493*05b00f60SXin Li break;
494*05b00f60SXin Li }
495*05b00f60SXin Li } else if (ether_type == ETHERTYPE_8021Q) {
496*05b00f60SXin Li /*
497*05b00f60SXin Li * Print VLAN information, and then go back and process
498*05b00f60SXin Li * the enclosed type field.
499*05b00f60SXin Li */
500*05b00f60SXin Li if (caplen < 4) {
501*05b00f60SXin Li ndo->ndo_protocol = "vlan";
502*05b00f60SXin Li nd_print_trunc(ndo);
503*05b00f60SXin Li ndo->ndo_ll_hdr_len += hdrlen + caplen;
504*05b00f60SXin Li return;
505*05b00f60SXin Li }
506*05b00f60SXin Li if (ndo->ndo_eflag) {
507*05b00f60SXin Li uint16_t tag = GET_BE_U_2(p);
508*05b00f60SXin Li
509*05b00f60SXin Li ND_PRINT("%s, ", ieee8021q_tci_string(tag));
510*05b00f60SXin Li }
511*05b00f60SXin Li
512*05b00f60SXin Li ether_type = GET_BE_U_2(p + 2);
513*05b00f60SXin Li if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
514*05b00f60SXin Li ether_type = LINUX_SLL_P_802_2;
515*05b00f60SXin Li if (!ndo->ndo_qflag) {
516*05b00f60SXin Li ND_PRINT("ethertype %s, ",
517*05b00f60SXin Li tok2str(ethertype_values, "Unknown", ether_type));
518*05b00f60SXin Li }
519*05b00f60SXin Li p += 4;
520*05b00f60SXin Li length -= 4;
521*05b00f60SXin Li caplen -= 4;
522*05b00f60SXin Li hdrlen += 4;
523*05b00f60SXin Li goto recurse;
524*05b00f60SXin Li } else {
525*05b00f60SXin Li if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
526*05b00f60SXin Li /* ether_type not known, print raw packet */
527*05b00f60SXin Li if (!ndo->ndo_eflag)
528*05b00f60SXin Li sll2_print(ndo, sllp, length + SLL2_HDR_LEN);
529*05b00f60SXin Li if (!ndo->ndo_suppress_default_print)
530*05b00f60SXin Li ND_DEFAULTPRINT(p, caplen);
531*05b00f60SXin Li }
532*05b00f60SXin Li }
533*05b00f60SXin Li
534*05b00f60SXin Li ndo->ndo_ll_hdr_len += hdrlen;
535*05b00f60SXin Li }
536