xref: /openbsd-src/usr.sbin/tcpdump/print-ether.c (revision 5a38ef86d0b61900239c7913d24a05e7b88a58f0)
1 /*	$OpenBSD: print-ether.c,v 1.39 2021/12/01 18:28:46 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  */
23 
24 #include <sys/time.h>
25 #include <sys/socket.h>
26 
27 #include <net/if.h>
28 
29 #include <netinet/in.h>
30 #include <netinet/if_ether.h>
31 #include <netinet/ip.h>
32 #include <netinet/ip6.h>
33 #include <netinet/ip_var.h>
34 #include <netinet/udp.h>
35 #include <netinet/udp_var.h>
36 #include <netinet/tcp.h>
37 
38 #include <stdio.h>
39 #include <pcap.h>
40 
41 
42 #include "interface.h"
43 #include "addrtoname.h"
44 #include "ethertype.h"
45 #include "extract.h"
46 
47 const u_char *packetp;
48 const u_char *snapend;
49 
50 void ether_macctl(const u_char *, u_int);
51 void ether_pbb_print(const u_char *, u_int, u_int);
52 
53 void
54 ether_print(const u_char *bp, u_int length)
55 {
56 	const struct ether_header *ep;
57 
58 	ep = (const struct ether_header *)bp;
59 	if (qflag) {
60 		TCHECK2(*ep, 12);
61 		printf("%s %s %d: ",
62 		    etheraddr_string(ESRC(ep)),
63 		    etheraddr_string(EDST(ep)),
64 		    length);
65 	} else {
66 		TCHECK2(*ep, 14);
67 		printf("%s %s %s %d: ",
68 		    etheraddr_string(ESRC(ep)),
69 		    etheraddr_string(EDST(ep)),
70 		    etherproto_string(ep->ether_type),
71 		    length);
72 	}
73 	return;
74 trunc:
75 	printf("[|ether] ");
76 }
77 
78 u_short extracted_ethertype;
79 
80 /*
81  * This is the top level routine of the printer.  'p' is the points
82  * to the ether header of the packet, 'tvp' is the timestamp,
83  * 'length' is the length of the packet off the wire, and 'caplen'
84  * is the number of bytes actually captured.
85  */
86 void
87 ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
88 {
89 	ts_print(&h->ts);
90 
91 	/*
92 	 * Some printers want to get back at the ethernet addresses,
93 	 * and/or check that they're not walking off the end of the packet.
94 	 * Rather than pass them all the way down, we set these globals.
95 	 */
96 	snapend = p + h->caplen;
97 
98 	ether_tryprint(p, h->len, 1);
99 }
100 
101 void
102 ether_tryprint(const u_char *p, u_int length, int first_header)
103 {
104 	struct ether_header *ep;
105 	u_int caplen = snapend - p;
106 	u_short ether_type;
107 
108 	if (caplen < sizeof(struct ether_header)) {
109 		printf("[|ether]");
110 		goto out;
111 	}
112 
113 	if (eflag)
114 		ether_print(p, length);
115 
116 	packetp = p;
117 	length -= sizeof(struct ether_header);
118 	caplen -= sizeof(struct ether_header);
119 	ep = (struct ether_header *)p;
120 	p += sizeof(struct ether_header);
121 
122 	ether_type = ntohs(ep->ether_type);
123 
124 	/*
125 	 * Is it (gag) an 802.3 encapsulation?
126 	 */
127 	extracted_ethertype = 0;
128 	if (ether_type <= ETHERMTU) {
129 		/* Try to print the LLC-layer header & higher layers */
130 		if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) {
131 			/* ether_type not known, print raw packet */
132 			if (!eflag)
133 				ether_print((u_char *)ep, length);
134 			if (extracted_ethertype) {
135 				printf("(LLC %s) ",
136 			       etherproto_string(htons(extracted_ethertype)));
137 			}
138 			if (!xflag && !qflag) {
139 				if (eflag)
140 					default_print(packetp,
141 					    snapend - packetp);
142 				else
143 					default_print(p, caplen);
144 			}
145 		}
146 	} else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
147 		/* ether_type not known, print raw packet */
148 		if (!eflag)
149 			ether_print((u_char *)ep, length + sizeof(*ep));
150 		if (!xflag && !qflag) {
151 			if (eflag)
152 				default_print(packetp, snapend - packetp);
153 			else
154 				default_print(p, caplen);
155 		}
156 	}
157 	if (xflag && first_header) {
158 		if (eflag)
159 			default_print(packetp, snapend - packetp);
160 		else
161 			default_print(p, caplen);
162 	}
163  out:
164 	if (first_header)
165 		putchar('\n');
166 }
167 
168 void
169 ether_pbb_print(const u_char *bp, u_int length, u_int caplen)
170 {
171 	uint32_t itag;
172 	uint8_t pri, res;
173 
174 	if (caplen < sizeof(itag))
175 		goto trunc;
176 
177 	itag = EXTRACT_32BITS(bp);
178 
179 	bp += sizeof(itag);
180 	length -= sizeof(itag);
181 	caplen -= sizeof(itag);
182 
183 	pri = itag >> 29;
184 	if (pri <= 1)
185 		pri = !pri;
186 
187 	res = (itag >> 24) & 0x7;
188 
189 	printf("802.1Q ivid %u pri %u ", itag & 0xffffff, pri);
190 	if (itag & (1 << 28))
191 		printf("dei ");
192 	if (itag & (1 << 27))
193 		printf("uca ");
194 	if (res)
195 		printf("res %u! ", res);
196 
197 	ether_tryprint(bp, length, 0);
198 
199 	return;
200 
201 trunc:
202 	printf("[|pbb] ");
203 }
204 
205 /*
206  * Prints the packet encapsulated in an Ethernet data segment
207  * (or an equivalent encapsulation), given the Ethernet type code.
208  *
209  * Returns non-zero if it can do so, zero if the ethertype is unknown.
210  *
211  * Stuffs the ether type into a global for the benefit of lower layers
212  * that might want to know what it is.
213  */
214 
215 int
216 ether_encap_print(u_short ethertype, const u_char *p,
217     u_int length, u_int caplen)
218 {
219 	uint16_t vlan, pri, vid;
220 recurse:
221 	extracted_ethertype = ethertype;
222 
223 	switch (ethertype) {
224 
225 	case ETHERTYPE_IP:
226 		ip_print(p, length);
227 		return (1);
228 
229 	case ETHERTYPE_IPV6:
230 		ip6_print(p, length);
231 		return (1);
232 
233 	case ETHERTYPE_ARP:
234 	case ETHERTYPE_REVARP:
235 		arp_print(p, length, caplen);
236 		return (1);
237 
238 	case ETHERTYPE_DN:
239 		decnet_print(p, length, caplen);
240 		return (1);
241 
242 	case ETHERTYPE_ATALK:
243 		if (vflag)
244 			printf("et1 ");
245 		atalk_print_llap(p, length);
246 		return (1);
247 
248 	case ETHERTYPE_AARP:
249 		aarp_print(p, length);
250 		return (1);
251 
252 	case ETHERTYPE_8021Q:
253 		printf("802.1Q ");
254 	case ETHERTYPE_QINQ:
255 		if (ethertype == ETHERTYPE_QINQ)
256 			printf("QinQ s");
257 
258 		/* XXX caplen check */
259 
260 		vlan = ntohs(*(unsigned short*)p);
261 		vid = vlan & 0xfff;
262 		pri = vlan >> 13;
263 		if (pri <= 1)
264 			pri = !pri;
265 
266 		printf("vid %d pri %d%s", vid, pri,
267 		    vlan & 0x1000 ? " dei " : " ");
268 		ethertype = ntohs(*(unsigned short*)(p+2));
269 		p += 4;
270 		length -= 4;
271 		caplen -= 4;
272 		if (ethertype > ETHERMTU)
273 			goto recurse;
274 
275 		extracted_ethertype = 0;
276 
277 		if (llc_print(p, length, caplen, p-18, p-12) == 0) {
278 			/* ether_type not known, print raw packet */
279 			if (!eflag)
280 				ether_print(p-18, length+4);
281 			if (extracted_ethertype) {
282 				printf("(LLC %s) ",
283 				etherproto_string(htons(extracted_ethertype)));
284 			}
285 			if (!xflag && !qflag)
286 				default_print(p-18, caplen+4);
287 		}
288 		return (1);
289 
290 #ifndef ETHERTYPE_NSH
291 #define ETHERTYPE_NSH 0x894f
292 #endif
293 	case ETHERTYPE_NSH:
294 		nsh_print(p, length);
295 		return (1);
296 
297 #ifndef ETHERTYPE_PBB
298 #define ETHERTYPE_PBB 0x88e7
299 #endif
300 	case ETHERTYPE_PBB:
301 		ether_pbb_print(p, length, caplen);
302 		return (1);
303 
304 #ifndef ETHERTYPE_NHRP
305 #define ETHERTYPE_NHRP 0x2001
306 #endif
307 	case ETHERTYPE_NHRP:
308 		nhrp_print(p, length);
309 		return (1);
310 
311 #ifdef PPP
312 	case ETHERTYPE_PPPOEDISC:
313 	case ETHERTYPE_PPPOE:
314 		pppoe_if_print(ethertype, p, length, caplen);
315 		return (1);
316 #endif
317 
318 	case ETHERTYPE_FLOWCONTROL:
319 		ether_macctl(p, length);
320 		return (1);
321 
322 	case ETHERTYPE_MPLS:
323 	case ETHERTYPE_MPLS_MCAST:
324 		mpls_print(p, length);
325 		return (1);
326 
327 	case ETHERTYPE_LLDP:
328 		lldp_print(p, length);
329 		return (1);
330 
331 	case ETHERTYPE_SLOW:
332 		slow_print(p, length);
333 		return (1);
334 
335 	case ETHERTYPE_LAT:
336 	case ETHERTYPE_SCA:
337 	case ETHERTYPE_MOPRC:
338 	case ETHERTYPE_MOPDL:
339 		/* default_print for now */
340 	default:
341 		return (0);
342 	}
343 }
344 
345 void
346 ether_macctl(const u_char *p, u_int length)
347 {
348 	printf("MACCTL");
349 
350 	if (length < 2)
351 		goto trunc;
352 	if (EXTRACT_16BITS(p) == 0x0001) {
353 		u_int plen;
354 
355 		printf(" PAUSE");
356 
357 		length -= 2;
358 		p += 2;
359 		if (length < 2)
360 			goto trunc;
361 		plen = 512 * EXTRACT_16BITS(p);
362 		printf(" quanta %u", plen);
363 	} else {
364 		printf(" unknown-opcode(0x%04x)", EXTRACT_16BITS(p));
365 	}
366 	return;
367 
368 trunc:
369 	printf("[|MACCTL]");
370 }
371