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