source: rtems-libbsd/freebsd/contrib/tcpdump/print-ether.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

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