xref: /freebsd/contrib/tcpdump/print-sll.c (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
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
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
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
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
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