]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Skip the LLC and SNAP headers with -x.
authorGuy Harris <[email protected]>
Sat, 18 Apr 2015 06:42:22 +0000 (23:42 -0700)
committerGuy Harris <[email protected]>
Sat, 18 Apr 2015 06:42:22 +0000 (23:42 -0700)
Have llc_print() return the length of the LLC header, plus the length of
the SNAP header, if available - or, if it couldn't dissect the payload,
return the *negative* of that sum.  Use that return value in link-layer
printers.

netdissect.h
print-802_11.c
print-atm.c
print-cip.c
print-ether.c
print-fddi.c
print-ipfc.c
print-juniper.c
print-llc.c
print-sll.c
print-token.c

index 7cdd53474fb3fa4cf62170aef9b7f302e98c0251..f4de98cd2726f32ed3355d94151151eb97fa6f5f 100644 (file)
@@ -387,10 +387,10 @@ extern void rrcp_print(netdissect_options *,const u_char *, u_int);
 extern void loopback_print(netdissect_options *, const u_char *, const u_int);
 extern void carp_print(netdissect_options *, const u_char *, u_int, int);
 
-extern void ether_print(netdissect_options *,
-                        const u_char *, u_int, u_int,
-                        void (*)(netdissect_options *, const u_char *),
-                        const u_char *);
+extern u_int ether_print(netdissect_options *,
+                         const u_char *, u_int, u_int,
+                         void (*)(netdissect_options *, const u_char *),
+                         const u_char *);
 
 extern u_int ether_if_print(netdissect_options *,
                             const struct pcap_pkthdr *,const u_char *);
@@ -454,7 +454,7 @@ extern u_int token_print(netdissect_options *, const u_char *, u_int, u_int);
 extern u_int token_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *);
 extern void vqp_print(netdissect_options *, register const u_char *, register u_int);
 extern void zephyr_print(netdissect_options *, const u_char *, int);
-extern void fddi_print(netdissect_options *, const u_char *, u_int, u_int);
+extern u_int fddi_print(netdissect_options *, const u_char *, u_int, u_int);
 extern u_int fddi_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *);
 extern void mpcp_print(netdissect_options *, const u_char *, u_int);
 extern void rpki_rtr_print(netdissect_options *, const u_char *, u_int);
