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