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