index 2c9f2a38be41648eb7834cb4ac5fa6376fb1f51e..2b4463ec07ac6fbf5bfde74a5af3d1792ed632e7 100644 (file)
@@ -2332,6 +2332,7 @@ ieee802_11_print(netdissect_options *ndo,
        uint16_t fc;
        u_int caplen, hdrlen, meshdrlen;
        const uint8_t *src, *dst;
+       int llc_hdrlen;
 
        caplen = orig_caplen;
        /* Remove FCS, if present */
@@ -2408,14 +2409,17 @@ ieee802_11_print(netdissect_options *ndo,
                        }
                } else {
                        get_data_src_dst_mac(fc, p - hdrlen, &src, &dst);
-                       if (llc_print(ndo, p, length, caplen, dst, src) == 0) {
+                       llc_hdrlen = llc_print(ndo, p, length, caplen, dst, src);
+                       if (llc_hdrlen < 0) {
                                /*
                                 * Some kinds of LLC packet we cannot
                                 * handle intelligently
                                 */
                                if (!ndo->ndo_suppress_default_print)
                                        ND_DEFAULTPRINT(p, caplen);
+                               llc_hdrlen = -llc_hdrlen;
                        }
+                       hdrlen += llc_hdrlen;
                }
                break;
        default:
index 82a012ba03139ac35224a06169b9da88bc1bdc5a..d2f18f7a3ae9bd52178408d7f8944b1163a666bc 100644 (file)
@@ -214,15 +214,20 @@ static const struct tok *oam_functype_values[16] = {
 /*
  * Print an RFC 1483 LLC-encapsulated ATM frame.
  */
-static void
+static u_int
 atm_llc_print(netdissect_options *ndo,
               const u_char *p, int length, int caplen)
 {
-       if (!llc_print(ndo, p, length, caplen, NULL, NULL)) {
-               /* ether_type not known, print raw packet */
+       int llc_hdrlen;
+
+       llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
+       if (llc_hdrlen < 0) {
+               /* packet not known, print raw packet */
                if (!ndo->ndo_suppress_default_print)
                        ND_DEFAULTPRINT(p, caplen);
+               llc_hdrlen = -llc_hdrlen;
        }
+       return (llc_hdrlen);
 }
 
 /*
@@ -310,7 +315,7 @@ atm_if_print(netdissect_options *ndo,
                caplen -= 20;
                hdrlen += 20;
        }
-       atm_llc_print(ndo, p, length, caplen);
+       hdrlen += atm_llc_print(ndo, p, length, caplen);
        return (hdrlen);
 }
 
index 23f6178808d5d38e6d57bba58bd4984371cd4777..fde5ab44512f59170a0d082da70413ed03a7096d 100644 (file)
@@ -61,6 +61,7 @@ cip_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
 {
        u_int caplen = h->caplen;
        u_int length = h->len;
+       int llc_hdrlen;
 
        if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
                ND_PRINT((ndo, "[|cip]"));
@@ -74,18 +75,22 @@ cip_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
                /*
                 * LLC header is present.  Try to print it & higher layers.
                 */
-               if (llc_print(ndo, p, length, caplen, NULL, NULL) == 0) {
+               llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
+               if (llc_hdrlen < 0) {
+                       /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
                                ND_DEFAULTPRINT(p, caplen);
+                       llc_hdrlen = -llc_hdrlen;
                }
        } else {
                /*
                 * LLC header is absent; treat it as just IP.
                 */
+               llc_hdrlen = 0;
                ip_print(ndo, p, length);
        }
 
-       return (0);
+       return (llc_hdrlen);
 }
 
 
index 26c5c97c9c3005dddb83e6299e22c6e4329e603f..f4906260baad56d9cc82f9555f42b7b44e7abb48 100644 (file)
@@ -122,7 +122,7 @@ ether_hdr_print(netdissect_options *ndo,
  * a pointer to a function that can print header information for that
  * frame's protocol, and an argument to pass to that function.
  */
-void
+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)
@@ -130,10 +130,16 @@ ether_print(netdissect_options *ndo,
        struct ether_header *ep;
        u_int orig_length;
        u_short ether_type;
+       u_int hdrlen;
+       int llc_hdrlen;
 
-       if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) {
+       if (caplen < ETHER_HDRLEN) {
+               ND_PRINT((ndo, "[|ether]"));
+               return (caplen);
+       }
+       if (length < ETHER_HDRLEN) {
                ND_PRINT((ndo, "[|ether]"));
-               return;
+               return (length);
        }
 
        if (ndo->ndo_eflag) {
@@ -147,6 +153,7 @@ ether_print(netdissect_options *ndo,
        caplen -= ETHER_HDRLEN;
        ep = (struct ether_header *)p;
        p += ETHER_HDRLEN;
+       hdrlen = ETHER_HDRLEN;
 
        ether_type = EXTRACT_16BITS(&ep->ether_type);
 
@@ -156,11 +163,14 @@ recurse:
         */
        if (ether_type <= ETHERMTU) {
                /* Try to print the LLC-layer header & higher layers */
-               if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep)) == 0) {
-                       /* ether_type not known, print raw packet */
+               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep));
+               if (llc_hdrlen < 0) {
+                       /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
                                ND_DEFAULTPRINT(p, caplen);
+                       llc_hdrlen = -llc_hdrlen;
                }
+               hdrlen += llc_hdrlen;
        } else if (ether_type == ETHERTYPE_8021Q  ||
                 ether_type == ETHERTYPE_8021Q9100 ||
                 ether_type == ETHERTYPE_8021Q9200 ||
@@ -169,9 +179,13 @@ recurse:
                 * Print VLAN information, and then go back and process
                 * the enclosed type field.
                 */
-               if (caplen < 4 || length < 4) {
+               if (caplen < 4) {
+                       ND_PRINT((ndo, "[|vlan]"));
+                       return (hdrlen + caplen);
+               }
+               if (length < 4) {
                        ND_PRINT((ndo, "[|vlan]"));
-                       return;
+                       return (hdrlen + length);
                }
                if (ndo->ndo_eflag) {
                        uint16_t tag = EXTRACT_16BITS(p);
@@ -185,6 +199,7 @@ recurse:
                p += 4;
                length -= 4;
                caplen -= 4;
+               hdrlen += 4;
                goto recurse;
        } else if (ether_type == ETHERTYPE_JUMBO) {
                /*
@@ -197,11 +212,14 @@ recurse:
                 * there's an LLC header and payload.
                 */
                /* Try to print the LLC-layer header & higher layers */
-               if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep)) == 0) {
-                       /* ether_type not known, print raw packet */
+               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep));
+               if (llc_hdrlen < 0) {
+                       /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
                                ND_DEFAULTPRINT(p, caplen);
+                       llc_hdrlen = -llc_hdrlen;
                }
