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