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