1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
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#include <sys/cdefs.h>
22#ifndef lint
23#if 0
24static const char rcsid[] _U_ =
25    "@(#) Header: /tcpdump/master/tcpdump/print-ether.c,v 1.106 2008-02-06 10:47:53 guy Exp (LBL)";
26#else
27__RCSID("$NetBSD$");
28#endif
29#endif
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include <tcpdump-stdinc.h>
36
37#include <stdio.h>
38#include <pcap.h>
39
40#include "interface.h"
41#include "extract.h"
42#include "addrtoname.h"
43#include "ethertype.h"
44
45#include "ether.h"
46
47const struct tok ethertype_values[] = {
48    { ETHERTYPE_IP,		"IPv4" },
49    { ETHERTYPE_MPLS,		"MPLS unicast" },
50    { ETHERTYPE_MPLS_MULTI,	"MPLS multicast" },
51    { ETHERTYPE_IPV6,		"IPv6" },
52    { ETHERTYPE_8021Q,		"802.1Q" },
53    { ETHERTYPE_VMAN,		"VMAN" },
54    { ETHERTYPE_PUP,            "PUP" },
55    { ETHERTYPE_ARP,            "ARP"},
56    { ETHERTYPE_REVARP,         "Reverse ARP"},
57    { ETHERTYPE_NS,             "NS" },
58    { ETHERTYPE_SPRITE,         "Sprite" },
59    { ETHERTYPE_TRAIL,          "Trail" },
60    { ETHERTYPE_MOPDL,          "MOP DL" },
61    { ETHERTYPE_MOPRC,          "MOP RC" },
62    { ETHERTYPE_DN,             "DN" },
63    { ETHERTYPE_LAT,            "LAT" },
64    { ETHERTYPE_SCA,            "SCA" },
65    { ETHERTYPE_TEB,            "TEB" },
66    { ETHERTYPE_LANBRIDGE,      "Lanbridge" },
67    { ETHERTYPE_DECDNS,         "DEC DNS" },
68    { ETHERTYPE_DECDTS,         "DEC DTS" },
69    { ETHERTYPE_VEXP,           "VEXP" },
70    { ETHERTYPE_VPROD,          "VPROD" },
71    { ETHERTYPE_ATALK,          "Appletalk" },
72    { ETHERTYPE_AARP,           "Appletalk ARP" },
73    { ETHERTYPE_IPX,            "IPX" },
74    { ETHERTYPE_PPP,            "PPP" },
75    { ETHERTYPE_MPCP,           "MPCP" },
76    { ETHERTYPE_SLOW,           "Slow Protocols" },
77    { ETHERTYPE_PPPOED,         "PPPoE D" },
78    { ETHERTYPE_PPPOES,         "PPPoE S" },
79    { ETHERTYPE_EAPOL,          "EAPOL" },
80    { ETHERTYPE_RRCP,           "RRCP" },
81    { ETHERTYPE_JUMBO,          "Jumbo" },
82    { ETHERTYPE_LOOPBACK,       "Loopback" },
83    { ETHERTYPE_ISO,            "OSI" },
84    { ETHERTYPE_GRE_ISO,        "GRE-OSI" },
85    { ETHERTYPE_CFM_OLD,        "CFM (old)" },
86    { ETHERTYPE_CFM,            "CFM" },
87    { ETHERTYPE_LLDP,           "LLDP" },
88    { 0, NULL}
89};
90
91static inline void
92ether_hdr_print(register const u_char *bp, u_int length)
93{
94	register const struct ether_header *ep;
95	u_int16_t ether_type;
96
97	ep = (const struct ether_header *)bp;
98
99	(void)printf("%s > %s",
100		     etheraddr_string(ESRC(ep)),
101		     etheraddr_string(EDST(ep)));
102
103	ether_type = EXTRACT_16BITS(&ep->ether_type);
104	if (!qflag) {
105	        if (ether_type <= ETHERMTU)
106		          (void)printf(", 802.3");
107                else
108		          (void)printf(", ethertype %s (0x%04x)",
109				       tok2str(ethertype_values,"Unknown", ether_type),
110                                       ether_type);
111        } else {
112                if (ether_type <= ETHERMTU)
113                          (void)printf(", 802.3");
114                else
115                          (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type));
116        }
117
118	(void)printf(", length %u: ", length);
119}
120
121/*
122 * Print an Ethernet frame.
123 * This might be encapsulated within another frame; we might be passed
124 * a pointer to a function that can print header information for that
125 * frame's protocol, and an argument to pass to that function.
126 */
127void
128ether_print(const u_char *p, u_int length, u_int caplen,
129    void (*print_encap_header)(const u_char *), const u_char *encap_header_arg)
130{
131	struct ether_header *ep;
132	u_int orig_length;
133	u_short ether_type;
134	u_short extracted_ether_type;
135
136	if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) {
137		printf("[|ether]");
138		return;
139	}
140
141	if (eflag) {
142		if (print_encap_header != NULL)
143			(*print_encap_header)(encap_header_arg);
144		ether_hdr_print(p, length);
145	}
146	orig_length = length;
147
148	length -= ETHER_HDRLEN;
149	caplen -= ETHER_HDRLEN;
150	ep = (struct ether_header *)p;
151	p += ETHER_HDRLEN;
152
153	ether_type = EXTRACT_16BITS(&ep->ether_type);
154
155recurse:
156	/*
157	 * Is it (gag) an 802.3 encapsulation?
158	 */
159	if (ether_type <= ETHERMTU) {
160		/* Try to print the LLC-layer header & higher layers */
161		if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
162		    &extracted_ether_type) == 0) {
163			/* ether_type not known, print raw packet */
164			if (!eflag) {
165				if (print_encap_header != NULL)
166					(*print_encap_header)(encap_header_arg);
167				ether_hdr_print((u_char *)ep, orig_length);
168			}
169
170			if (!suppress_default_print)
171				default_print(p, caplen);
172		}
173	} else if (ether_type == ETHERTYPE_8021Q) {
174		/*
175		 * Print VLAN information, and then go back and process
176		 * the enclosed type field.
177		 */
178		if (caplen < 4 || length < 4) {
179			printf("[|vlan]");
180			return;
181		}
182	        if (eflag) {
183	        	u_int16_t tag = EXTRACT_16BITS(p);
184
185			printf("vlan %u, p %u%s, ",
186			    tag & 0xfff,
187			    tag >> 13,
188			    (tag & 0x1000) ? ", CFI" : "");
189		}
190
191		ether_type = EXTRACT_16BITS(p + 2);
192		if (eflag && ether_type > ETHERMTU)
193			printf("ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type));
194		p += 4;
195		length -= 4;
196		caplen -= 4;
197		goto recurse;
198	} else if (ether_type == ETHERTYPE_JUMBO) {
199		/*
200		 * Alteon jumbo frames.
201		 * See
202		 *
203		 *	http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01
204		 *
205		 * which indicates that, following the type field,
206		 * there's an LLC header and payload.
207		 */
208		/* Try to print the LLC-layer header & higher layers */
209		if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
210		    &extracted_ether_type) == 0) {
211			/* ether_type not known, print raw packet */
212			if (!eflag) {
213				if (print_encap_header != NULL)
214					(*print_encap_header)(encap_header_arg);
215				ether_hdr_print((u_char *)ep, orig_length);
216			}
217
218			if (!suppress_default_print)
219				default_print(p, caplen);
220		}
221	} else {
222		if (ethertype_print(ether_type, p, length, caplen) == 0) {
223			/* ether_type not known, print raw packet */
224			if (!eflag) {
225				if (print_encap_header != NULL)
226					(*print_encap_header)(encap_header_arg);
227				ether_hdr_print((u_char *)ep, orig_length);
228			}
229
230			if (!suppress_default_print)
231				default_print(p, caplen);
232		}
233	}
234}
235
236/*
237 * This is the top level routine of the printer.  'p' points
238 * to the ether header of the packet, 'h->ts' is the timestamp,
239 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
240 * is the number of bytes actually captured.
241 */
242u_int
243ether_if_print(const struct pcap_pkthdr *h, const u_char *p)
244{
245	ether_print(p, h->len, h->caplen, NULL, NULL);
246
247	return (ETHER_HDRLEN);
248}
249
250/*
251 * Prints the packet payload, given an Ethernet type code for the payload's
252 * protocol.
253 *
254 * Returns non-zero if it can do so, zero if the ethertype is unknown.
255 */
256
257int
258ethertype_print(u_short ether_type, const u_char *p, u_int length, u_int caplen)
259{
260	switch (ether_type) {
261
262	case ETHERTYPE_IP:
263	        ip_print(gndo, p, length);
264		return (1);
265
266#ifdef INET6
267	case ETHERTYPE_IPV6:
268		ip6_print(p, length);
269		return (1);
270#endif /*INET6*/
271
272	case ETHERTYPE_ARP:
273	case ETHERTYPE_REVARP:
274  	        arp_print(gndo, p, length, caplen);
275		return (1);
276
277	case ETHERTYPE_DN:
278		decnet_print(p, length, caplen);
279		return (1);
280
281	case ETHERTYPE_ATALK:
282		if (vflag)
283			fputs("et1 ", stdout);
284		atalk_print(p, length);
285		return (1);
286
287	case ETHERTYPE_AARP:
288		aarp_print(p, length);
289		return (1);
290
291	case ETHERTYPE_IPX:
292		printf("(NOV-ETHII) ");
293		ipx_print(p, length);
294		return (1);
295
296        case ETHERTYPE_ISO:
297                isoclns_print(p+1, length-1, length-1);
298                return(1);
299
300	case ETHERTYPE_PPPOED:
301	case ETHERTYPE_PPPOES:
302	case ETHERTYPE_PPPOED2:
303	case ETHERTYPE_PPPOES2:
304		pppoe_print(p, length);
305		return (1);
306
307	case ETHERTYPE_EAPOL:
308	        eap_print(gndo, p, length);
309		return (1);
310
311	case ETHERTYPE_RRCP:
312	        rrcp_print(gndo, p - 14 , length + 14);
313		return (1);
314
315	case ETHERTYPE_PPP:
316		if (length) {
317			printf(": ");
318			ppp_print(p, length);
319		}
320		return (1);
321
322	case ETHERTYPE_MPCP:
323	        mpcp_print(p, length);
324		return (1);
325
326	case ETHERTYPE_SLOW:
327	        slow_print(p, length);
328		return (1);
329
330	case ETHERTYPE_CFM:
331	case ETHERTYPE_CFM_OLD:
332	        cfm_print(p, length);
333		return (1);
334
335	case ETHERTYPE_LLDP:
336	        lldp_print(p, length);
337		return (1);
338
339        case ETHERTYPE_LOOPBACK:
340                return (1);
341
342	case ETHERTYPE_MPLS:
343	case ETHERTYPE_MPLS_MULTI:
344		mpls_print(p, length);
345		return (1);
346
347	case ETHERTYPE_LAT:
348	case ETHERTYPE_SCA:
349	case ETHERTYPE_MOPRC:
350	case ETHERTYPE_MOPDL:
351		/* default_print for now */
352	default:
353		return (0);
354	}
355}
356
357
358/*
359 * Local Variables:
360 * c-style: whitesmith
361 * c-basic-offset: 8
362 * End:
363 */
364
365