xref: /minix3/external/bsd/tcpdump/dist/print-ether.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3*b636d99dSDavid van Moolenbroek  *	The Regents of the University of California.  All rights reserved.
4*b636d99dSDavid van Moolenbroek  *
5*b636d99dSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek  * modification, are permitted provided that: (1) source code distributions
7*b636d99dSDavid van Moolenbroek  * retain the above copyright notice and this paragraph in its entirety, (2)
8*b636d99dSDavid van Moolenbroek  * distributions including binary code include the above copyright notice and
9*b636d99dSDavid van Moolenbroek  * this paragraph in its entirety in the documentation or other materials
10*b636d99dSDavid van Moolenbroek  * provided with the distribution, and (3) all advertising materials mentioning
11*b636d99dSDavid van Moolenbroek  * features or use of this software display the following acknowledgement:
12*b636d99dSDavid van Moolenbroek  * ``This product includes software developed by the University of California,
13*b636d99dSDavid van Moolenbroek  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*b636d99dSDavid van Moolenbroek  * the University nor the names of its contributors may be used to endorse
15*b636d99dSDavid van Moolenbroek  * or promote products derived from this software without specific prior
16*b636d99dSDavid van Moolenbroek  * written permission.
17*b636d99dSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*b636d99dSDavid van Moolenbroek  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*b636d99dSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*b636d99dSDavid van Moolenbroek  */
21*b636d99dSDavid van Moolenbroek 
22*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
23*b636d99dSDavid van Moolenbroek #ifndef lint
24*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-ether.c,v 1.6 2015/03/31 21:59:35 christos Exp $");
25*b636d99dSDavid van Moolenbroek #endif
26*b636d99dSDavid van Moolenbroek 
27*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
28*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
29*b636d99dSDavid van Moolenbroek #include "config.h"
30*b636d99dSDavid van Moolenbroek #endif
31*b636d99dSDavid van Moolenbroek 
32*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
33*b636d99dSDavid van Moolenbroek 
34*b636d99dSDavid van Moolenbroek #include "interface.h"
35*b636d99dSDavid van Moolenbroek #include "extract.h"
36*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
37*b636d99dSDavid van Moolenbroek #include "ethertype.h"
38*b636d99dSDavid van Moolenbroek #include "ether.h"
39*b636d99dSDavid van Moolenbroek 
40*b636d99dSDavid van Moolenbroek const struct tok ethertype_values[] = {
41*b636d99dSDavid van Moolenbroek     { ETHERTYPE_IP,		"IPv4" },
42*b636d99dSDavid van Moolenbroek     { ETHERTYPE_MPLS,		"MPLS unicast" },
43*b636d99dSDavid van Moolenbroek     { ETHERTYPE_MPLS_MULTI,	"MPLS multicast" },
44*b636d99dSDavid van Moolenbroek     { ETHERTYPE_IPV6,		"IPv6" },
45*b636d99dSDavid van Moolenbroek     { ETHERTYPE_8021Q,		"802.1Q" },
46*b636d99dSDavid van Moolenbroek     { ETHERTYPE_8021Q9100,	"802.1Q-9100" },
47*b636d99dSDavid van Moolenbroek     { ETHERTYPE_8021QinQ,	"802.1Q-QinQ" },
48*b636d99dSDavid van Moolenbroek     { ETHERTYPE_8021Q9200,	"802.1Q-9200" },
49*b636d99dSDavid van Moolenbroek     { ETHERTYPE_VMAN,		"VMAN" },
50*b636d99dSDavid van Moolenbroek     { ETHERTYPE_PUP,            "PUP" },
51*b636d99dSDavid van Moolenbroek     { ETHERTYPE_ARP,            "ARP"},
52*b636d99dSDavid van Moolenbroek     { ETHERTYPE_REVARP,         "Reverse ARP"},
53*b636d99dSDavid van Moolenbroek     { ETHERTYPE_NS,             "NS" },
54*b636d99dSDavid van Moolenbroek     { ETHERTYPE_SPRITE,         "Sprite" },
55*b636d99dSDavid van Moolenbroek     { ETHERTYPE_TRAIL,          "Trail" },
56*b636d99dSDavid van Moolenbroek     { ETHERTYPE_MOPDL,          "MOP DL" },
57*b636d99dSDavid van Moolenbroek     { ETHERTYPE_MOPRC,          "MOP RC" },
58*b636d99dSDavid van Moolenbroek     { ETHERTYPE_DN,             "DN" },
59*b636d99dSDavid van Moolenbroek     { ETHERTYPE_LAT,            "LAT" },
60*b636d99dSDavid van Moolenbroek     { ETHERTYPE_SCA,            "SCA" },
61*b636d99dSDavid van Moolenbroek     { ETHERTYPE_TEB,            "TEB" },
62*b636d99dSDavid van Moolenbroek     { ETHERTYPE_LANBRIDGE,      "Lanbridge" },
63*b636d99dSDavid van Moolenbroek     { ETHERTYPE_DECDNS,         "DEC DNS" },
64*b636d99dSDavid van Moolenbroek     { ETHERTYPE_DECDTS,         "DEC DTS" },
65*b636d99dSDavid van Moolenbroek     { ETHERTYPE_VEXP,           "VEXP" },
66*b636d99dSDavid van Moolenbroek     { ETHERTYPE_VPROD,          "VPROD" },
67*b636d99dSDavid van Moolenbroek     { ETHERTYPE_ATALK,          "Appletalk" },
68*b636d99dSDavid van Moolenbroek     { ETHERTYPE_AARP,           "Appletalk ARP" },
69*b636d99dSDavid van Moolenbroek     { ETHERTYPE_IPX,            "IPX" },
70*b636d99dSDavid van Moolenbroek     { ETHERTYPE_PPP,            "PPP" },
71*b636d99dSDavid van Moolenbroek     { ETHERTYPE_MPCP,           "MPCP" },
72*b636d99dSDavid van Moolenbroek     { ETHERTYPE_SLOW,           "Slow Protocols" },
73*b636d99dSDavid van Moolenbroek     { ETHERTYPE_PPPOED,         "PPPoE D" },
74*b636d99dSDavid van Moolenbroek     { ETHERTYPE_PPPOES,         "PPPoE S" },
75*b636d99dSDavid van Moolenbroek     { ETHERTYPE_EAPOL,          "EAPOL" },
76*b636d99dSDavid van Moolenbroek     { ETHERTYPE_RRCP,           "RRCP" },
77*b636d99dSDavid van Moolenbroek     { ETHERTYPE_MS_NLB_HB,      "MS NLB heartbeat" },
78*b636d99dSDavid van Moolenbroek     { ETHERTYPE_JUMBO,          "Jumbo" },
79*b636d99dSDavid van Moolenbroek     { ETHERTYPE_LOOPBACK,       "Loopback" },
80*b636d99dSDavid van Moolenbroek     { ETHERTYPE_ISO,            "OSI" },
81*b636d99dSDavid van Moolenbroek     { ETHERTYPE_GRE_ISO,        "GRE-OSI" },
82*b636d99dSDavid van Moolenbroek     { ETHERTYPE_CFM_OLD,        "CFM (old)" },
83*b636d99dSDavid van Moolenbroek     { ETHERTYPE_CFM,            "CFM" },
84*b636d99dSDavid van Moolenbroek     { ETHERTYPE_IEEE1905_1,     "IEEE1905.1" },
85*b636d99dSDavid van Moolenbroek     { ETHERTYPE_LLDP,           "LLDP" },
86*b636d99dSDavid van Moolenbroek     { ETHERTYPE_TIPC,           "TIPC"},
87*b636d99dSDavid van Moolenbroek     { ETHERTYPE_GEONET_OLD,     "GeoNet (old)"},
88*b636d99dSDavid van Moolenbroek     { ETHERTYPE_GEONET,         "GeoNet"},
89*b636d99dSDavid van Moolenbroek     { ETHERTYPE_CALM_FAST,      "CALM FAST"},
90*b636d99dSDavid van Moolenbroek     { ETHERTYPE_AOE,            "AoE" },
91*b636d99dSDavid van Moolenbroek     { 0, NULL}
92*b636d99dSDavid van Moolenbroek };
93*b636d99dSDavid van Moolenbroek 
94*b636d99dSDavid van Moolenbroek static inline void
ether_hdr_print(netdissect_options * ndo,const u_char * bp,u_int length)95*b636d99dSDavid van Moolenbroek ether_hdr_print(netdissect_options *ndo,
96*b636d99dSDavid van Moolenbroek                 const u_char *bp, u_int length)
97*b636d99dSDavid van Moolenbroek {
98*b636d99dSDavid van Moolenbroek 	register const struct ether_header *ep;
99*b636d99dSDavid van Moolenbroek 	uint16_t ether_type;
100*b636d99dSDavid van Moolenbroek 
101*b636d99dSDavid van Moolenbroek 	ep = (const struct ether_header *)bp;
102*b636d99dSDavid van Moolenbroek 
103*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%s > %s",
104*b636d99dSDavid van Moolenbroek 		     etheraddr_string(ndo, ESRC(ep)),
105*b636d99dSDavid van Moolenbroek 		     etheraddr_string(ndo, EDST(ep))));
106*b636d99dSDavid van Moolenbroek 
107*b636d99dSDavid van Moolenbroek 	ether_type = EXTRACT_16BITS(&ep->ether_type);
108*b636d99dSDavid van Moolenbroek 	if (!ndo->ndo_qflag) {
109*b636d99dSDavid van Moolenbroek 	        if (ether_type <= ETHERMTU)
110*b636d99dSDavid van Moolenbroek 		          ND_PRINT((ndo, ", 802.3"));
111*b636d99dSDavid van Moolenbroek                 else
112*b636d99dSDavid van Moolenbroek 		          ND_PRINT((ndo, ", ethertype %s (0x%04x)",
113*b636d99dSDavid van Moolenbroek 				       tok2str(ethertype_values,"Unknown", ether_type),
114*b636d99dSDavid van Moolenbroek                                        ether_type));
115*b636d99dSDavid van Moolenbroek         } else {
116*b636d99dSDavid van Moolenbroek                 if (ether_type <= ETHERMTU)
117*b636d99dSDavid van Moolenbroek                           ND_PRINT((ndo, ", 802.3"));
118*b636d99dSDavid van Moolenbroek                 else
119*b636d99dSDavid van Moolenbroek                           ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type)));
120*b636d99dSDavid van Moolenbroek         }
121*b636d99dSDavid van Moolenbroek 
122*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, ", length %u: ", length));
123*b636d99dSDavid van Moolenbroek }
124*b636d99dSDavid van Moolenbroek 
125*b636d99dSDavid van Moolenbroek /*
126*b636d99dSDavid van Moolenbroek  * Print an Ethernet frame.
127*b636d99dSDavid van Moolenbroek  * This might be encapsulated within another frame; we might be passed
128*b636d99dSDavid van Moolenbroek  * a pointer to a function that can print header information for that
129*b636d99dSDavid van Moolenbroek  * frame's protocol, and an argument to pass to that function.
130*b636d99dSDavid van Moolenbroek  */
131*b636d99dSDavid van Moolenbroek void
ether_print(netdissect_options * ndo,const u_char * p,u_int length,u_int caplen,void (* print_encap_header)(netdissect_options * ndo,const u_char *),const u_char * encap_header_arg)132*b636d99dSDavid van Moolenbroek ether_print(netdissect_options *ndo,
133*b636d99dSDavid van Moolenbroek             const u_char *p, u_int length, u_int caplen,
134*b636d99dSDavid van Moolenbroek             void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg)
135*b636d99dSDavid van Moolenbroek {
136*b636d99dSDavid van Moolenbroek 	struct ether_header *ep;
137*b636d99dSDavid van Moolenbroek 	u_int orig_length;
138*b636d99dSDavid van Moolenbroek 	u_short ether_type;
139*b636d99dSDavid van Moolenbroek 	u_short extracted_ether_type;
140*b636d99dSDavid van Moolenbroek 
141*b636d99dSDavid van Moolenbroek 	if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) {
142*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|ether]"));
143*b636d99dSDavid van Moolenbroek 		return;
144*b636d99dSDavid van Moolenbroek 	}
145*b636d99dSDavid van Moolenbroek 
146*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_eflag) {
147*b636d99dSDavid van Moolenbroek 		if (print_encap_header != NULL)
148*b636d99dSDavid van Moolenbroek 			(*print_encap_header)(ndo, encap_header_arg);
149*b636d99dSDavid van Moolenbroek 		ether_hdr_print(ndo, p, length);
150*b636d99dSDavid van Moolenbroek 	}
151*b636d99dSDavid van Moolenbroek 	orig_length = length;
152*b636d99dSDavid van Moolenbroek 
153*b636d99dSDavid van Moolenbroek 	length -= ETHER_HDRLEN;
154*b636d99dSDavid van Moolenbroek 	caplen -= ETHER_HDRLEN;
155*b636d99dSDavid van Moolenbroek 	ep = (struct ether_header *)p;
156*b636d99dSDavid van Moolenbroek 	p += ETHER_HDRLEN;
157*b636d99dSDavid van Moolenbroek 
158*b636d99dSDavid van Moolenbroek 	ether_type = EXTRACT_16BITS(&ep->ether_type);
159*b636d99dSDavid van Moolenbroek 
160*b636d99dSDavid van Moolenbroek recurse:
161*b636d99dSDavid van Moolenbroek 	/*
162*b636d99dSDavid van Moolenbroek 	 * Is it (gag) an 802.3 encapsulation?
163*b636d99dSDavid van Moolenbroek 	 */
164*b636d99dSDavid van Moolenbroek 	if (ether_type <= ETHERMTU) {
165*b636d99dSDavid van Moolenbroek 		/* Try to print the LLC-layer header & higher layers */
166*b636d99dSDavid van Moolenbroek 		if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep),
167*b636d99dSDavid van Moolenbroek 		    &extracted_ether_type) == 0) {
168*b636d99dSDavid van Moolenbroek 			/* ether_type not known, print raw packet */
169*b636d99dSDavid van Moolenbroek 			if (!ndo->ndo_eflag) {
170*b636d99dSDavid van Moolenbroek 				if (print_encap_header != NULL)
171*b636d99dSDavid van Moolenbroek 					(*print_encap_header)(ndo, encap_header_arg);
172*b636d99dSDavid van Moolenbroek 				ether_hdr_print(ndo, (u_char *)ep, orig_length);
173*b636d99dSDavid van Moolenbroek 			}
174*b636d99dSDavid van Moolenbroek 
175*b636d99dSDavid van Moolenbroek 			if (!ndo->ndo_suppress_default_print)
176*b636d99dSDavid van Moolenbroek 				ND_DEFAULTPRINT(p, caplen);
177*b636d99dSDavid van Moolenbroek 		}
178*b636d99dSDavid van Moolenbroek 	} else if (ether_type == ETHERTYPE_8021Q  ||
179*b636d99dSDavid van Moolenbroek                 ether_type == ETHERTYPE_8021Q9100 ||
180*b636d99dSDavid van Moolenbroek                 ether_type == ETHERTYPE_8021Q9200 ||
181*b636d99dSDavid van Moolenbroek                 ether_type == ETHERTYPE_8021QinQ) {
182*b636d99dSDavid van Moolenbroek 		/*
183*b636d99dSDavid van Moolenbroek 		 * Print VLAN information, and then go back and process
184*b636d99dSDavid van Moolenbroek 		 * the enclosed type field.
185*b636d99dSDavid van Moolenbroek 		 */
186*b636d99dSDavid van Moolenbroek 		if (caplen < 4 || length < 4) {
187*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "[|vlan]"));
188*b636d99dSDavid van Moolenbroek 			return;
189*b636d99dSDavid van Moolenbroek 		}
190*b636d99dSDavid van Moolenbroek 	        if (ndo->ndo_eflag) {
191*b636d99dSDavid van Moolenbroek 	        	uint16_t tag = EXTRACT_16BITS(p);
192*b636d99dSDavid van Moolenbroek 
193*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s, ", ieee8021q_tci_string(tag)));
194*b636d99dSDavid van Moolenbroek 		}
195*b636d99dSDavid van Moolenbroek 
196*b636d99dSDavid van Moolenbroek 		ether_type = EXTRACT_16BITS(p + 2);
197*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_eflag && ether_type > ETHERMTU)
198*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type)));
199*b636d99dSDavid van Moolenbroek 		p += 4;
200*b636d99dSDavid van Moolenbroek 		length -= 4;
201*b636d99dSDavid van Moolenbroek 		caplen -= 4;
202*b636d99dSDavid van Moolenbroek 		goto recurse;
203*b636d99dSDavid van Moolenbroek 	} else if (ether_type == ETHERTYPE_JUMBO) {
204*b636d99dSDavid van Moolenbroek 		/*
205*b636d99dSDavid van Moolenbroek 		 * Alteon jumbo frames.
206*b636d99dSDavid van Moolenbroek 		 * See
207*b636d99dSDavid van Moolenbroek 		 *
208*b636d99dSDavid van Moolenbroek 		 *	http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01
209*b636d99dSDavid van Moolenbroek 		 *
210*b636d99dSDavid van Moolenbroek 		 * which indicates that, following the type field,
211*b636d99dSDavid van Moolenbroek 		 * there's an LLC header and payload.
212*b636d99dSDavid van Moolenbroek 		 */
213*b636d99dSDavid van Moolenbroek 		/* Try to print the LLC-layer header & higher layers */
214*b636d99dSDavid van Moolenbroek 		if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep),
215*b636d99dSDavid van Moolenbroek 		    &extracted_ether_type) == 0) {
216*b636d99dSDavid van Moolenbroek 			/* ether_type not known, print raw packet */
217*b636d99dSDavid van Moolenbroek 			if (!ndo->ndo_eflag) {
218*b636d99dSDavid van Moolenbroek 				if (print_encap_header != NULL)
219*b636d99dSDavid van Moolenbroek 					(*print_encap_header)(ndo, encap_header_arg);
220*b636d99dSDavid van Moolenbroek 				ether_hdr_print(ndo, (u_char *)ep, orig_length);
221*b636d99dSDavid van Moolenbroek 			}
222*b636d99dSDavid van Moolenbroek 
223*b636d99dSDavid van Moolenbroek 			if (!ndo->ndo_suppress_default_print)
224*b636d99dSDavid van Moolenbroek 				ND_DEFAULTPRINT(p, caplen);
225*b636d99dSDavid van Moolenbroek 		}
226*b636d99dSDavid van Moolenbroek 	} else {
227*b636d99dSDavid van Moolenbroek 		if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
228*b636d99dSDavid van Moolenbroek 			/* ether_type not known, print raw packet */
229*b636d99dSDavid van Moolenbroek 			if (!ndo->ndo_eflag) {
230*b636d99dSDavid van Moolenbroek 				if (print_encap_header != NULL)
231*b636d99dSDavid van Moolenbroek 					(*print_encap_header)(ndo, encap_header_arg);
232*b636d99dSDavid van Moolenbroek 				ether_hdr_print(ndo, (u_char *)ep, orig_length);
233*b636d99dSDavid van Moolenbroek 			}
234*b636d99dSDavid van Moolenbroek 
235*b636d99dSDavid van Moolenbroek 			if (!ndo->ndo_suppress_default_print)
236*b636d99dSDavid van Moolenbroek 				ND_DEFAULTPRINT(p, caplen);
237*b636d99dSDavid van Moolenbroek 		}
238*b636d99dSDavid van Moolenbroek 	}
239*b636d99dSDavid van Moolenbroek }
240*b636d99dSDavid van Moolenbroek 
241*b636d99dSDavid van Moolenbroek /*
242*b636d99dSDavid van Moolenbroek  * This is the top level routine of the printer.  'p' points
243*b636d99dSDavid van Moolenbroek  * to the ether header of the packet, 'h->ts' is the timestamp,
244*b636d99dSDavid van Moolenbroek  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
245*b636d99dSDavid van Moolenbroek  * is the number of bytes actually captured.
246*b636d99dSDavid van Moolenbroek  */
247*b636d99dSDavid van Moolenbroek u_int
ether_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)248*b636d99dSDavid van Moolenbroek ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
249*b636d99dSDavid van Moolenbroek                const u_char *p)
250*b636d99dSDavid van Moolenbroek {
251*b636d99dSDavid van Moolenbroek 	ether_print(ndo, p, h->len, h->caplen, NULL, NULL);
252*b636d99dSDavid van Moolenbroek 
253*b636d99dSDavid van Moolenbroek 	return (ETHER_HDRLEN);
254*b636d99dSDavid van Moolenbroek }
255*b636d99dSDavid van Moolenbroek 
256*b636d99dSDavid van Moolenbroek /*
257*b636d99dSDavid van Moolenbroek  * This is the top level routine of the printer.  'p' points
258*b636d99dSDavid van Moolenbroek  * to the ether header of the packet, 'h->ts' is the timestamp,
259*b636d99dSDavid van Moolenbroek  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
260*b636d99dSDavid van Moolenbroek  * is the number of bytes actually captured.
261*b636d99dSDavid van Moolenbroek  *
262*b636d99dSDavid van Moolenbroek  * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header
263*b636d99dSDavid van Moolenbroek  * before the Ethernet header.
264*b636d99dSDavid van Moolenbroek  */
265*b636d99dSDavid van Moolenbroek u_int
netanalyzer_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)266*b636d99dSDavid van Moolenbroek netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
267*b636d99dSDavid van Moolenbroek                      const u_char *p)
268*b636d99dSDavid van Moolenbroek {
269*b636d99dSDavid van Moolenbroek 	/*
270*b636d99dSDavid van Moolenbroek 	 * Fail if we don't have enough data for the Hilscher pseudo-header.
271*b636d99dSDavid van Moolenbroek 	 */
272*b636d99dSDavid van Moolenbroek 	if (h->len < 4 || h->caplen < 4) {
273*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|netanalyzer]"));
274*b636d99dSDavid van Moolenbroek 		return (h->caplen);
275*b636d99dSDavid van Moolenbroek 	}
276*b636d99dSDavid van Moolenbroek 
277*b636d99dSDavid van Moolenbroek 	/* Skip the pseudo-header. */
278*b636d99dSDavid van Moolenbroek 	ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL);
279*b636d99dSDavid van Moolenbroek 
280*b636d99dSDavid van Moolenbroek 	return (4 + ETHER_HDRLEN);
281*b636d99dSDavid van Moolenbroek }
282*b636d99dSDavid van Moolenbroek 
283*b636d99dSDavid van Moolenbroek /*
284*b636d99dSDavid van Moolenbroek  * This is the top level routine of the printer.  'p' points
285*b636d99dSDavid van Moolenbroek  * to the ether header of the packet, 'h->ts' is the timestamp,
286*b636d99dSDavid van Moolenbroek  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
287*b636d99dSDavid van Moolenbroek  * is the number of bytes actually captured.
288*b636d99dSDavid van Moolenbroek  *
289*b636d99dSDavid van Moolenbroek  * This is for DLT_NETANALYZER_TRANSPARENT, which has a 4-byte
290*b636d99dSDavid van Moolenbroek  * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF
291*b636d99dSDavid van Moolenbroek  * before the Ethernet header.
292*b636d99dSDavid van Moolenbroek  */
293*b636d99dSDavid van Moolenbroek u_int
netanalyzer_transparent_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)294*b636d99dSDavid van Moolenbroek netanalyzer_transparent_if_print(netdissect_options *ndo,
295*b636d99dSDavid van Moolenbroek                                  const struct pcap_pkthdr *h,
296*b636d99dSDavid van Moolenbroek                                  const u_char *p)
297*b636d99dSDavid van Moolenbroek {
298*b636d99dSDavid van Moolenbroek 	/*
299*b636d99dSDavid van Moolenbroek 	 * Fail if we don't have enough data for the Hilscher pseudo-header,
300*b636d99dSDavid van Moolenbroek 	 * preamble, and SOF.
301*b636d99dSDavid van Moolenbroek 	 */
302*b636d99dSDavid van Moolenbroek 	if (h->len < 12 || h->caplen < 12) {
303*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|netanalyzer-transparent]"));
304*b636d99dSDavid van Moolenbroek 		return (h->caplen);
305*b636d99dSDavid van Moolenbroek 	}
306*b636d99dSDavid van Moolenbroek 
307*b636d99dSDavid van Moolenbroek 	/* Skip the pseudo-header, preamble, and SOF. */
308*b636d99dSDavid van Moolenbroek 	ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL);
309*b636d99dSDavid van Moolenbroek 
310*b636d99dSDavid van Moolenbroek 	return (12 + ETHER_HDRLEN);
311*b636d99dSDavid van Moolenbroek }
312*b636d99dSDavid van Moolenbroek 
313*b636d99dSDavid van Moolenbroek /*
314*b636d99dSDavid van Moolenbroek  * Prints the packet payload, given an Ethernet type code for the payload's
315*b636d99dSDavid van Moolenbroek  * protocol.
316*b636d99dSDavid van Moolenbroek  *
317*b636d99dSDavid van Moolenbroek  * Returns non-zero if it can do so, zero if the ethertype is unknown.
318*b636d99dSDavid van Moolenbroek  */
319*b636d99dSDavid van Moolenbroek 
320*b636d99dSDavid van Moolenbroek int
ethertype_print(netdissect_options * ndo,u_short ether_type,const u_char * p,u_int length,u_int caplen)321*b636d99dSDavid van Moolenbroek ethertype_print(netdissect_options *ndo,
322*b636d99dSDavid van Moolenbroek                 u_short ether_type, const u_char *p,
323*b636d99dSDavid van Moolenbroek                 u_int length, u_int caplen)
324*b636d99dSDavid van Moolenbroek {
325*b636d99dSDavid van Moolenbroek 	switch (ether_type) {
326*b636d99dSDavid van Moolenbroek 
327*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IP:
328*b636d99dSDavid van Moolenbroek 	        ip_print(ndo, p, length);
329*b636d99dSDavid van Moolenbroek 		return (1);
330*b636d99dSDavid van Moolenbroek 
331*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IPV6:
332*b636d99dSDavid van Moolenbroek 		ip6_print(ndo, p, length);
333*b636d99dSDavid van Moolenbroek 		return (1);
334*b636d99dSDavid van Moolenbroek 
335*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_ARP:
336*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_REVARP:
337*b636d99dSDavid van Moolenbroek   	        arp_print(ndo, p, length, caplen);
338*b636d99dSDavid van Moolenbroek 		return (1);
339*b636d99dSDavid van Moolenbroek 
340*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_DN:
341*b636d99dSDavid van Moolenbroek 		decnet_print(ndo, p, length, caplen);
342*b636d99dSDavid van Moolenbroek 		return (1);
343*b636d99dSDavid van Moolenbroek 
344*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_ATALK:
345*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag)
346*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "et1 "));
347*b636d99dSDavid van Moolenbroek 		atalk_print(ndo, p, length);
348*b636d99dSDavid van Moolenbroek 		return (1);
349*b636d99dSDavid van Moolenbroek 
350*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_AARP:
351*b636d99dSDavid van Moolenbroek 		aarp_print(ndo, p, length);
352*b636d99dSDavid van Moolenbroek 		return (1);
353*b636d99dSDavid van Moolenbroek 
354*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IPX:
355*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "(NOV-ETHII) "));
356*b636d99dSDavid van Moolenbroek 		ipx_print(ndo, p, length);
357*b636d99dSDavid van Moolenbroek 		return (1);
358*b636d99dSDavid van Moolenbroek 
359*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_ISO:
360*b636d99dSDavid van Moolenbroek 		isoclns_print(ndo, p + 1, length - 1, length - 1);
361*b636d99dSDavid van Moolenbroek 		return(1);
362*b636d99dSDavid van Moolenbroek 
363*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_PPPOED:
364*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_PPPOES:
365*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_PPPOED2:
366*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_PPPOES2:
367*b636d99dSDavid van Moolenbroek 		pppoe_print(ndo, p, length);
368*b636d99dSDavid van Moolenbroek 		return (1);
369*b636d99dSDavid van Moolenbroek 
370*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_EAPOL:
371*b636d99dSDavid van Moolenbroek 	        eap_print(ndo, p, length);
372*b636d99dSDavid van Moolenbroek 		return (1);
373*b636d99dSDavid van Moolenbroek 
374*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_RRCP:
375*b636d99dSDavid van Moolenbroek 	        rrcp_print(ndo, p - 14 , length + 14);
376*b636d99dSDavid van Moolenbroek 		return (1);
377*b636d99dSDavid van Moolenbroek 
378*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_PPP:
379*b636d99dSDavid van Moolenbroek 		if (length) {
380*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": "));
381*b636d99dSDavid van Moolenbroek 			ppp_print(ndo, p, length);
382*b636d99dSDavid van Moolenbroek 		}
383*b636d99dSDavid van Moolenbroek 		return (1);
384*b636d99dSDavid van Moolenbroek 
385*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_MPCP:
386*b636d99dSDavid van Moolenbroek 	        mpcp_print(ndo, p, length);
387*b636d99dSDavid van Moolenbroek 		return (1);
388*b636d99dSDavid van Moolenbroek 
389*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_SLOW:
390*b636d99dSDavid van Moolenbroek 	        slow_print(ndo, p, length);
391*b636d99dSDavid van Moolenbroek 		return (1);
392*b636d99dSDavid van Moolenbroek 
393*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_CFM:
394*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_CFM_OLD:
395*b636d99dSDavid van Moolenbroek 		cfm_print(ndo, p, length);
396*b636d99dSDavid van Moolenbroek 		return (1);
397*b636d99dSDavid van Moolenbroek 
398*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_LLDP:
399*b636d99dSDavid van Moolenbroek 		lldp_print(ndo, p, length);
400*b636d99dSDavid van Moolenbroek 		return (1);
401*b636d99dSDavid van Moolenbroek 
402*b636d99dSDavid van Moolenbroek         case ETHERTYPE_LOOPBACK:
403*b636d99dSDavid van Moolenbroek 		loopback_print(ndo, p, length);
404*b636d99dSDavid van Moolenbroek                 return (1);
405*b636d99dSDavid van Moolenbroek 
406*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_MPLS:
407*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_MPLS_MULTI:
408*b636d99dSDavid van Moolenbroek 		mpls_print(ndo, p, length);
409*b636d99dSDavid van Moolenbroek 		return (1);
410*b636d99dSDavid van Moolenbroek 
411*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_TIPC:
412*b636d99dSDavid van Moolenbroek 		tipc_print(ndo, p, length, caplen);
413*b636d99dSDavid van Moolenbroek 		return (1);
414*b636d99dSDavid van Moolenbroek 
415*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_MS_NLB_HB:
416*b636d99dSDavid van Moolenbroek 		msnlb_print(ndo, p);
417*b636d99dSDavid van Moolenbroek 		return (1);
418*b636d99dSDavid van Moolenbroek 
419*b636d99dSDavid van Moolenbroek         case ETHERTYPE_GEONET_OLD:
420*b636d99dSDavid van Moolenbroek         case ETHERTYPE_GEONET:
421*b636d99dSDavid van Moolenbroek                 geonet_print(ndo, p-14, p, length);
422*b636d99dSDavid van Moolenbroek                 return (1);
423*b636d99dSDavid van Moolenbroek 
424*b636d99dSDavid van Moolenbroek         case ETHERTYPE_CALM_FAST:
425*b636d99dSDavid van Moolenbroek                 calm_fast_print(ndo, p-14, p, length);
426*b636d99dSDavid van Moolenbroek                 return (1);
427*b636d99dSDavid van Moolenbroek 
428*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_AOE:
429*b636d99dSDavid van Moolenbroek 		aoe_print(ndo, p, length);
430*b636d99dSDavid van Moolenbroek 		return (1);
431*b636d99dSDavid van Moolenbroek 
432*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_LAT:
433*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_SCA:
434*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_MOPRC:
435*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_MOPDL:
436*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IEEE1905_1:
437*b636d99dSDavid van Moolenbroek 		/* default_print for now */
438*b636d99dSDavid van Moolenbroek 	default:
439*b636d99dSDavid van Moolenbroek 		return (0);
440*b636d99dSDavid van Moolenbroek 	}
441*b636d99dSDavid van Moolenbroek }
442*b636d99dSDavid van Moolenbroek 
443*b636d99dSDavid van Moolenbroek 
444*b636d99dSDavid van Moolenbroek /*
445*b636d99dSDavid van Moolenbroek  * Local Variables:
446*b636d99dSDavid van Moolenbroek  * c-style: whitesmith
447*b636d99dSDavid van Moolenbroek  * c-basic-offset: 8
448*b636d99dSDavid van Moolenbroek  * End:
449*b636d99dSDavid van Moolenbroek  */
450*b636d99dSDavid van Moolenbroek 
451