From bd00116d80c18b782f4cb15dfc90cd5bf993d4f5 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 17 Apr 2015 23:42:22 -0700 Subject: [PATCH] Skip the LLC and SNAP headers with -x. 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 | 10 +++--- print-802_11.c | 6 +++- print-atm.c | 13 ++++--- print-cip.c | 9 +++-- print-ether.c | 49 ++++++++++++++++---------- print-fddi.c | 20 ++++++----- print-ipfc.c | 14 ++++---- print-juniper.c | 10 ++++-- print-llc.c | 94 +++++++++++++++++++++++++++++-------------------- print-sll.c | 18 +++++++--- print-token.c | 9 +++-- 11 files changed, 161 insertions(+), 91 deletions(-) diff --git a/netdissect.h b/netdissect.h index 7cdd5347..f4de98cd 100644 --- a/netdissect.h +++ b/netdissect.h @@ -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); diff --git a/print-802_11.c b/print-802_11.c index 2c9f2a38..2b4463ec 100644 --- a/print-802_11.c +++ b/print-802_11.c @@ -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: diff --git a/print-atm.c b/print-atm.c index 82a012ba..d2f18f7a 100644 --- a/print-atm.c +++ b/print-atm.c @@ -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); } diff --git a/print-cip.c b/print-cip.c index 23f61788..fde5ab44 100644 --- a/print-cip.c +++ b/print-cip.c @@ -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); } diff --git a/print-ether.c b/print-ether.c index 26c5c97c..f4906260 100644 --- a/print-ether.c +++ b/print-ether.c @@ -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; + return (caplen); + } + if (length < ETHER_HDRLEN) { + ND_PRINT((ndo, "[|ether]")); + 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; + return (hdrlen + caplen); + } + if (length < 4) { + ND_PRINT((ndo, "[|vlan]")); + 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)); } /* diff --git a/print-fddi.c b/print-fddi.c index 9e6ec0b1..7576b6f0 100644 --- a/print-fddi.c +++ b/print-fddi.c @@ -277,15 +277,16 @@ fddi_smt_print(netdissect_options *ndo, const u_char *p _U_, u_int length _U_) ND_PRINT((ndo, "")); } -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)); } diff --git a/print-ipfc.c b/print-ipfc.c index b2869eb8..6d07f80e 100644 --- a/print-ipfc.c +++ b/print-ipfc.c @@ -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)); } diff --git a/print-juniper.c b/print-juniper.c index 8fc8eee2..6ae5b6d8 100644 --- a/print-juniper.c +++ b/print-juniper.c @@ -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; } diff --git a/print-llc.c b/print-llc.c index 65c08c08..0132bdaa 100644 --- a/print-llc.c +++ b/print-llc.c @@ -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 (1); + return (caplen); + } + if (length < 3) { + ND_PRINT((ndo, "[|llc]")); + ND_DEFAULTPRINT((u_char *)p, caplen); + 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 diff --git a/print-sll.c b/print-sll.c index e15afa9e..91694693 100644 --- a/print-sll.c +++ b/print-sll.c @@ -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); } diff --git a/print-token.c b/print-token.c index 9a0e9742..6565af9d 100644 --- a/print-token.c +++ b/print-token.c @@ -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 */