From: guy Date: Sun, 7 Apr 2002 09:50:30 +0000 (+0000) Subject: Support RFC 2684 bridging of Ethernet, 802.5 Token Ring, and FDDI, and X-Git-Tag: tcpdump-3.8-bp~522 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/a57421867fff43381f2ca80c43bb0be3037c562e Support RFC 2684 bridging of Ethernet, 802.5 Token Ring, and FDDI, and RFC 2684 encapsulation of BPDUs. --- diff --git a/interface.h b/interface.h index 94ece1a9..033debe0 100644 --- a/interface.h +++ b/interface.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.179 2002-02-05 10:07:39 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.180 2002-04-07 09:50:30 guy Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -208,10 +208,13 @@ extern void pflog_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); extern void arcnet_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); +extern void ether_print(const u_char *, u_int, u_int); extern void ether_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); +extern void token_print(const u_char *, u_int, u_int); extern void token_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); +extern void fddi_print(const u_char *, u_int, u_int); extern void fddi_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); extern void ieee802_11_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); diff --git a/llc.h b/llc.h index 768858f7..503c9014 100644 --- a/llc.h +++ b/llc.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/llc.h,v 1.13 2001-06-04 05:47:13 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/llc.h,v 1.14 2002-04-07 09:50:30 guy Exp $ (LBL) */ /* @@ -127,6 +127,27 @@ struct llc { #define OUI_ENCAP_ETHER 0x000000 /* encapsulated Ethernet */ #define OUI_CISCO 0x00000c /* Cisco protocols */ -#define ETHERTYPE_CISCO_CDP 0x2000 /* Cisco Discovery Protocol */ #define OUI_CISCO_90 0x0000f8 /* Cisco bridging */ +#define OUI_RFC2684 0x0080c2 /* RFC 2684 bridged Ethernet */ #define OUI_APPLETALK 0x080007 /* Appletalk */ + +/* + * PIDs for use with OUI_CISCO. + */ +#define PID_CISCO_CDP 0x2000 /* Cisco Discovery Protocol */ + +/* + * PIDs for use with OUI_RFC2684. + */ +#define PID_RFC2684_ETH_FCS 0x0001 /* Ethernet, with FCS */ +#define PID_RFC2684_ETH_NOFCS 0x0007 /* Ethernet, without FCS */ +#define PID_RFC2684_802_4_FCS 0x0002 /* 802.4, with FCS */ +#define PID_RFC2684_802_4_NOFCS 0x0008 /* 802.4, without FCS */ +#define PID_RFC2684_802_5_FCS 0x0003 /* 802.5, with FCS */ +#define PID_RFC2684_802_5_NOFCS 0x0009 /* 802.5, without FCS */ +#define PID_RFC2684_FDDI_FCS 0x0004 /* FDDI, with FCS */ +#define PID_RFC2684_FDDI_NOFCS 0x000a /* FDDI, without FCS */ +#define PID_RFC2684_802_6_FCS 0x0005 /* 802.6, with FCS */ +#define PID_RFC2684_802_6_NOFCS 0x000b /* 802.6, without FCS */ +#define PID_RFC2684_BPDU 0x000e /* BPDUs */ + diff --git a/print-ether.c b/print-ether.c index 0bcd82d5..a28f6652 100644 --- a/print-ether.c +++ b/print-ether.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.66 2001-11-25 02:01:47 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.67 2002-04-07 09:50:31 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -49,7 +49,7 @@ const u_char *packetp; const u_char *snapend; static inline void -ether_print(register const u_char *bp, u_int length) +ether_hdr_print(register const u_char *bp, u_int length) { register const struct ether_header *ep; @@ -67,31 +67,20 @@ ether_print(register const u_char *bp, u_int length) length); } -/* - * This is the top level routine of the printer. 'p' is the points - * to the ether header of the packet, 'h->tv' is the timestamp, - * 'h->length' is the length of the packet off the wire, and 'h->caplen' - * is the number of bytes actually captured. - */ void -ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +ether_print(const u_char *p, u_int length, u_int caplen) { - u_int caplen = h->caplen; - u_int length = h->len; struct ether_header *ep; u_short ether_type; u_short extracted_ethertype; - ++infodelay; - ts_print(&h->ts); - if (caplen < ETHER_HDRLEN) { printf("[|ether]"); goto out; } if (eflag) - ether_print(p, length); + ether_hdr_print(p, length); /* * Some printers want to get back at the ethernet addresses, @@ -118,7 +107,7 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) &extracted_ethertype) == 0) { /* ether_type not known, print raw packet */ if (!eflag) - ether_print((u_char *)ep, length + ETHER_HDRLEN); + ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); if (extracted_ethertype) { printf("(LLC %s) ", etherproto_string(htons(extracted_ethertype))); @@ -130,7 +119,7 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) &extracted_ethertype) == 0) { /* ether_type not known, print raw packet */ if (!eflag) - ether_print((u_char *)ep, length + ETHER_HDRLEN); + ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); if (!xflag && !qflag) default_print(p, caplen); } @@ -138,6 +127,25 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) default_print(p, caplen); out: putchar('\n'); +} + +/* + * This is the top level routine of the printer. 'p' is the points + * to the ether header of the packet, 'h->tv' is the timestamp, + * 'h->length' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +void +ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + + ++infodelay; + ts_print(&h->ts); + + ether_print(p, length, caplen); + --infodelay; if (infoprint) info(0); @@ -216,7 +224,7 @@ ether_encap_print(u_short ethertype, const u_char *p, extracted_ethertype) == 0) { /* ether_type not known, print raw packet */ if (!eflag) - ether_print(p - 18, length + 4); + ether_hdr_print(p - 18, length + 4); if (*extracted_ethertype) { printf("(LLC %s) ", etherproto_string(htons(*extracted_ethertype))); diff --git a/print-fddi.c b/print-fddi.c index 71cdb309..bf090d7c 100644 --- a/print-fddi.c +++ b/print-fddi.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.53 2001-11-14 16:46:34 fenner Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.54 2002-04-07 09:50:32 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -219,7 +219,7 @@ extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst) * Print the FDDI MAC header */ static inline void -fddi_print(register const struct fddi_header *fddip, register u_int length, +fddi_hdr_print(register const struct fddi_header *fddip, register u_int length, register const u_char *fsrc, register const u_char *fdst) { const char *srcname, *dstname; @@ -246,25 +246,13 @@ fddi_smt_print(const u_char *p, u_int length) printf(""); } -/* - * This is the top level routine of the printer. 'sp' is the points - * to the FDDI header of the packet, 'tvp' is the timestamp, - * 'length' is the length of the packet off the wire, and 'caplen' - * is the number of bytes actually captured. - */ void -fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, - register const u_char *p) +fddi_print(const u_char *p, u_int length, u_int caplen) { - u_int caplen = h->caplen; - u_int length = h->len; const struct fddi_header *fddip = (const struct fddi_header *)p; struct ether_header ehdr; u_short extracted_ethertype; - ++infodelay; - ts_print(&h->ts); - if (caplen < FDDI_HDRLEN) { printf("[|fddi]"); goto out; @@ -288,7 +276,7 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, packetp = (u_char *)&ehdr; if (eflag) - fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); + fddi_hdr_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); /* Skip over FDDI MAC header */ length -= FDDI_HDRLEN; @@ -306,7 +294,7 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, * handle intelligently */ if (!eflag) - fddi_print(fddip, length + FDDI_HDRLEN, + fddi_hdr_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), EDST(&ehdr)); if (extracted_ethertype) { printf("(LLC %s) ", @@ -320,7 +308,7 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, else { /* Some kinds of FDDI packet we cannot handle intelligently */ if (!eflag) - fddi_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), + fddi_hdr_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), EDST(&ehdr)); if (!xflag && !qflag) default_print(p, caplen); @@ -329,6 +317,26 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, default_print(p, caplen); out: putchar('\n'); +} + +/* + * This is the top level routine of the printer. 'sp' is the points + * to the FDDI header of the packet, 'tvp' is the timestamp, + * 'length' is the length of the packet off the wire, and 'caplen' + * is the number of bytes actually captured. + */ +void +fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, + register const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + + ++infodelay; + ts_print(&h->ts); + + fddi_print(p, length, caplen); + --infodelay; if (infoprint) info(0); diff --git a/print-llc.c b/print-llc.c index da8a5132..d36dd570 100644 --- a/print-llc.c +++ b/print-llc.c @@ -24,7 +24,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.44 2001-11-25 02:01:48 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.45 2002-04-07 09:50:33 guy Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -226,11 +226,78 @@ llc_print(const u_char *p, u_int length, u_int caplen, break; case OUI_CISCO: - if (et == ETHERTYPE_CISCO_CDP) { + if (et == PID_CISCO_CDP) { cdp_print(p, length, caplen, esrc, edst); return 1; } break; + + case OUI_RFC2684: + switch (et) { + + case PID_RFC2684_ETH_FCS: + case PID_RFC2684_ETH_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + caplen -= 2; + length -= 2; + p += 2; + + /* + * What remains is an Ethernet packet. + */ + ether_print(p, length, caplen); + return (1); + + case PID_RFC2684_802_5_FCS: + case PID_RFC2684_802_5_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding, but not the Access + * Control field. + */ + caplen -= 2; + length -= 2; + p += 2; + + /* + * What remains is an 802.5 Token Ring + * packet. + */ + token_print(p, length, caplen); + return (1); + + case PID_RFC2684_FDDI_FCS: + case PID_RFC2684_FDDI_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + caplen -= 3; + length -= 3; + p += 3; + + /* + * What remains is an FDDI packet. + */ + fddi_print(p, length, caplen); + return (1); + + case PID_RFC2684_BPDU: + stp_print(p, length); + return (1); + } } } diff --git a/print-token.c b/print-token.c index 0d0b23a6..0f4afedb 100644 --- a/print-token.c +++ b/print-token.c @@ -25,7 +25,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.13 2001-09-18 15:46:37 fenner Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.14 2002-04-07 09:50:33 guy Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -61,7 +61,7 @@ extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) * Print the TR MAC header */ static inline void -token_print(register const struct token_header *trp, register u_int length, +token_hdr_print(register const struct token_header *trp, register u_int length, register const u_char *fsrc, register const u_char *fdst) { const char *srcname, *dstname; @@ -101,17 +101,9 @@ static const char *largest_frame[] = { "??" }; -/* - * This is the top level routine of the printer. 'p' is the points - * to the TR header of the packet, 'tvp' is the timestamp, - * 'length' is the length of the packet off the wire, and 'caplen' - * is the number of bytes actually captured. - */ void -token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +token_print(const u_char *p, u_int length, u_int caplen) { - u_int caplen = h->caplen; - u_int length = h->len; const struct token_header *trp; u_short extracted_ethertype; struct ether_header ehdr; @@ -119,9 +111,6 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) trp = (const struct token_header *)p; - ++infodelay; - ts_print(&h->ts); - if (caplen < TOKEN_HDRLEN) { printf("[|token-ring]"); goto out; @@ -150,7 +139,7 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) *ESRC(&ehdr) &= 0x7f; if (eflag) - token_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); route_len = RIF_LENGTH(trp); if (vflag) { @@ -169,7 +158,7 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); } else { if (eflag) - token_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); } /* Skip over token ring MAC header and routing information */ @@ -185,7 +174,7 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) &extracted_ethertype) == 0) { /* ether_type not known, print raw packet */ if (!eflag) - token_print(trp, + token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, ESRC(&ehdr), EDST(&ehdr)); if (extracted_ethertype) { @@ -199,7 +188,7 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) /* Some kinds of TR packet we cannot handle intelligently */ /* XXX - dissect MAC packets if frame type is 0 */ if (!eflag) - token_print(trp, length + TOKEN_HDRLEN + route_len, + token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, ESRC(&ehdr), EDST(&ehdr)); if (!xflag && !qflag) default_print(p, caplen); @@ -208,6 +197,25 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) default_print(p, caplen); out: putchar('\n'); +} + +/* + * This is the top level routine of the printer. 'p' is the points + * to the TR header of the packet, 'tvp' is the timestamp, + * 'length' is the length of the packet off the wire, and 'caplen' + * is the number of bytes actually captured. + */ +void +token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + + ++infodelay; + ts_print(&h->ts); + + token_print(p, length, caplen); + --infodelay; if (infoprint) info(0);