+               hdrlen += llc_hdrlen;
        } else {
                if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
                        /* ether_type not known, print raw packet */
@@ -215,6 +233,7 @@ recurse:
                                ND_DEFAULTPRINT(p, caplen);
                }
        }
+       return (hdrlen);
 }
 
 /*
@@ -227,9 +246,7 @@ u_int
 ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
                const u_char *p)
 {
-       ether_print(ndo, p, h->len, h->caplen, NULL, NULL);
-
-       return (ETHER_HDRLEN);
+       return (ether_print(ndo, p, h->len, h->caplen, NULL, NULL));
 }
 
 /*
@@ -254,9 +271,7 @@ netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
        }
 
        /* Skip the pseudo-header. */
-       ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL);
-
-       return (4 + ETHER_HDRLEN);
+       return (4 + ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL));
 }
 
 /*
@@ -284,9 +299,7 @@ netanalyzer_transparent_if_print(netdissect_options *ndo,
        }
 
        /* Skip the pseudo-header, preamble, and SOF. */
-       ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL);
-
-       return (12 + ETHER_HDRLEN);
+       return (12 + ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL));
 }
 
 /*
index 9e6ec0b1024226213ca8e729ff66a9511093be73..7576b6f0d4f679ea46d7573311405e6ba0990717 100644 (file)
@@ -277,15 +277,16 @@ fddi_smt_print(netdissect_options *ndo, const u_char *p _U_, u_int length _U_)
        ND_PRINT((ndo, "<SMT printer not yet implemented>"));
 }
 
-void
+u_int
 fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
 {
        const struct fddi_header *fddip = (const struct fddi_header *)p;
        struct ether_header ehdr;
+       int llc_hdrlen;
 
        if (caplen < FDDI_HDRLEN) {
                ND_PRINT((ndo, "[|fddi]"));
-               return;
+               return (caplen);
        }
 
        /*
@@ -304,24 +305,29 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
        /* Frame Control field determines interpretation of packet */
        if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
                /* Try to print the LLC-layer header & higher layers */
-               if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr)) == 0) {
+               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr));
+               if (llc_hdrlen < 0) {
                        /*
                         * Some kinds of LLC packet we cannot
                         * handle intelligently
                         */
                        if (!ndo->ndo_suppress_default_print)
                                ND_DEFAULTPRINT(p, caplen);
+                       llc_hdrlen = -llc_hdrlen;
                }
-       } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT)
+       } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT) {
                fddi_smt_print(ndo, p, caplen);
-       else {
+               llc_hdrlen = 0;
+       } else {
                /* Some kinds of FDDI packet we cannot handle intelligently */
                if (!ndo->ndo_eflag)
                        fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN, ESRC(&ehdr),
                            EDST(&ehdr));
                if (!ndo->ndo_suppress_default_print)
                        ND_DEFAULTPRINT(p, caplen);
+               llc_hdrlen = 0;
        }
