]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Support RFC 2684 bridging of Ethernet, 802.5 Token Ring, and FDDI, and
authorguy <guy>
Sun, 7 Apr 2002 09:50:30 +0000 (09:50 +0000)
committerguy <guy>
Sun, 7 Apr 2002 09:50:30 +0000 (09:50 +0000)
RFC 2684 encapsulation of BPDUs.

interface.h
llc.h
print-ether.c
print-fddi.c
print-llc.c
print-token.c

index 94ece1a93333cdd95ffb7bee87bf663bed9730b6..033debe0ee96cbb8e98853dc481d090125cc51b6 100644 (file)
@@ -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 768858f75bf707ec451fc82102b164f8028ac0fd..503c9014fc940ce445de47aa30070a5b8b7da790 100644 (file)
--- 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 */
+
index 0bcd82d5f8ae77a1ddf154de3c7337c43bd137dc..a28f6652c6ae08492c76100e85df7b852612490e 100644 (file)
@@ -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)));
index 71cdb3098f0391023ad0bf1a84c57aeb1e37da02..bf090d7ce97a4c225649790309c26dd8c42f9577 100644 (file)
@@ -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("<SMT printer not yet implemented>");
 }
 
-/*
- * 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);
index da8a51324d596cc70a30058407b78e082fa044fd..d36dd570b04e5e0ea116c6b5e9b53802ecdfe81b 100644 (file)
@@ -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);
+                       }
                }
        }
 
index 0d0b23a67c9fbaaf57d703de5a0f116773e1a169..0f4afedbd1725f93c5d99bb15a9801d831339b63 100644 (file)
@@ -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);