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