print-ether.c revision 146778
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 * $FreeBSD: head/contrib/tcpdump/print-ether.c 146778 2005-05-29 19:09:28Z sam $
22 */
23#ifndef lint
24static const char rcsid[] _U_ =
25    "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.95 2005/04/06 21:32:39 mcr Exp $ (LBL)";
26#endif
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <tcpdump-stdinc.h>
33
34#include <stdio.h>
35#include <pcap.h>
36
37#include "interface.h"
38#include "addrtoname.h"
39#include "ethertype.h"
40
41#include "ether.h"
42#include "llc.h"
43
44const struct tok ethertype_values[] = {
45    /* not really ethertypes but PIDs that are used
46       in the SNAP printer - its more convenient
47       to put them into a single tokentable */
48    { PID_RFC2684_ETH_FCS,      "Ethernet + FCS" },
49    { PID_RFC2684_ETH_NOFCS,    "Ethernet no FCS" },
50    { PID_RFC2684_802_4_FCS,    "802.4 + FCS" },
51    { PID_RFC2684_802_4_NOFCS,  "w/o FCS" },
52    { PID_RFC2684_802_5_FCS,    "Tokenring + FCS" },
53    { PID_RFC2684_802_5_NOFCS,  "Tokenring no FCS" },
54    { PID_RFC2684_FDDI_FCS,     "FDDI + FCS" },
55    { PID_RFC2684_FDDI_NOFCS,   "FDDI no FCS" },
56    { PID_RFC2684_802_6_FCS,    "802.6 + FCS" },
57    { PID_RFC2684_802_6_NOFCS,  "802.6 no FCS" },
58    { PID_RFC2684_BPDU,         "BPDU" },
59    /* the real Ethertypes */
60    { ETHERTYPE_IP,		"IPv4" },
61    { ETHERTYPE_MPLS,		"MPLS unicast" },
62    { ETHERTYPE_MPLS_MULTI,	"MPLS multicast" },
63    { ETHERTYPE_IPV6,		"IPv6" },
64    { ETHERTYPE_8021Q,		"802.1Q" },
65    { ETHERTYPE_VMAN,		"VMAN" },
66    { ETHERTYPE_PUP,            "PUP" },
67    { ETHERTYPE_ARP,            "ARP"},
68    { ETHERTYPE_REVARP ,        "Reverse ARP"},
69    { ETHERTYPE_NS,             "NS" },
70    { ETHERTYPE_SPRITE,         "Sprite" },
71    { ETHERTYPE_TRAIL,          "Trail" },
72    { ETHERTYPE_MOPDL,          "MOP DL" },
73    { ETHERTYPE_MOPRC,          "MOP RC" },
74    { ETHERTYPE_DN,             "DN" },
75    { ETHERTYPE_LAT,            "LAT" },
76    { ETHERTYPE_SCA,            "SCA" },
77    { ETHERTYPE_LANBRIDGE,      "Lanbridge" },
78    { ETHERTYPE_DECDNS,         "DEC DNS" },
79    { ETHERTYPE_DECDTS,         "DEC DTS" },
80    { ETHERTYPE_VEXP,           "VEXP" },
81    { ETHERTYPE_VPROD,          "VPROD" },
82    { ETHERTYPE_ATALK,          "Appletalk" },
83    { ETHERTYPE_AARP,           "Appletalk ARP" },
84    { ETHERTYPE_IPX,            "IPX" },
85    { ETHERTYPE_PPP,            "PPP" },
86    { ETHERTYPE_PPPOED,         "PPPoE D" },
87    { ETHERTYPE_PPPOES,         "PPPoE S" },
88    { ETHERTYPE_EAPOL,          "EAPOL" },
89    { ETHERTYPE_JUMBO,          "Jumbo" },
90    { ETHERTYPE_LOOPBACK,       "Loopback" },
91    { ETHERTYPE_ISO,            "OSI" },
92    { ETHERTYPE_GRE_ISO,        "GRE-OSI" },
93    { 0, NULL}
94};
95
96static inline void
97ether_hdr_print(register const u_char *bp, u_int length)
98{
99	register const struct ether_header *ep;
100	ep = (const struct ether_header *)bp;
101
102	(void)printf("%s > %s",
103		     etheraddr_string(ESRC(ep)),
104		     etheraddr_string(EDST(ep)));
105
106	if (!qflag) {
107	        if (ntohs(ep->ether_type) <= ETHERMTU)
108		          (void)printf(", 802.3");
109                else
110		          (void)printf(", ethertype %s (0x%04x)",
111				       tok2str(ethertype_values,"Unknown", ntohs(ep->ether_type)),
112                                       ntohs(ep->ether_type));
113        } else {
114                if (ntohs(ep->ether_type) <= ETHERMTU)
115                          (void)printf(", 802.3");
116                else
117                          (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ntohs(ep->ether_type)));
118        }
119
120	(void)printf(", length %u: ", length);
121}
122
123void
124ether_print(const u_char *p, u_int length, u_int caplen)
125{
126	struct ether_header *ep;
127	u_short ether_type;
128	u_short extracted_ether_type;
129
130	if (caplen < ETHER_HDRLEN) {
131		printf("[|ether]");
132		return;
133	}
134
135	if (eflag)
136		ether_hdr_print(p, length);
137
138	length -= ETHER_HDRLEN;
139	caplen -= ETHER_HDRLEN;
140	ep = (struct ether_header *)p;
141	p += ETHER_HDRLEN;
142
143	ether_type = ntohs(ep->ether_type);
144
145	/*
146	 * Is it (gag) an 802.3 encapsulation?
147	 */
148	extracted_ether_type = 0;
149	if (ether_type <= ETHERMTU) {
150		/* Try to print the LLC-layer header & higher layers */
151		if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
152		    &extracted_ether_type) == 0) {
153			/* ether_type not known, print raw packet */
154			if (!eflag)
155				ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN);
156
157			if (!xflag && !qflag)
158				default_print(p, caplen);
159		}
160	} else if (ether_encap_print(ether_type, p, length, caplen,
161	    &extracted_ether_type) == 0) {
162		/* ether_type not known, print raw packet */
163		if (!eflag)
164			ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN);
165
166		if (!xflag && !qflag)
167			default_print(p, caplen);
168	}
169}
170
171/*
172 * This is the top level routine of the printer.  'p' points
173 * to the ether header of the packet, 'h->ts' is the timestamp,
174 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
175 * is the number of bytes actually captured.
176 */
177u_int
178ether_if_print(const struct pcap_pkthdr *h, const u_char *p)
179{
180	ether_print(p, h->len, h->caplen);
181
182	return (ETHER_HDRLEN);
183}
184
185/*
186 * Prints the packet encapsulated in an Ethernet data segment
187 * (or an equivalent encapsulation), given the Ethernet type code.
188 *
189 * Returns non-zero if it can do so, zero if the ethertype is unknown.
190 *
191 * The Ethernet type code is passed through a pointer; if it was
192 * ETHERTYPE_8021Q, it gets updated to be the Ethernet type of
193 * the 802.1Q payload, for the benefit of lower layers that might
194 * want to know what it is.
195 */
196
197int
198ether_encap_print(u_short ether_type, const u_char *p,
199    u_int length, u_int caplen, u_short *extracted_ether_type)
200{
201 recurse:
202	*extracted_ether_type = ether_type;
203
204	switch (ether_type) {
205
206	case ETHERTYPE_IP:
207	        ip_print(gndo, p, length);
208		return (1);
209
210#ifdef INET6
211	case ETHERTYPE_IPV6:
212		ip6_print(p, length);
213		return (1);
214#endif /*INET6*/
215
216	case ETHERTYPE_ARP:
217	case ETHERTYPE_REVARP:
218  	        arp_print(gndo, p, length, caplen);
219		return (1);
220
221	case ETHERTYPE_DN:
222		decnet_print(p, length, caplen);
223		return (1);
224
225	case ETHERTYPE_ATALK:
226		if (vflag)
227			fputs("et1 ", stdout);
228		atalk_print(p, length);
229		return (1);
230
231	case ETHERTYPE_AARP:
232		aarp_print(p, length);
233		return (1);
234
235	case ETHERTYPE_IPX:
236		printf("(NOV-ETHII) ");
237		ipx_print(p, length);
238		return (1);
239
240	case ETHERTYPE_8021Q:
241	        if (eflag)
242		    printf("vlan %u, p %u%s, ",
243			   ntohs(*(u_int16_t *)p) & 0xfff,
244			   ntohs(*(u_int16_t *)p) >> 13,
245			   (ntohs(*(u_int16_t *)p) & 0x1000) ? ", CFI" : "");
246
247		ether_type = ntohs(*(u_int16_t *)(p + 2));
248		p += 4;
249		length -= 4;
250		caplen -= 4;
251
252		if (ether_type > ETHERMTU) {
253		        if (eflag)
254			        printf("ethertype %s, ",
255				       tok2str(ethertype_values,"0x%04x", ether_type));
256			goto recurse;
257		}
258
259		*extracted_ether_type = 0;
260
261		if (llc_print(p, length, caplen, p - 18, p - 12,
262		    extracted_ether_type) == 0) {
263				ether_hdr_print(p - 18, length + 4);
264		}
265
266		if (!xflag && !qflag)
267		        default_print(p - 18, caplen + 4);
268
269		return (1);
270
271        case ETHERTYPE_JUMBO:
272                ether_type = ntohs(*(u_int16_t *)(p));
273                p += 2;
274                length -= 2;
275                caplen -= 2;
276
277                if (ether_type > ETHERMTU) {
278                    if (eflag)
279                        printf("ethertype %s, ",
280                               tok2str(ethertype_values,"0x%04x", ether_type));
281                    goto recurse;
282                }
283
284                *extracted_ether_type = 0;
285
286                if (llc_print(p, length, caplen, p - 16, p - 10,
287                              extracted_ether_type) == 0) {
288                    ether_hdr_print(p - 16, length + 2);
289                }
290
291                if (!xflag && !qflag)
292                    default_print(p - 16, caplen + 2);
293
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_PPP:
312		if (length) {
313			printf(": ");
314			ppp_print(p, length);
315		}
316		return (1);
317
318        case ETHERTYPE_LOOPBACK:
319                return (0);
320
321	case ETHERTYPE_MPLS:
322	case ETHERTYPE_MPLS_MULTI:
323		mpls_print(p, length);
324		return (1);
325
326	case ETHERTYPE_LAT:
327	case ETHERTYPE_SCA:
328	case ETHERTYPE_MOPRC:
329	case ETHERTYPE_MOPDL:
330		/* default_print for now */
331	default:
332		return (0);
333	}
334}
335
336
337/*
338 * Local Variables:
339 * c-style: whitesmith
340 * c-basic-offset: 8
341 * End:
342 */
343
344