+       return (FDDI_HDRLEN + llc_hdrlen);
 }
 
 /*
@@ -333,7 +339,5 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
 u_int
 fddi_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
 {
-       fddi_print(ndo, p, h->len, h->caplen);
-
-       return (FDDI_HDRLEN);
+       return (fddi_print(ndo, p, h->len, h->caplen));
 }
index b2869eb81318f6ceb73dc81ee9893c351f33981f..6d07f80edfe21cb08ba75eab9390295347b51579 100644 (file)
@@ -76,15 +76,16 @@ ipfc_hdr_print(netdissect_options *ndo,
        ND_PRINT((ndo, "%s %s %d: ", srcname, dstname, length));
 }
 
-static void
+static u_int
 ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
 {
        const struct ipfc_header *ipfcp = (const struct ipfc_header *)p;
        struct ether_header ehdr;
+       int llc_hdrlen;
 
        if (caplen < IPFC_HDRLEN) {
                ND_PRINT((ndo, "[|ipfc]"));
-               return;
+               return (caplen);
        }
        /*
         * Get the network addresses into a canonical form
@@ -100,14 +101,17 @@ ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
        caplen -= IPFC_HDRLEN;
 
        /* Try to print the LLC-layer header & higher layers */
-       if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr)) == 0) {
+       llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr));
+       if (llc_hdrlen < 0) {
                /*
                 * Some kinds of LLC packet we cannot
                 * handle intelligently
                 */
                if (!ndo->ndo_suppress_default_print)
                        ND_DEFAULTPRINT(p, caplen);
+               llc_hdrlen = -llc_hdrlen;
        }
+       return (IPFC_HDRLEN + llc_hdrlen);
 }
 
 /*
@@ -119,7 +123,5 @@ ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
 u_int
 ipfc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
 {
-       ipfc_print(ndo, p, h->len, h->caplen);
-
-       return (IPFC_HDRLEN);
+       return (ipfc_print(ndo, p, h->len, h->caplen));
 }
index 8fc8eee294b51bd59a0f3dc67759adc62785f991..6ae5b6d8d19619a6bdbe5497d60a8f315e5caf5c 100644 (file)
@@ -919,6 +919,8 @@ u_int
 juniper_atm1_print(netdissect_options *ndo,
                    const struct pcap_pkthdr *h, register const u_char *p)
 {
+        int llc_hdrlen;
+
         struct juniper_l2info_t l2info;
 
         l2info.pictype = DLT_JUNIPER_ATM1;
@@ -935,7 +937,8 @@ juniper_atm1_print(netdissect_options *ndo,
         if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
             EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
 
-            if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL) != 0)
+            llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
+            if (llc_hdrlen > 0)
                 return l2info.header_len;
         }
 
@@ -965,6 +968,8 @@ u_int
 juniper_atm2_print(netdissect_options *ndo,
                    const struct pcap_pkthdr *h, register const u_char *p)
 {
+        int llc_hdrlen;
+
         struct juniper_l2info_t l2info;
 
         l2info.pictype = DLT_JUNIPER_ATM2;
@@ -981,7 +986,8 @@ juniper_atm2_print(netdissect_options *ndo,
         if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
             EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
 
-            if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL) != 0)
+            llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
+            if (llc_hdrlen > 0)
                 return l2info.header_len;
         }
 
index 65c08c08ccd41573c71408c9d84c7118e6728b1e..0132bdaa6b9ccecc7d0390a29c69abc6051bd7e4 100644 (file)
@@ -137,9 +137,12 @@ static const struct oui_tok oui_to_tok[] = {
 };
 
 /*
- * Returns zero if we have a payload but haven't printed it (for example,
- * because it has unknown SAPs or has a SNAP header with an unknown OUI/
- * PID combination).
+ * If we printed information about the payload, returns the length of the LLC
+ * header, plus the length of any SNAP header following it.
+ *
+ * Otherwise (for example, if the packet has unknown SAPs or has a SNAP
+ * header with an unknown OUI/PID combination), returns the *negative*
+ * of that value.
  */
 int
 llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
