X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/ed4c2ad164153b4d410315a3e5ed55c10dd5e9cf..6c8ef0eb86a39c277d1a43802dd8ea01b51cfb2a:/print-ppp.c diff --git a/print-ppp.c b/print-ppp.c index 582a3727..89176172 100644 --- a/print-ppp.c +++ b/print-ppp.c @@ -22,6 +22,8 @@ * complete PPP support. */ +/* \summary: Point to Point Protocol (PPP) printer */ + /* * TODO: * o resolve XXX as much as possible @@ -29,12 +31,11 @@ * o BAP support */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #ifdef __bsdi__ #include @@ -43,7 +44,7 @@ #include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" #include "ppp.h" @@ -548,7 +549,7 @@ handle_ctrl_proto(netdissect_options *ndo, /* RFC 1661 says this is intended to be human readable */ if (len > 8) { ND_PRINT((ndo, "\n\t Message\n\t ")); - if (fn_printn(tptr + 4, len - 4, ndo->ndo_snapend)) + if (fn_printn(ndo, tptr + 4, len - 4, ndo->ndo_snapend)) goto trunc; } break; @@ -610,7 +611,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 6)")); return len; } - ND_TCHECK2(*(p + 2), 3); + ND_TCHECK_24BITS(p + 2); ND_PRINT((ndo, ": Vendor: %s (%u)", tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), EXTRACT_24BITS(p + 2))); @@ -629,7 +630,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return len; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); break; case LCPOPT_ACCM: @@ -637,7 +638,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return len; } - ND_TCHECK2(*(p + 2), 4); + ND_TCHECK_32BITS(p + 2); ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); break; case LCPOPT_AP: @@ -645,7 +646,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2)))); switch (EXTRACT_16BITS(p+2)) { @@ -667,7 +668,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p+2); if (EXTRACT_16BITS(p+2) == PPP_LQM) ND_PRINT((ndo, ": LQR")); else @@ -678,7 +679,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return 0; } - ND_TCHECK2(*(p + 2), 4); + ND_TCHECK_32BITS(p + 2); ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); break; case LCPOPT_PFC: @@ -690,7 +691,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2))); break; case LCPOPT_CBACK: @@ -709,7 +710,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p + 2); ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); break; case LCPOPT_MLED: @@ -731,16 +732,15 @@ print_lcp_config_options(netdissect_options *ndo, return 0; } ND_TCHECK2(*(p + 3), 4); - ND_PRINT((ndo, ": IPv4 %s", ipaddr_string(p + 3))); + ND_PRINT((ndo, ": IPv4 %s", ipaddr_string(ndo, p + 3))); break; case MEDCLASS_MAC: if (len != 9) { ND_PRINT((ndo, " (length bogus, should be = 9)")); return 0; } - ND_TCHECK(p[8]); - ND_PRINT((ndo, ": MAC %02x:%02x:%02x:%02x:%02x:%02x", - p[3], p[4], p[5], p[6], p[7], p[8])); + ND_TCHECK2(*(p + 3), 6); + ND_PRINT((ndo, ": MAC %s", etheraddr_string(ndo, p + 3))); break; case MEDCLASS_MNB: ND_PRINT((ndo, ": Magic-Num-Block")); /* XXX */ @@ -806,11 +806,20 @@ static const struct tok ppp_ml_flag_values[] = { static void handle_mlppp(netdissect_options *ndo, - const u_char *p, int length) { - + const u_char *p, int length) +{ if (!ndo->ndo_eflag) ND_PRINT((ndo, "MLPPP, ")); + if (length < 2) { + ND_PRINT((ndo, "[|mlppp]")); + return; + } + if (!ND_TTEST_16BITS(p)) { + ND_PRINT((ndo, "[|mlppp]")); + return; + } + ND_PRINT((ndo, "seq 0x%03x, Flags [%s], length %u", (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */ bittok2str(ppp_ml_flag_values, "none", *p & 0xc0), @@ -944,6 +953,9 @@ handle_pap(netdissect_options *ndo, switch (code) { case PAP_AREQ: + /* A valid Authenticate-Request is 6 or more octets long. */ + if (len < 6) + goto trunc; if (length - (p - p0) < 1) return; ND_TCHECK(*p); @@ -972,6 +984,13 @@ handle_pap(netdissect_options *ndo, break; case PAP_AACK: case PAP_ANAK: + /* Although some implementations ignore truncation at + * this point and at least one generates a truncated + * packet, RFC 1334 section 2.2.2 clearly states that + * both AACK and ANAK are at least 5 bytes long. + */ + if (len < 5) + goto trunc; if (length - (p - p0) < 1) return; ND_TCHECK(*p); @@ -1037,15 +1056,15 @@ print_ipcp_config_options(netdissect_options *ndo, } ND_TCHECK2(*(p + 6), 4); ND_PRINT((ndo, ": src %s, dst %s", - ipaddr_string(p + 2), - ipaddr_string(p + 6))); + ipaddr_string(ndo, p + 2), + ipaddr_string(ndo, p + 6))); break; case IPCPOPT_IPCOMP: if (len < 4) { ND_PRINT((ndo, " (length bogus, should be >= 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); + ND_TCHECK_16BITS(p+2); compproto = EXTRACT_16BITS(p+2); ND_PRINT((ndo, ": %s (0x%02x):", @@ -1118,7 +1137,7 @@ print_ipcp_config_options(netdissect_options *ndo, return 0; } ND_TCHECK2(*(p + 2), 4); - ND_PRINT((ndo, ": %s", ipaddr_string(p + 2))); + ND_PRINT((ndo, ": %s", ipaddr_string(ndo, p + 2))); break; default: /* @@ -1231,7 +1250,7 @@ print_ccp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 3)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK(p[2]); ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u", p[2] >> 5, p[2] & 0x1f)); break; @@ -1240,7 +1259,7 @@ print_ccp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK(p[3]); ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u", (p[2] & 0xc0) >> 6, (p[2] & 0x20) ? "Enabled" : "Disabled", @@ -1251,10 +1270,10 @@ print_ccp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK(p[3]); ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u", (p[2] & 0xf0) >> 4, - ((p[2] & 0x0f) == 8) ? "zlib" : "unkown", + ((p[2] & 0x0f) == 8) ? "zlib" : "unknown", p[2] & 0x0f, (p[3] & 0xfc) >> 2, p[3] & 0x03)); break; @@ -1326,7 +1345,7 @@ print_bacp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return len; } - ND_TCHECK2(*(p + 2), 4); + ND_TCHECK_32BITS(p + 2); ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2))); break; default: @@ -1352,14 +1371,15 @@ static void ppp_hdlc(netdissect_options *ndo, const u_char *p, int length) { - u_char *b, *s, *t, c; + u_char *b, *t, c; + const u_char *s; int i, proto; const void *se; if (length <= 0) return; - b = (u_int8_t *)malloc(length); + b = (u_char *)malloc(length); if (b == NULL) return; @@ -1368,14 +1388,13 @@ ppp_hdlc(netdissect_options *ndo, * Do this so that we dont overwrite the original packet * contents. */ - for (s = (u_char *)p, t = b, i = length; i > 0; i--) { + for (s = p, t = b, i = length; i > 0 && ND_TTEST(*s); i--) { c = *s++; if (c == 0x7d) { - if (i > 1) { - i--; - c = *s++ ^ 0x20; - } else - continue; + if (i <= 1 || !ND_TTEST(*s)) + break; + i--; + c = *s++ ^ 0x20; } *t++ = c; } @@ -1393,11 +1412,9 @@ ppp_hdlc(netdissect_options *ndo, case PPP_IP: ip_print(ndo, b + 1, length - 1); goto cleanup; -#ifdef INET6 case PPP_IPV6: ip6_print(ndo, b + 1, length - 1); goto cleanup; -#endif default: /* no luck - try next guess */ break; } @@ -1467,18 +1484,16 @@ handle_ppp(netdissect_options *ndo, case PPP_IP: ip_print(ndo, p, length); break; -#ifdef INET6 case ETHERTYPE_IPV6: /*XXX*/ case PPP_IPV6: ip6_print(ndo, p, length); break; -#endif case ETHERTYPE_IPX: /*XXX*/ case PPP_IPX: ipx_print(ndo, p, length); break; case PPP_OSI: - isoclns_print(ndo, p, length, length); + isoclns_print(ndo, p, length); break; case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: @@ -1675,6 +1690,11 @@ ppp_hdlc_if_print(netdissect_options *ndo, return (chdlc_if_print(ndo, h, p)); default: + if (caplen < 4) { + ND_PRINT((ndo, "[|ppp]")); + return (caplen); + } + if (ndo->ndo_eflag) ND_PRINT((ndo, "%02x %02x %d ", p[0], p[1], length)); p += 2; @@ -1703,7 +1723,7 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, #ifdef __bsdi__ register u_int length = h->len; register u_int caplen = h->caplen; - u_int16_t ptype; + uint16_t ptype; const u_char *q; int i; @@ -1782,11 +1802,9 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, case PPP_IP: ip_print(ndo, p, length); break; -#ifdef INET6 case PPP_IPV6: ip6_print(ndo, p, length); break; -#endif case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: mpls_print(ndo, p, length); @@ -1801,11 +1819,9 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, case PPP_IP: ip_print(ndo, p, length); break; -#ifdef INET6 case PPP_IPV6: ip6_print(ndo, p, length); break; -#endif case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: mpls_print(ndo, p, length); @@ -1833,11 +1849,9 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, case PPP_IP: ip_print(p, length); break; -#ifdef INET6 case PPP_IPV6: ip6_print(ndo, p, length); break; -#endif case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: mpls_print(ndo, p, length);