From: Guy Harris Date: Sat, 18 Apr 2015 01:38:46 +0000 (-0700) Subject: Clean up printing of LLC packets. X-Git-Tag: tcpdump-4.8.0~282^2~10 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/59864b113d8f2310a38d916e11a27c6f7e979ad9 Clean up printing of LLC packets. Don't print LLC header information for SNAP packets; if we have a SNAP header, just call snap_print() and return its return value, regardless of whether it's 1 or 0, don't fall into the code to print raw LLC header information - and don't print it with -e, either. If llc_print() returns 0, just call the default packet printer, don't print the MAC-layer header or the extracted ethertype - llc_print() will print the source and destination MAC addresses and whatever type information is in the LLC or SNAP headers. If we don't know the DSAP/LSAP, and it's an information frame (numbered or not) and not an XID frame, return 0, so that we give a hex dump of the raw payload. In addition, print the length when printing SNAP header information with -e. --- diff --git a/netdissect.h b/netdissect.h index d7361a4f..7cdd5347 100644 --- a/netdissect.h +++ b/netdissect.h @@ -460,8 +460,9 @@ extern void mpcp_print(netdissect_options *, const u_char *, u_int); extern void rpki_rtr_print(netdissect_options *, const u_char *, u_int); extern u_int sll_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); extern void dccp_print(netdissect_options *, const u_char *, const u_char *, u_int); -extern int llc_print(netdissect_options *, const u_char *, u_int, u_int, const u_char *, const u_char *, u_short *); -extern int snap_print(netdissect_options *, const u_char *, u_int, u_int, u_int); +extern int llc_print(netdissect_options *, const u_char *, u_int, u_int, const u_char *, const u_char *); +extern int snap_print(netdissect_options *, const u_char *, u_int, u_int, + const u_char *, const u_char *, u_int); extern void eigrp_print(netdissect_options *, const u_char *, u_int); extern void stp_print(netdissect_options *, const u_char *, u_int); extern void l2tp_print(netdissect_options *, const u_char *, u_int); diff --git a/print-802_11.c b/print-802_11.c index 3c510e8a..2c9f2a38 100644 --- a/print-802_11.c +++ b/print-802_11.c @@ -2332,7 +2332,6 @@ ieee802_11_print(netdissect_options *ndo, uint16_t fc; u_int caplen, hdrlen, meshdrlen; const uint8_t *src, *dst; - u_short extracted_ethertype; caplen = orig_caplen; /* Remove FCS, if present */ @@ -2409,20 +2408,11 @@ 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, - &extracted_ethertype) == 0) { + if (llc_print(ndo, p, length, caplen, dst, src) == 0) { /* * Some kinds of LLC packet we cannot * handle intelligently */ - if (!ndo->ndo_eflag) { - ieee_802_11_hdr_print(ndo, fc, p - hdrlen, - hdrlen, meshdrlen); - } - if (extracted_ethertype) - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string( - htons(extracted_ethertype)))); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } diff --git a/print-atm.c b/print-atm.c index b5d3385f..82a012ba 100644 --- a/print-atm.c +++ b/print-atm.c @@ -218,15 +218,8 @@ static void atm_llc_print(netdissect_options *ndo, const u_char *p, int length, int caplen) { - u_short extracted_ethertype; - - if (!llc_print(ndo, p, length, caplen, NULL, NULL, - &extracted_ethertype)) { + if (!llc_print(ndo, p, length, caplen, NULL, NULL)) { /* ether_type not known, print raw packet */ - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } diff --git a/print-cip.c b/print-cip.c index fadb83be..23f61788 100644 --- a/print-cip.c +++ b/print-cip.c @@ -61,7 +61,6 @@ cip_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char { u_int caplen = h->caplen; u_int length = h->len; - u_short extracted_ethertype; if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) { ND_PRINT((ndo, "[|cip]")); @@ -75,15 +74,7 @@ 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, - &extracted_ethertype) == 0) { - /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) - cip_print(ndo, length); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } + if (llc_print(ndo, p, length, caplen, NULL, NULL) == 0) { if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } diff --git a/print-ether.c b/print-ether.c index e491515c..26c5c97c 100644 --- a/print-ether.c +++ b/print-ether.c @@ -130,7 +130,6 @@ ether_print(netdissect_options *ndo, struct ether_header *ep; u_int orig_length; u_short ether_type; - u_short extracted_ether_type; if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) { ND_PRINT((ndo, "[|ether]")); @@ -157,15 +156,8 @@ 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), - &extracted_ether_type) == 0) { + if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep)) == 0) { /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) { - if (print_encap_header != NULL) - (*print_encap_header)(ndo, encap_header_arg); - ether_hdr_print(ndo, (u_char *)ep, orig_length); - } - if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } @@ -205,15 +197,8 @@ 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), - &extracted_ether_type) == 0) { + if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep)) == 0) { /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) { - if (print_encap_header != NULL) - (*print_encap_header)(ndo, encap_header_arg); - ether_hdr_print(ndo, (u_char *)ep, orig_length); - } - if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } diff --git a/print-fddi.c b/print-fddi.c index 04ab0f67..9e6ec0b1 100644 --- a/print-fddi.c +++ b/print-fddi.c @@ -282,7 +282,6 @@ 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; - u_short extracted_ethertype; if (caplen < FDDI_HDRLEN) { ND_PRINT((ndo, "[|fddi]")); @@ -305,19 +304,11 @@ 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), - &extracted_ethertype) == 0) { + if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr)) == 0) { /* * Some kinds of LLC packet we cannot * handle intelligently */ - if (!ndo->ndo_eflag) - fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN, - ESRC(&ehdr), EDST(&ehdr)); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } diff --git a/print-fr.c b/print-fr.c index d7dfe6c7..17321b14 100644 --- a/print-fr.c +++ b/print-fr.c @@ -330,7 +330,7 @@ fr_print(netdissect_options *ndo, break; case NLPID_SNAP: - if (snap_print(ndo, p, length, length, 0) == 0) { + if (snap_print(ndo, p, length, length, NULL, NULL, 0) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) fr_hdr_print(ndo, length + hdr_len, hdr_len, diff --git a/print-ipfc.c b/print-ipfc.c index 6c92f901..b2869eb8 100644 --- a/print-ipfc.c +++ b/print-ipfc.c @@ -81,7 +81,6 @@ 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; - u_short extracted_ethertype; if (caplen < IPFC_HDRLEN) { ND_PRINT((ndo, "[|ipfc]")); @@ -101,19 +100,11 @@ 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), - &extracted_ethertype) == 0) { + if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr)) == 0) { /* * Some kinds of LLC packet we cannot * handle intelligently */ - if (!ndo->ndo_eflag) - ipfc_hdr_print(ndo, ipfcp, length + IPFC_HDRLEN, - ESRC(&ehdr), EDST(&ehdr)); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } diff --git a/print-juniper.c b/print-juniper.c index 750f76ab..d402c00d 100644 --- a/print-juniper.c +++ b/print-juniper.c @@ -937,8 +937,7 @@ 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, - &extracted_ethertype) != 0) + if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL) != 0) return l2info.header_len; } @@ -986,8 +985,7 @@ 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, - &extracted_ethertype) != 0) + if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL) != 0) return l2info.header_len; } diff --git a/print-llc.c b/print-llc.c index fc838028..5681b495 100644 --- a/print-llc.c +++ b/print-llc.c @@ -137,18 +137,17 @@ static const struct oui_tok oui_to_tok[] = { }; /* - * Returns non-zero IFF it succeeds in printing the header + * 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). */ int llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, - const u_char *esrc, const u_char *edst, u_short *extracted_ethertype) + const u_char *esrc, const u_char *edst) { uint8_t dsap_field, dsap, ssap_field, ssap; uint16_t control; int is_u; - register int ret; - - *extracted_ethertype = 0; if (caplen < 3 || length < 3) { ND_PRINT((ndo, "[|llc]")); @@ -215,6 +214,23 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, dsap = dsap_field & ~LLC_IG; ssap = ssap_field & ~LLC_GSAP; + /* + * Check for SNAP UI packets; if we have one, there's no point + * in printing the LLC header information, as we already know it - + * the relevant protocol-selection information is the SNAP OUI + * and PID, so it's sufficient to print that for frames we + * don't know how to print and for the "-e" flag. + */ + if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP + && control == LLC_UI) { + /* + * XXX - what *is* the right bridge pad value here? + * 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 (ndo->ndo_eflag) { ND_PRINT((ndo, "LLC, dsap %s (0x%02x) %s, ssap %s (0x%02x) %s", tok2str(llc_values, "Unknown", dsap), @@ -298,18 +314,6 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, return (1); } - if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP - && control == LLC_UI) { - /* - * XXX - what *is* the right bridge pad value here? - * Does anybody ever bridge one form of LAN traffic - * over a networking type that uses 802.2 LLC? - */ - ret = snap_print(ndo, p+3, length-3, caplen-3, 2); - if (ret) - return (ret); - } - if (!ndo->ndo_eflag) { if (ssap == dsap) { if (esrc == NULL || edst == NULL) @@ -344,6 +348,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, if ((control & ~LLC_U_POLL) == LLC_XID) { if (*p == LLC_XID_FI) { ND_PRINT((ndo, ": %02x %02x", p[1], p[2])); + return (1); } } } else { @@ -353,6 +358,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, LLC_IS_NR(control), tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)), length)); + return (1); /* no payload to print */ } else { ND_PRINT((ndo, "Information, send seq %u, rcv seq %u, Flags [%s], length %u", LLC_I_NS(control), @@ -361,11 +367,38 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, length)); } } - return(1); + return (0); +} + +static void +snap_hdr_print(netdissect_options *ndo, const uint8_t *esrc, const uint8_t *edst, + uint32_t orgcode, u_short et, u_int length) +{ + const struct tok *tok = null_values; + const struct oui_tok *otp; + + if (esrc != NULL && edst != NULL) { + ND_PRINT((ndo, "%s > %s ", + etheraddr_string(ndo, esrc), + etheraddr_string(ndo, edst))); + } + for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) { + if (otp->oui == orgcode) { + tok = otp->tok; + break; + } + } + ND_PRINT((ndo, "SNAP oui %s (0x%06x), %s %s (0x%04x), length %u: ", + tok2str(oui_values, "Unknown", orgcode), + orgcode, + (orgcode == 0x000000 ? "ethertype" : "pid"), + tok2str(tok, "Unknown", et), + et, length)); } int -snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, u_int bridge_pad) +snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, + const u_char *esrc, const u_char *edst, u_int bridge_pad) { uint32_t orgcode; register u_short et; @@ -378,21 +411,11 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, et = EXTRACT_16BITS(p + 3); if (ndo->ndo_eflag) { - const struct tok *tok = null_values; - const struct oui_tok *otp; - - for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) { - if (otp->oui == orgcode) { - tok = otp->tok; - break; - } - } - ND_PRINT((ndo, "oui %s (0x%06x), %s %s (0x%04x): ", - tok2str(oui_values, "Unknown", orgcode), - orgcode, - (orgcode == 0x000000 ? "ethertype" : "pid"), - tok2str(tok, "Unknown", et), - et)); + /* + * Somebody's already printed the MAC addresses, if there + * are any, so just print the SNAP header. + */ + snap_hdr_print(ndo, NULL, NULL, orgcode, et, length - 5); } p += 5; length -= 5; @@ -521,6 +544,8 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, return (1); } } + if (!ndo->ndo_eflag) + snap_hdr_print(ndo, esrc, edst, orgcode, et, length); return (0); trunc: diff --git a/print-sll.c b/print-sll.c index 76b4e95f..e15afa9e 100644 --- a/print-sll.c +++ b/print-sll.c @@ -197,7 +197,6 @@ 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; - u_short extracted_ethertype; if (caplen < SLL_HDR_LEN) { /* @@ -246,23 +245,15 @@ recurse: * 802.2. * Try to print the LLC-layer header & higher layers. */ - if (llc_print(ndo, p, length, caplen, NULL, NULL, - &extracted_ethertype) == 0) + if (llc_print(ndo, p, length, caplen, NULL, NULL) == 0) goto unknown; /* unknown LLC type */ break; default: - extracted_ethertype = 0; /*FALLTHROUGH*/ unknown: /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) - sll_print(ndo, sllp, length + SLL_HDR_LEN); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); break; diff --git a/print-token.c b/print-token.c index 33647a14..9a0e9742 100644 --- a/print-token.c +++ b/print-token.c @@ -148,7 +148,6 @@ u_int token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { const struct token_header *trp; - u_short extracted_ethertype; struct ether_header ehdr; u_int route_len = 0, hdr_len = TOKEN_HDRLEN; int seg; @@ -210,17 +209,8 @@ 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), - &extracted_ethertype) == 0) { + if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr)) == 0) { /* ether_type not known, print raw packet */ - if (!ndo->ndo_eflag) - token_hdr_print(ndo, trp, - length + TOKEN_HDRLEN + route_len, - ESRC(&ehdr), EDST(&ehdr)); - if (extracted_ethertype) { - ND_PRINT((ndo, "(LLC %s) ", - etherproto_string(htons(extracted_ethertype)))); - } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); }