@@ -147,12 +150,18 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
 {
        uint8_t dsap_field, dsap, ssap_field, ssap;
        uint16_t control;
+       u_int hdrlen;
        int is_u;
 
-       if (caplen < 3 || length < 3) {
+       if (caplen < 3) {
+               ND_PRINT((ndo, "[|llc]"));
+               ND_DEFAULTPRINT((u_char *)p, caplen);
+               return (caplen);
+       }
+       if (length < 3) {
                ND_PRINT((ndo, "[|llc]"));
                ND_DEFAULTPRINT((u_char *)p, caplen);
-               return (1);
+               return (length);
        }
 
        dsap_field = *p;
@@ -170,15 +179,21 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 * U frame.
                 */
                is_u = 1;
+               hdrlen = 3;     /* DSAP, SSAP, 1-byte control field */
        } else {
                /*
                 * The control field in I and S frames is
                 * 2 bytes...
                 */
-               if (caplen < 4 || length < 4) {
+               if (caplen < 4) {
                        ND_PRINT((ndo, "[|llc]"));
                        ND_DEFAULTPRINT((u_char *)p, caplen);
-                       return (1);
+                       return (caplen);
+               }
+               if (length < 4) {
+                       ND_PRINT((ndo, "[|llc]"));
+                       ND_DEFAULTPRINT((u_char *)p, caplen);
+                       return (length);
                }
 
                /*
@@ -186,6 +201,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 */
                control = EXTRACT_LE_16BITS(p + 2);
                is_u = 0;
+               hdrlen = 4;     /* DSAP, SSAP, 2-byte control field */
        }
 
        if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) {
@@ -208,12 +224,19 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                ND_PRINT((ndo, "IPX 802.3: "));
 
             ipx_print(ndo, p, length);
-            return (1);
+            return (0);                /* no LLC header */
        }
 
        dsap = dsap_field & ~LLC_IG;
        ssap = ssap_field & ~LLC_GSAP;
 
+       /*
+        * Skip LLC header.
+        */
+       p += hdrlen;
+       length -= hdrlen;
+       caplen -= hdrlen;
+
        /*
         * Check for SNAP UI packets; if we have one, there's no point
         * in printing the LLC header information, as we already know it -
@@ -228,7 +251,15 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 * Does anybody ever bridge one form of LAN traffic
                 * over a networking type that uses 802.2 LLC?
                 */
-               return (snap_print(ndo, p+3, length-3, caplen-3, esrc, edst, 2));
+               if (!snap_print(ndo, p, length, caplen, esrc, edst, 2)) {
+                       /*
+                        * Unknown packet type; tell our caller, by
+                        * returning a negative value, so they
+                        * can print the raw packet.
+                        */
+                       return (-(hdrlen + 5)); /* include LLC and SNAP header */
+               } else
+                       return (hdrlen + 5);    /* include LLC and SNAP header */
        }
 
        if (ndo->ndo_eflag) {
@@ -249,8 +280,8 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
 
        if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D &&
            control == LLC_UI) {
-               stp_print(ndo, p+3, length-3);
-               return (1);
+               stp_print(ndo, p, length);
+               return (hdrlen);
        }
 
        if (ssap == LLCSAP_IP && dsap == LLCSAP_IP &&
@@ -261,8 +292,8 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 * with the source and destination SAPs being
                 * the IP SAP.
                 */
-               ip_print(ndo, p+3, length-3);
-               return (1);
+               ip_print(ndo, p, length);
+               return (hdrlen);
        }
 
        if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX &&
@@ -271,14 +302,12 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 * This is an Ethernet_802.2 IPX frame, with an 802.3
                 * header and an 802.2 LLC header with the source and
                 * destination SAPs being the IPX SAP.
-                *
-                * Skip DSAP, LSAP, and control field.
                 */
                 if (ndo->ndo_eflag)
                         ND_PRINT((ndo, "IPX 802.2: "));
 
-               ipx_print(ndo, p+3, length-3);
-               return (1);
+               ipx_print(ndo, p, length);
+               return (hdrlen);
        }
 
 #ifdef TCPDUMP_DO_SMB
@@ -294,25 +323,14 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 * LLC_S_FMT, set in the first byte of the control field)
                 * and UI frames (whose control field is just 3, LLC_U_FMT).
                 */
-
-               /*
-                * Skip the LLC header.
-                */
-               if (is_u) {
-                       p += 3;
-                       length -= 3;
-               } else {
-                       p += 4;
-                       length -= 4;
-               }
                netbeui_print(ndo, control, p, length);
