141c99275SPeter Avalos /*
241c99275SPeter Avalos * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
341c99275SPeter Avalos * The Regents of the University of California. All rights reserved.
441c99275SPeter Avalos *
541c99275SPeter Avalos * Redistribution and use in source and binary forms, with or without
641c99275SPeter Avalos * modification, are permitted provided that: (1) source code distributions
741c99275SPeter Avalos * retain the above copyright notice and this paragraph in its entirety, (2)
841c99275SPeter Avalos * distributions including binary code include the above copyright notice and
941c99275SPeter Avalos * this paragraph in its entirety in the documentation or other materials
1041c99275SPeter Avalos * provided with the distribution, and (3) all advertising materials mentioning
1141c99275SPeter Avalos * features or use of this software display the following acknowledgement:
1241c99275SPeter Avalos * ``This product includes software developed by the University of California,
1341c99275SPeter Avalos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1441c99275SPeter Avalos * the University nor the names of its contributors may be used to endorse
1541c99275SPeter Avalos * or promote products derived from this software without specific prior
1641c99275SPeter Avalos * written permission.
1741c99275SPeter Avalos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1841c99275SPeter Avalos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1941c99275SPeter Avalos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2041c99275SPeter Avalos */
21411677aeSAaron LI
22411677aeSAaron LI /* \summary: Linux cooked sockets capture printer */
2341c99275SPeter Avalos
2441c99275SPeter Avalos #ifdef HAVE_CONFIG_H
25*ed775ee7SAntonio Huete Jimenez #include <config.h>
2641c99275SPeter Avalos #endif
2741c99275SPeter Avalos
28*ed775ee7SAntonio Huete Jimenez #ifdef HAVE_NET_IF_H
29*ed775ee7SAntonio Huete Jimenez #include <net/if.h>
30*ed775ee7SAntonio Huete Jimenez #endif
3141c99275SPeter Avalos
32*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
33*ed775ee7SAntonio Huete Jimenez
34*ed775ee7SAntonio Huete Jimenez #define ND_LONGJMP_FROM_TCHECK
35411677aeSAaron LI #include "netdissect.h"
3641c99275SPeter Avalos #include "addrtoname.h"
3741c99275SPeter Avalos #include "ethertype.h"
3841c99275SPeter Avalos #include "extract.h"
3941c99275SPeter Avalos
40411677aeSAaron LI /*
41411677aeSAaron LI * For captures on Linux cooked sockets, we construct a fake header
42411677aeSAaron LI * that includes:
43411677aeSAaron LI *
44411677aeSAaron LI * a 2-byte "packet type" which is one of:
45411677aeSAaron LI *
46411677aeSAaron LI * LINUX_SLL_HOST packet was sent to us
47411677aeSAaron LI * LINUX_SLL_BROADCAST packet was broadcast
48411677aeSAaron LI * LINUX_SLL_MULTICAST packet was multicast
49411677aeSAaron LI * LINUX_SLL_OTHERHOST packet was sent to somebody else
50411677aeSAaron LI * LINUX_SLL_OUTGOING packet was sent *by* us;
51411677aeSAaron LI *
52411677aeSAaron LI * a 2-byte Ethernet protocol field;
53411677aeSAaron LI *
54411677aeSAaron LI * a 2-byte link-layer type;
55411677aeSAaron LI *
56411677aeSAaron LI * a 2-byte link-layer address length;
57411677aeSAaron LI *
58411677aeSAaron LI * an 8-byte source link-layer address, whose actual length is
59411677aeSAaron LI * specified by the previous value.
60411677aeSAaron LI *
61411677aeSAaron LI * All fields except for the link-layer address are in network byte order.
62411677aeSAaron LI *
63411677aeSAaron LI * DO NOT change the layout of this structure, or change any of the
64411677aeSAaron LI * LINUX_SLL_ values below. If you must change the link-layer header
65411677aeSAaron LI * for a "cooked" Linux capture, introduce a new DLT_ type (ask
66411677aeSAaron LI * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
67411677aeSAaron LI * a value that collides with a value already being used), and use the
68411677aeSAaron LI * new header in captures of that type, so that programs that can
69411677aeSAaron LI * handle DLT_LINUX_SLL captures will continue to handle them correctly
70411677aeSAaron LI * without any change, and so that capture files with different headers
71411677aeSAaron LI * can be told apart and programs that read them can dissect the
72411677aeSAaron LI * packets in them.
73411677aeSAaron LI *
74411677aeSAaron LI * This structure, and the #defines below, must be the same in the
75411677aeSAaron LI * libpcap and tcpdump versions of "sll.h".
76411677aeSAaron LI */
77411677aeSAaron LI
78411677aeSAaron LI /*
79411677aeSAaron LI * A DLT_LINUX_SLL fake link-layer header.
80411677aeSAaron LI */
81411677aeSAaron LI #define SLL_HDR_LEN 16 /* total header length */
82411677aeSAaron LI #define SLL_ADDRLEN 8 /* length of address field */
83411677aeSAaron LI
84411677aeSAaron LI struct sll_header {
85*ed775ee7SAntonio Huete Jimenez nd_uint16_t sll_pkttype; /* packet type */
86*ed775ee7SAntonio Huete Jimenez nd_uint16_t sll_hatype; /* link-layer address type */
87*ed775ee7SAntonio Huete Jimenez nd_uint16_t sll_halen; /* link-layer address length */
88*ed775ee7SAntonio Huete Jimenez nd_byte sll_addr[SLL_ADDRLEN]; /* link-layer address */
89*ed775ee7SAntonio Huete Jimenez nd_uint16_t sll_protocol; /* protocol */
90*ed775ee7SAntonio Huete Jimenez };
91*ed775ee7SAntonio Huete Jimenez
92*ed775ee7SAntonio Huete Jimenez /*
93*ed775ee7SAntonio Huete Jimenez * A DLT_LINUX_SLL2 fake link-layer header.
94*ed775ee7SAntonio Huete Jimenez */
95*ed775ee7SAntonio Huete Jimenez #define SLL2_HDR_LEN 20 /* total header length */
96*ed775ee7SAntonio Huete Jimenez
97*ed775ee7SAntonio Huete Jimenez struct sll2_header {
98*ed775ee7SAntonio Huete Jimenez nd_uint16_t sll2_protocol; /* protocol */
99*ed775ee7SAntonio Huete Jimenez nd_uint16_t sll2_reserved_mbz; /* reserved - must be zero */
100*ed775ee7SAntonio Huete Jimenez nd_uint32_t sll2_if_index; /* 1-based interface index */
101*ed775ee7SAntonio Huete Jimenez nd_uint16_t sll2_hatype; /* link-layer address type */
102*ed775ee7SAntonio Huete Jimenez nd_uint8_t sll2_pkttype; /* packet type */
103*ed775ee7SAntonio Huete Jimenez nd_uint8_t sll2_halen; /* link-layer address length */
104*ed775ee7SAntonio Huete Jimenez nd_byte sll2_addr[SLL_ADDRLEN]; /* link-layer address */
105411677aeSAaron LI };
106411677aeSAaron LI
107411677aeSAaron LI /*
108411677aeSAaron LI * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
109411677aeSAaron LI * PACKET_ values on Linux, but are defined here so that they're
110411677aeSAaron LI * available even on systems other than Linux, and so that they
111411677aeSAaron LI * don't change even if the PACKET_ values change.
112411677aeSAaron LI */
113411677aeSAaron LI #define LINUX_SLL_HOST 0
114411677aeSAaron LI #define LINUX_SLL_BROADCAST 1
115411677aeSAaron LI #define LINUX_SLL_MULTICAST 2
116411677aeSAaron LI #define LINUX_SLL_OTHERHOST 3
117411677aeSAaron LI #define LINUX_SLL_OUTGOING 4
118411677aeSAaron LI
119411677aeSAaron LI /*
120411677aeSAaron LI * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
121411677aeSAaron LI * ETH_P_ values on Linux, but are defined here so that they're
122411677aeSAaron LI * available even on systems other than Linux. We assume, for now,
123411677aeSAaron LI * that the ETH_P_ values won't change in Linux; if they do, then:
124411677aeSAaron LI *
125411677aeSAaron LI * if we don't translate them in "pcap-linux.c", capture files
126411677aeSAaron LI * won't necessarily be readable if captured on a system that
127411677aeSAaron LI * defines ETH_P_ values that don't match these values;
128411677aeSAaron LI *
129411677aeSAaron LI * if we do translate them in "pcap-linux.c", that makes life
130411677aeSAaron LI * unpleasant for the BPF code generator, as the values you test
131411677aeSAaron LI * for in the kernel aren't the values that you test for when
132411677aeSAaron LI * reading a capture file, so the fixup code run on BPF programs
133411677aeSAaron LI * handed to the kernel ends up having to do more work.
134411677aeSAaron LI *
135411677aeSAaron LI * Add other values here as necessary, for handling packet types that
136411677aeSAaron LI * might show up on non-Ethernet, non-802.x networks. (Not all the ones
137411677aeSAaron LI * in the Linux "if_ether.h" will, I suspect, actually show up in
138411677aeSAaron LI * captures.)
139411677aeSAaron LI */
140411677aeSAaron LI #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
141411677aeSAaron LI #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
142411677aeSAaron LI
143411677aeSAaron LI static const struct tok sll_pkttype_values[] = {
14441c99275SPeter Avalos { LINUX_SLL_HOST, "In" },
14541c99275SPeter Avalos { LINUX_SLL_BROADCAST, "B" },
14641c99275SPeter Avalos { LINUX_SLL_MULTICAST, "M" },
14741c99275SPeter Avalos { LINUX_SLL_OTHERHOST, "P" },
14841c99275SPeter Avalos { LINUX_SLL_OUTGOING, "Out" },
14941c99275SPeter Avalos { 0, NULL}
15041c99275SPeter Avalos };
15141c99275SPeter Avalos
152*ed775ee7SAntonio Huete Jimenez static void
sll_print(netdissect_options * ndo,const struct sll_header * sllp,u_int length)153*ed775ee7SAntonio Huete Jimenez sll_print(netdissect_options *ndo, const struct sll_header *sllp, u_int length)
15441c99275SPeter Avalos {
15541c99275SPeter Avalos u_short ether_type;
15641c99275SPeter Avalos
157*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sll";
158*ed775ee7SAntonio Huete Jimenez ND_PRINT("%3s ",
159*ed775ee7SAntonio Huete Jimenez tok2str(sll_pkttype_values,"?",GET_BE_U_2(sllp->sll_pkttype)));
16041c99275SPeter Avalos
16141c99275SPeter Avalos /*
16241c99275SPeter Avalos * XXX - check the link-layer address type value?
16341c99275SPeter Avalos * For now, we just assume 6 means Ethernet.
16441c99275SPeter Avalos * XXX - print others as strings of hex?
16541c99275SPeter Avalos */
166*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(sllp->sll_halen) == MAC_ADDR_LEN)
167*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll_addr));
16841c99275SPeter Avalos
169411677aeSAaron LI if (!ndo->ndo_qflag) {
170*ed775ee7SAntonio Huete Jimenez ether_type = GET_BE_U_2(sllp->sll_protocol);
17141c99275SPeter Avalos
172*ed775ee7SAntonio Huete Jimenez if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
17341c99275SPeter Avalos /*
17441c99275SPeter Avalos * Not an Ethernet type; what type is it?
17541c99275SPeter Avalos */
17641c99275SPeter Avalos switch (ether_type) {
17741c99275SPeter Avalos
17841c99275SPeter Avalos case LINUX_SLL_P_802_3:
17941c99275SPeter Avalos /*
18041c99275SPeter Avalos * Ethernet_802.3 IPX frame.
18141c99275SPeter Avalos */
182*ed775ee7SAntonio Huete Jimenez ND_PRINT("802.3");
18341c99275SPeter Avalos break;
18441c99275SPeter Avalos
18541c99275SPeter Avalos case LINUX_SLL_P_802_2:
18641c99275SPeter Avalos /*
18741c99275SPeter Avalos * 802.2.
18841c99275SPeter Avalos */
189*ed775ee7SAntonio Huete Jimenez ND_PRINT("802.2");
19041c99275SPeter Avalos break;
19141c99275SPeter Avalos
19241c99275SPeter Avalos default:
19341c99275SPeter Avalos /*
19441c99275SPeter Avalos * What is it?
19541c99275SPeter Avalos */
196*ed775ee7SAntonio Huete Jimenez ND_PRINT("ethertype Unknown (0x%04x)",
197*ed775ee7SAntonio Huete Jimenez ether_type);
19841c99275SPeter Avalos break;
19941c99275SPeter Avalos }
20041c99275SPeter Avalos } else {
201*ed775ee7SAntonio Huete Jimenez ND_PRINT("ethertype %s (0x%04x)",
20241c99275SPeter Avalos tok2str(ethertype_values, "Unknown", ether_type),
203*ed775ee7SAntonio Huete Jimenez ether_type);
20441c99275SPeter Avalos }
205*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u: ", length);
20641c99275SPeter Avalos }
20741c99275SPeter Avalos }
20841c99275SPeter Avalos
20941c99275SPeter Avalos /*
21041c99275SPeter Avalos * This is the top level routine of the printer. 'p' points to the
21141c99275SPeter Avalos * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
21241c99275SPeter Avalos * 'h->len' is the length of the packet off the wire, and 'h->caplen'
21341c99275SPeter Avalos * is the number of bytes actually captured.
21441c99275SPeter Avalos */
215*ed775ee7SAntonio Huete Jimenez void
sll_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)216411677aeSAaron LI sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
21741c99275SPeter Avalos {
21841c99275SPeter Avalos u_int caplen = h->caplen;
21941c99275SPeter Avalos u_int length = h->len;
220*ed775ee7SAntonio Huete Jimenez const struct sll_header *sllp;
221411677aeSAaron LI u_short hatype;
22241c99275SPeter Avalos u_short ether_type;
223411677aeSAaron LI int llc_hdrlen;
224411677aeSAaron LI u_int hdrlen;
22541c99275SPeter Avalos
226*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sll";
227*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(p, SLL_HDR_LEN);
22841c99275SPeter Avalos
22941c99275SPeter Avalos sllp = (const struct sll_header *)p;
23041c99275SPeter Avalos
231411677aeSAaron LI if (ndo->ndo_eflag)
232411677aeSAaron LI sll_print(ndo, sllp, length);
23341c99275SPeter Avalos
23441c99275SPeter Avalos /*
23541c99275SPeter Avalos * Go past the cooked-mode header.
23641c99275SPeter Avalos */
23741c99275SPeter Avalos length -= SLL_HDR_LEN;
23841c99275SPeter Avalos caplen -= SLL_HDR_LEN;
23941c99275SPeter Avalos p += SLL_HDR_LEN;
240411677aeSAaron LI hdrlen = SLL_HDR_LEN;
24141c99275SPeter Avalos
242*ed775ee7SAntonio Huete Jimenez hatype = GET_BE_U_2(sllp->sll_hatype);
243411677aeSAaron LI switch (hatype) {
244411677aeSAaron LI
245411677aeSAaron LI case 803:
246411677aeSAaron LI /*
247411677aeSAaron LI * This is an packet with a radiotap header;
248411677aeSAaron LI * just dissect the payload as such.
249411677aeSAaron LI */
250*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += SLL_HDR_LEN;
251*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
252*ed775ee7SAntonio Huete Jimenez return;
253411677aeSAaron LI }
254*ed775ee7SAntonio Huete Jimenez ether_type = GET_BE_U_2(sllp->sll_protocol);
25541c99275SPeter Avalos
25627bfbee1SPeter Avalos recurse:
25741c99275SPeter Avalos /*
25841c99275SPeter Avalos * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
25941c99275SPeter Avalos * packet type?
26041c99275SPeter Avalos */
261*ed775ee7SAntonio Huete Jimenez if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
26241c99275SPeter Avalos /*
26341c99275SPeter Avalos * Yes - what type is it?
26441c99275SPeter Avalos */
26541c99275SPeter Avalos switch (ether_type) {
26641c99275SPeter Avalos
26741c99275SPeter Avalos case LINUX_SLL_P_802_3:
26841c99275SPeter Avalos /*
26941c99275SPeter Avalos * Ethernet_802.3 IPX frame.
27041c99275SPeter Avalos */
271411677aeSAaron LI ipx_print(ndo, p, length);
27241c99275SPeter Avalos break;
27341c99275SPeter Avalos
27441c99275SPeter Avalos case LINUX_SLL_P_802_2:
27541c99275SPeter Avalos /*
27641c99275SPeter Avalos * 802.2.
27741c99275SPeter Avalos * Try to print the LLC-layer header & higher layers.
27841c99275SPeter Avalos */
279411677aeSAaron LI llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
280411677aeSAaron LI if (llc_hdrlen < 0)
28141c99275SPeter Avalos goto unknown; /* unknown LLC type */
282411677aeSAaron LI hdrlen += llc_hdrlen;
28341c99275SPeter Avalos break;
28441c99275SPeter Avalos
28541c99275SPeter Avalos default:
28641c99275SPeter Avalos /*FALLTHROUGH*/
28741c99275SPeter Avalos
28841c99275SPeter Avalos unknown:
289411677aeSAaron LI /* packet type not known, print raw packet */
290411677aeSAaron LI if (!ndo->ndo_suppress_default_print)
291411677aeSAaron LI ND_DEFAULTPRINT(p, caplen);
29241c99275SPeter Avalos break;
29341c99275SPeter Avalos }
29427bfbee1SPeter Avalos } else if (ether_type == ETHERTYPE_8021Q) {
29527bfbee1SPeter Avalos /*
29627bfbee1SPeter Avalos * Print VLAN information, and then go back and process
29727bfbee1SPeter Avalos * the enclosed type field.
29827bfbee1SPeter Avalos */
299411677aeSAaron LI if (caplen < 4) {
300*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "vlan";
301*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
302*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += hdrlen + caplen;
303*ed775ee7SAntonio Huete Jimenez return;
304411677aeSAaron LI }
305411677aeSAaron LI if (ndo->ndo_eflag) {
306*ed775ee7SAntonio Huete Jimenez uint16_t tag = GET_BE_U_2(p);
30727bfbee1SPeter Avalos
308*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s, ", ieee8021q_tci_string(tag));
30927bfbee1SPeter Avalos }
31027bfbee1SPeter Avalos
311*ed775ee7SAntonio Huete Jimenez ether_type = GET_BE_U_2(p + 2);
312*ed775ee7SAntonio Huete Jimenez if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
31327bfbee1SPeter Avalos ether_type = LINUX_SLL_P_802_2;
314411677aeSAaron LI if (!ndo->ndo_qflag) {
315*ed775ee7SAntonio Huete Jimenez ND_PRINT("ethertype %s, ",
316*ed775ee7SAntonio Huete Jimenez tok2str(ethertype_values, "Unknown", ether_type));
31727bfbee1SPeter Avalos }
31827bfbee1SPeter Avalos p += 4;
31927bfbee1SPeter Avalos length -= 4;
32027bfbee1SPeter Avalos caplen -= 4;
321411677aeSAaron LI hdrlen += 4;
32227bfbee1SPeter Avalos goto recurse;
32327bfbee1SPeter Avalos } else {
324411677aeSAaron LI if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
32541c99275SPeter Avalos /* ether_type not known, print raw packet */
326411677aeSAaron LI if (!ndo->ndo_eflag)
327411677aeSAaron LI sll_print(ndo, sllp, length + SLL_HDR_LEN);
328411677aeSAaron LI if (!ndo->ndo_suppress_default_print)
329411677aeSAaron LI ND_DEFAULTPRINT(p, caplen);
33041c99275SPeter Avalos }
33127bfbee1SPeter Avalos }
33241c99275SPeter Avalos
333*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += hdrlen;
334*ed775ee7SAntonio Huete Jimenez }
335*ed775ee7SAntonio Huete Jimenez
336*ed775ee7SAntonio Huete Jimenez static void
sll2_print(netdissect_options * ndo,const struct sll2_header * sllp,u_int length)337*ed775ee7SAntonio Huete Jimenez sll2_print(netdissect_options *ndo, const struct sll2_header *sllp, u_int length)
338*ed775ee7SAntonio Huete Jimenez {
339*ed775ee7SAntonio Huete Jimenez u_short ether_type;
340*ed775ee7SAntonio Huete Jimenez
341*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sll2";
342*ed775ee7SAntonio Huete Jimenez ND_PRINT("ifindex %u ", GET_BE_U_4(sllp->sll2_if_index));
343*ed775ee7SAntonio Huete Jimenez
344*ed775ee7SAntonio Huete Jimenez /*
345*ed775ee7SAntonio Huete Jimenez * XXX - check the link-layer address type value?
346*ed775ee7SAntonio Huete Jimenez * For now, we just assume 6 means Ethernet.
347*ed775ee7SAntonio Huete Jimenez * XXX - print others as strings of hex?
348*ed775ee7SAntonio Huete Jimenez */
349*ed775ee7SAntonio Huete Jimenez if (GET_U_1(sllp->sll2_halen) == MAC_ADDR_LEN)
350*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll2_addr));
351*ed775ee7SAntonio Huete Jimenez
352*ed775ee7SAntonio Huete Jimenez if (!ndo->ndo_qflag) {
353*ed775ee7SAntonio Huete Jimenez ether_type = GET_BE_U_2(sllp->sll2_protocol);
354*ed775ee7SAntonio Huete Jimenez
355*ed775ee7SAntonio Huete Jimenez if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
356*ed775ee7SAntonio Huete Jimenez /*
357*ed775ee7SAntonio Huete Jimenez * Not an Ethernet type; what type is it?
358*ed775ee7SAntonio Huete Jimenez */
359*ed775ee7SAntonio Huete Jimenez switch (ether_type) {
360*ed775ee7SAntonio Huete Jimenez
361*ed775ee7SAntonio Huete Jimenez case LINUX_SLL_P_802_3:
362*ed775ee7SAntonio Huete Jimenez /*
363*ed775ee7SAntonio Huete Jimenez * Ethernet_802.3 IPX frame.
364*ed775ee7SAntonio Huete Jimenez */
365*ed775ee7SAntonio Huete Jimenez ND_PRINT("802.3");
366*ed775ee7SAntonio Huete Jimenez break;
367*ed775ee7SAntonio Huete Jimenez
368*ed775ee7SAntonio Huete Jimenez case LINUX_SLL_P_802_2:
369*ed775ee7SAntonio Huete Jimenez /*
370*ed775ee7SAntonio Huete Jimenez * 802.2.
371*ed775ee7SAntonio Huete Jimenez */
372*ed775ee7SAntonio Huete Jimenez ND_PRINT("802.2");
373*ed775ee7SAntonio Huete Jimenez break;
374*ed775ee7SAntonio Huete Jimenez
375*ed775ee7SAntonio Huete Jimenez default:
376*ed775ee7SAntonio Huete Jimenez /*
377*ed775ee7SAntonio Huete Jimenez * What is it?
378*ed775ee7SAntonio Huete Jimenez */
379*ed775ee7SAntonio Huete Jimenez ND_PRINT("ethertype Unknown (0x%04x)",
380*ed775ee7SAntonio Huete Jimenez ether_type);
381*ed775ee7SAntonio Huete Jimenez break;
382*ed775ee7SAntonio Huete Jimenez }
383*ed775ee7SAntonio Huete Jimenez } else {
384*ed775ee7SAntonio Huete Jimenez ND_PRINT("ethertype %s (0x%04x)",
385*ed775ee7SAntonio Huete Jimenez tok2str(ethertype_values, "Unknown", ether_type),
386*ed775ee7SAntonio Huete Jimenez ether_type);
387*ed775ee7SAntonio Huete Jimenez }
388*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u: ", length);
389*ed775ee7SAntonio Huete Jimenez }
390*ed775ee7SAntonio Huete Jimenez }
391*ed775ee7SAntonio Huete Jimenez
392*ed775ee7SAntonio Huete Jimenez /*
393*ed775ee7SAntonio Huete Jimenez * This is the top level routine of the printer. 'p' points to the
394*ed775ee7SAntonio Huete Jimenez * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
395*ed775ee7SAntonio Huete Jimenez * 'h->len' is the length of the packet off the wire, and 'h->caplen'
396*ed775ee7SAntonio Huete Jimenez * is the number of bytes actually captured.
397*ed775ee7SAntonio Huete Jimenez */
398*ed775ee7SAntonio Huete Jimenez void
sll2_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)399*ed775ee7SAntonio Huete Jimenez sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
400*ed775ee7SAntonio Huete Jimenez {
401*ed775ee7SAntonio Huete Jimenez u_int caplen = h->caplen;
402*ed775ee7SAntonio Huete Jimenez u_int length = h->len;
403*ed775ee7SAntonio Huete Jimenez const struct sll2_header *sllp;
404*ed775ee7SAntonio Huete Jimenez u_short hatype;
405*ed775ee7SAntonio Huete Jimenez u_short ether_type;
406*ed775ee7SAntonio Huete Jimenez int llc_hdrlen;
407*ed775ee7SAntonio Huete Jimenez u_int hdrlen;
408*ed775ee7SAntonio Huete Jimenez #ifdef HAVE_NET_IF_H
409*ed775ee7SAntonio Huete Jimenez uint32_t if_index;
410*ed775ee7SAntonio Huete Jimenez char ifname[IF_NAMESIZE];
411*ed775ee7SAntonio Huete Jimenez #endif
412*ed775ee7SAntonio Huete Jimenez
413*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sll2";
414*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(p, SLL2_HDR_LEN);
415*ed775ee7SAntonio Huete Jimenez
416*ed775ee7SAntonio Huete Jimenez sllp = (const struct sll2_header *)p;
417*ed775ee7SAntonio Huete Jimenez #ifdef HAVE_NET_IF_H
418*ed775ee7SAntonio Huete Jimenez if_index = GET_BE_U_4(sllp->sll2_if_index);
419*ed775ee7SAntonio Huete Jimenez if (!if_indextoname(if_index, ifname))
420*ed775ee7SAntonio Huete Jimenez strncpy(ifname, "?", 2);
421*ed775ee7SAntonio Huete Jimenez ND_PRINT("%-5s ", ifname);
422*ed775ee7SAntonio Huete Jimenez #endif
423*ed775ee7SAntonio Huete Jimenez
424*ed775ee7SAntonio Huete Jimenez ND_PRINT("%-3s ",
425*ed775ee7SAntonio Huete Jimenez tok2str(sll_pkttype_values, "?", GET_U_1(sllp->sll2_pkttype)));
426*ed775ee7SAntonio Huete Jimenez
427*ed775ee7SAntonio Huete Jimenez if (ndo->ndo_eflag)
428*ed775ee7SAntonio Huete Jimenez sll2_print(ndo, sllp, length);
429*ed775ee7SAntonio Huete Jimenez
430*ed775ee7SAntonio Huete Jimenez /*
431*ed775ee7SAntonio Huete Jimenez * Go past the cooked-mode header.
432*ed775ee7SAntonio Huete Jimenez */
433*ed775ee7SAntonio Huete Jimenez length -= SLL2_HDR_LEN;
434*ed775ee7SAntonio Huete Jimenez caplen -= SLL2_HDR_LEN;
435*ed775ee7SAntonio Huete Jimenez p += SLL2_HDR_LEN;
436*ed775ee7SAntonio Huete Jimenez hdrlen = SLL2_HDR_LEN;
437*ed775ee7SAntonio Huete Jimenez
438*ed775ee7SAntonio Huete Jimenez hatype = GET_BE_U_2(sllp->sll2_hatype);
439*ed775ee7SAntonio Huete Jimenez switch (hatype) {
440*ed775ee7SAntonio Huete Jimenez
441*ed775ee7SAntonio Huete Jimenez case 803:
442*ed775ee7SAntonio Huete Jimenez /*
443*ed775ee7SAntonio Huete Jimenez * This is an packet with a radiotap header;
444*ed775ee7SAntonio Huete Jimenez * just dissect the payload as such.
445*ed775ee7SAntonio Huete Jimenez */
446*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += SLL2_HDR_LEN;
447*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
448*ed775ee7SAntonio Huete Jimenez return;
449*ed775ee7SAntonio Huete Jimenez }
450*ed775ee7SAntonio Huete Jimenez ether_type = GET_BE_U_2(sllp->sll2_protocol);
451*ed775ee7SAntonio Huete Jimenez
452*ed775ee7SAntonio Huete Jimenez recurse:
453*ed775ee7SAntonio Huete Jimenez /*
454*ed775ee7SAntonio Huete Jimenez * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
455*ed775ee7SAntonio Huete Jimenez * packet type?
456*ed775ee7SAntonio Huete Jimenez */
457*ed775ee7SAntonio Huete Jimenez if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
458*ed775ee7SAntonio Huete Jimenez /*
459*ed775ee7SAntonio Huete Jimenez * Yes - what type is it?
460*ed775ee7SAntonio Huete Jimenez */
461*ed775ee7SAntonio Huete Jimenez switch (ether_type) {
462*ed775ee7SAntonio Huete Jimenez
463*ed775ee7SAntonio Huete Jimenez case LINUX_SLL_P_802_3:
464*ed775ee7SAntonio Huete Jimenez /*
465*ed775ee7SAntonio Huete Jimenez * Ethernet_802.3 IPX frame.
466*ed775ee7SAntonio Huete Jimenez */
467*ed775ee7SAntonio Huete Jimenez ipx_print(ndo, p, length);
468*ed775ee7SAntonio Huete Jimenez break;
469*ed775ee7SAntonio Huete Jimenez
470*ed775ee7SAntonio Huete Jimenez case LINUX_SLL_P_802_2:
471*ed775ee7SAntonio Huete Jimenez /*
472*ed775ee7SAntonio Huete Jimenez * 802.2.
473*ed775ee7SAntonio Huete Jimenez * Try to print the LLC-layer header & higher layers.
474*ed775ee7SAntonio Huete Jimenez */
475*ed775ee7SAntonio Huete Jimenez llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
476*ed775ee7SAntonio Huete Jimenez if (llc_hdrlen < 0)
477*ed775ee7SAntonio Huete Jimenez goto unknown; /* unknown LLC type */
478*ed775ee7SAntonio Huete Jimenez hdrlen += llc_hdrlen;
479*ed775ee7SAntonio Huete Jimenez break;
480*ed775ee7SAntonio Huete Jimenez
481*ed775ee7SAntonio Huete Jimenez default:
482*ed775ee7SAntonio Huete Jimenez /*FALLTHROUGH*/
483*ed775ee7SAntonio Huete Jimenez
484*ed775ee7SAntonio Huete Jimenez unknown:
485*ed775ee7SAntonio Huete Jimenez /* packet type not known, print raw packet */
486*ed775ee7SAntonio Huete Jimenez if (!ndo->ndo_suppress_default_print)
487*ed775ee7SAntonio Huete Jimenez ND_DEFAULTPRINT(p, caplen);
488*ed775ee7SAntonio Huete Jimenez break;
489*ed775ee7SAntonio Huete Jimenez }
490*ed775ee7SAntonio Huete Jimenez } else if (ether_type == ETHERTYPE_8021Q) {
491*ed775ee7SAntonio Huete Jimenez /*
492*ed775ee7SAntonio Huete Jimenez * Print VLAN information, and then go back and process
493*ed775ee7SAntonio Huete Jimenez * the enclosed type field.
494*ed775ee7SAntonio Huete Jimenez */
495*ed775ee7SAntonio Huete Jimenez if (caplen < 4) {
496*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "vlan";
497*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
498*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += hdrlen + caplen;
499*ed775ee7SAntonio Huete Jimenez return;
500*ed775ee7SAntonio Huete Jimenez }
501*ed775ee7SAntonio Huete Jimenez if (ndo->ndo_eflag) {
502*ed775ee7SAntonio Huete Jimenez uint16_t tag = GET_BE_U_2(p);
503*ed775ee7SAntonio Huete Jimenez
504*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s, ", ieee8021q_tci_string(tag));
505*ed775ee7SAntonio Huete Jimenez }
506*ed775ee7SAntonio Huete Jimenez
507*ed775ee7SAntonio Huete Jimenez ether_type = GET_BE_U_2(p + 2);
508*ed775ee7SAntonio Huete Jimenez if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
509*ed775ee7SAntonio Huete Jimenez ether_type = LINUX_SLL_P_802_2;
510*ed775ee7SAntonio Huete Jimenez if (!ndo->ndo_qflag) {
511*ed775ee7SAntonio Huete Jimenez ND_PRINT("ethertype %s, ",
512*ed775ee7SAntonio Huete Jimenez tok2str(ethertype_values, "Unknown", ether_type));
513*ed775ee7SAntonio Huete Jimenez }
514*ed775ee7SAntonio Huete Jimenez p += 4;
515*ed775ee7SAntonio Huete Jimenez length -= 4;
516*ed775ee7SAntonio Huete Jimenez caplen -= 4;
517*ed775ee7SAntonio Huete Jimenez hdrlen += 4;
518*ed775ee7SAntonio Huete Jimenez goto recurse;
519*ed775ee7SAntonio Huete Jimenez } else {
520*ed775ee7SAntonio Huete Jimenez if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
521*ed775ee7SAntonio Huete Jimenez /* ether_type not known, print raw packet */
522*ed775ee7SAntonio Huete Jimenez if (!ndo->ndo_eflag)
523*ed775ee7SAntonio Huete Jimenez sll2_print(ndo, sllp, length + SLL2_HDR_LEN);
524*ed775ee7SAntonio Huete Jimenez if (!ndo->ndo_suppress_default_print)
525*ed775ee7SAntonio Huete Jimenez ND_DEFAULTPRINT(p, caplen);
526*ed775ee7SAntonio Huete Jimenez }
527*ed775ee7SAntonio Huete Jimenez }
528*ed775ee7SAntonio Huete Jimenez
529*ed775ee7SAntonio Huete Jimenez ndo->ndo_ll_hdr_len += hdrlen;
53041c99275SPeter Avalos }
531