-               return (1);
+               return (hdrlen);
        }
 #endif
        if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
            && control == LLC_UI) {
-               isoclns_print(ndo, p + 3, length - 3, caplen - 3);
-               return (1);
+               isoclns_print(ndo, p, length, caplen);
+               return (hdrlen);
        }
 
        if (!ndo->ndo_eflag) {
@@ -342,14 +360,12 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                ND_PRINT((ndo, "Unnumbered, %s, Flags [%s], length %u",
                        tok2str(llc_cmd_values, "%02x", LLC_U_CMD(control)),
                        tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_U_POLL)),
-                       length));
-
-               p += 3;
+                       length + hdrlen));
 
                if ((control & ~LLC_U_POLL) == LLC_XID) {
                        if (*p == LLC_XID_FI) {
                                ND_PRINT((ndo, ": %02x %02x", p[1], p[2]));
-                               return (1);
+                               return (hdrlen);
                        }
                }
        } else {
@@ -358,17 +374,17 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                                tok2str(llc_supervisory_values,"?",LLC_S_CMD(control)),
                                LLC_IS_NR(control),
                                tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)),
-                                length));
-                       return (1);     /* no payload to print */
+                                length + hdrlen));
+                       return (hdrlen);        /* no payload to print */
                } else {
                        ND_PRINT((ndo, "Information, send seq %u, rcv seq %u, Flags [%s], length %u",
                                LLC_I_NS(control),
                                LLC_IS_NR(control),
                                tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)),
-                                length));
+                                length + hdrlen));
                }
        }
-       return (0);
+       return (-hdrlen);
 }
 
 static void
index e15afa9e44663b665eeaf6cae0df56d1236b4e59..916946938fddf734f1ccf46ddcae07df3dc4540c 100644 (file)
@@ -197,6 +197,8 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
        u_int length = h->len;
        register const struct sll_header *sllp;
        u_short ether_type;
+       int llc_hdrlen;
+       u_int hdrlen;
 
        if (caplen < SLL_HDR_LEN) {
                /*
@@ -219,6 +221,7 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
        length -= SLL_HDR_LEN;
        caplen -= SLL_HDR_LEN;
        p += SLL_HDR_LEN;
+       hdrlen = SLL_HDR_LEN;
 
        ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
 
@@ -245,8 +248,10 @@ recurse:
                         * 802.2.
                         * Try to print the LLC-layer header & higher layers.
                         */
-                       if (llc_print(ndo, p, length, caplen, NULL, NULL) == 0)
+                       llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
+                       if (llc_hdrlen < 0)
                                goto unknown;   /* unknown LLC type */
+                       hdrlen += llc_hdrlen;
                        break;
 
                default:
@@ -263,9 +268,13 @@ recurse:
                 * Print VLAN information, and then go back and process
                 * the enclosed type field.
                 */
-               if (caplen < 4 || length < 4) {
+               if (caplen < 4) {
                        ND_PRINT((ndo, "[|vlan]"));
-                       return (SLL_HDR_LEN);
+                       return (hdrlen + caplen);
+               }
+               if (length < 4) {
+                       ND_PRINT((ndo, "[|vlan]"));
+                       return (hdrlen + length);
                }
                if (ndo->ndo_eflag) {
                        uint16_t tag = EXTRACT_16BITS(p);
@@ -283,6 +292,7 @@ recurse:
                p += 4;
                length -= 4;
                caplen -= 4;
+               hdrlen += 4;
                goto recurse;
        } else {
                if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
@@ -294,5 +304,5 @@ recurse:
                }
        }
 
-       return (SLL_HDR_LEN);
+       return (hdrlen);
 }
index 9a0e974279a027d4b620392e792c48026cea9e88..6565af9df87e0727d8c16c1c354de810f89edf4d 100644 (file)
@@ -148,6 +148,7 @@ u_int
 token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
 {
        const struct token_header *trp;
+       int llc_hdrlen;
        struct ether_header ehdr;
        u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
        int seg;
@@ -209,11 +210,15 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
        /* Frame Control field determines interpretation of packet */
        if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
                /* Try to print the LLC-layer header & higher layers */
-               if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr)) == 0) {
-                       /* ether_type not known, print raw packet */
+               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(&ehdr),
+                   EDST(&ehdr));
+               if (llc_hdrlen < 0) {
+                       /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
                                ND_DEFAULTPRINT(p, caplen);
+                       llc_hdrlen = -llc_hdrlen;
                }
+               hdr_len += llc_hdrlen;
        } else {
                /* Some kinds of TR packet we cannot handle intelligently */
                /* XXX - dissect MAC packets if frame type is 0 */