X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/c6d472bf63488b0c2ab7ab9f4b32c68dd2c8ea2b..9f957a5883cb4c5c99cefa71b42fc9d2d27d73e1:/print-ppp.c diff --git a/print-ppp.c b/print-ppp.c index edc03c02..31b87a24 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" @@ -178,9 +179,6 @@ static const struct tok cpcodes[] = { #define LCPOPT_SDLOS 29 #define LCPOPT_PPPMUX 30 -#define LCPOPT_MIN LCPOPT_VEXT -#define LCPOPT_MAX LCPOPT_PPPMUX - static const char *lcpconfopts[] = { "Vend-Ext", /* (0) */ "MRU", /* (1) */ @@ -215,6 +213,8 @@ static const char *lcpconfopts[] = { "PPP-Muxing", /* (30) */ }; +#define NUM_LCPOPTS (sizeof lcpconfopts / sizeof lcpconfopts[0]) + /* ECP - to be supported */ /* CCP Config Options */ @@ -401,22 +401,22 @@ static const struct tok papcode_values[] = { #define BAP_CSIND 7 #define BAP_CSRES 8 -static int print_lcp_config_options(netdissect_options *, const u_char *p, int); -static int print_ipcp_config_options(netdissect_options *, const u_char *p, int); -static int print_ip6cp_config_options(netdissect_options *, const u_char *p, int); -static int print_ccp_config_options(netdissect_options *, const u_char *p, int); -static int print_bacp_config_options(netdissect_options *, const u_char *p, int); -static void handle_ppp(netdissect_options *, u_int proto, const u_char *p, int length); +static u_int print_lcp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_ipcp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_ip6cp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_ccp_config_options(netdissect_options *, const u_char *p, u_int); +static u_int print_bacp_config_options(netdissect_options *, const u_char *p, u_int); +static void handle_ppp(netdissect_options *, u_int proto, const u_char *p, u_int length); /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ static void handle_ctrl_proto(netdissect_options *ndo, - u_int proto, const u_char *pptr, int length) + u_int proto, const u_char *pptr, u_int length) { const char *typestr; u_int code, len; - int (*pfunc)(netdissect_options *, const u_char *, int); - int x, j; + u_int (*pfunc)(netdissect_options *, const u_char *, u_int); + u_int x, j; const u_char *tptr; tptr=pptr; @@ -426,28 +426,41 @@ handle_ctrl_proto(netdissect_options *ndo, if (length < 4) /* FIXME weak boundary checking */ goto trunc; - ND_TCHECK2(*tptr, 2); + ND_TCHECK_2(tptr); - code = *tptr++; + code = EXTRACT_U_1(tptr); + tptr++; ND_PRINT((ndo, "%s (0x%02x), id %u, length %u", tok2str(cpcodes, "Unknown Opcode",code), code, - *tptr++, /* ID */ + EXTRACT_U_1(tptr), /* ID */ length + 2)); + tptr++; if (!ndo->ndo_vflag) return; - if (length <= 4) - return; /* there may be a NULL confreq etc. */ - - ND_TCHECK2(*tptr, 2); - len = EXTRACT_16BITS(tptr); + ND_TCHECK_2(tptr); + len = EXTRACT_BE_U_2(tptr); tptr += 2; + if (len < 4) { + ND_PRINT((ndo, "\n\tencoded length %u (< 4))", len)); + return; + } + + if (len > length) { + ND_PRINT((ndo, "\n\tencoded length %u (> packet length %u))", len, length)); + return; + } + length = len; + ND_PRINT((ndo, "\n\tencoded length %u (=Option(s) length %u)", len, len - 4)); + if (length == 4) + return; /* there may be a NULL confreq etc. */ + if (ndo->ndo_vflag > 1) print_unknown_data(ndo, pptr - 2, "\n\t", 6); @@ -456,13 +469,13 @@ handle_ctrl_proto(netdissect_options *ndo, case CPCODES_VEXT: if (length < 11) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); + ND_TCHECK_4(tptr); + ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr))); tptr += 4; - ND_TCHECK2(*tptr, 3); + ND_TCHECK_3(tptr); ND_PRINT((ndo, " Vendor: %s (%u)", - tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)), - EXTRACT_24BITS(tptr))); + tok2str(oui_values,"Unknown",EXTRACT_BE_U_3(tptr)), + EXTRACT_BE_U_3(tptr))); /* XXX: need to decode Kind and Value(s)? */ break; case CPCODES_CONF_REQ: @@ -503,7 +516,7 @@ handle_ctrl_proto(netdissect_options *ndo, break; x -= j; tptr += j; - } while (x > 0); + } while (x != 0); break; case CPCODES_TERM_REQ: @@ -516,10 +529,10 @@ handle_ctrl_proto(netdissect_options *ndo, case CPCODES_PROT_REJ: if (length < 6) break; - ND_TCHECK2(*tptr, 2); + ND_TCHECK_2(tptr); ND_PRINT((ndo, "\n\t Rejected %s Protocol (0x%04x)", - tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), - EXTRACT_16BITS(tptr))); + tok2str(ppptype2str,"unknown", EXTRACT_BE_U_2(tptr)), + EXTRACT_BE_U_2(tptr))); /* XXX: need to decode Rejected-Information? - hexdump for now */ if (len > 6) { ND_PRINT((ndo, "\n\t Rejected Packet")); @@ -531,20 +544,20 @@ handle_ctrl_proto(netdissect_options *ndo, case CPCODES_DISC_REQ: if (length < 8) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); + ND_TCHECK_4(tptr); + ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr))); /* XXX: need to decode Data? - hexdump for now */ if (len > 8) { ND_PRINT((ndo, "\n\t -----trailing data-----")); - ND_TCHECK2(tptr[4], len - 8); + ND_TCHECK_LEN(tptr + 4, len - 8); print_unknown_data(ndo, tptr + 4, "\n\t ", len - 8); } break; case CPCODES_ID: if (length < 8) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); + ND_TCHECK_4(tptr); + ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr))); /* RFC 1661 says this is intended to be human readable */ if (len > 8) { ND_PRINT((ndo, "\n\t Message\n\t ")); @@ -555,10 +568,10 @@ handle_ctrl_proto(netdissect_options *ndo, case CPCODES_TIME_REM: if (length < 12) break; - ND_TCHECK2(*tptr, 4); - ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr))); - ND_TCHECK2(*(tptr + 4), 4); - ND_PRINT((ndo, ", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4))); + ND_TCHECK_4(tptr); + ND_PRINT((ndo, "\n\t Magic-Num 0x%08x", EXTRACT_BE_U_4(tptr))); + ND_TCHECK_4(tptr + 4); + ND_PRINT((ndo, ", Seconds-Remaining %us", EXTRACT_BE_U_4(tptr + 4))); /* XXX: need to decode Message? */ break; default: @@ -576,28 +589,28 @@ trunc: } /* LCP config options */ -static int +static u_int print_lcp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = EXTRACT_U_1(p); + len = EXTRACT_U_1(p + 1); if (length < len) return 0; if (len < 2) { - if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) + if (opt < NUM_LCPOPTS) ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", lcpconfopts[opt], opt, len)); else ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt)); return 0; } - if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) + if (opt < NUM_LCPOPTS) ND_PRINT((ndo, "\n\t %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len)); else { ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt)); @@ -610,17 +623,17 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 6)")); return len; } - ND_TCHECK2(*(p + 2), 3); + ND_TCHECK_3(p + 2); ND_PRINT((ndo, ": Vendor: %s (%u)", - tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), - EXTRACT_24BITS(p + 2))); + tok2str(oui_values,"Unknown",EXTRACT_BE_U_3(p + 2)), + EXTRACT_BE_U_3(p + 2))); #if 0 - ND_TCHECK(p[5]); - ND_PRINT((ndo, ", kind: 0x%02x", p[5])); + ND_TCHECK_1(p + 5); + ND_PRINT((ndo, ", kind: 0x%02x", EXTRACT_U_1(p + 5))); ND_PRINT((ndo, ", Value: 0x")); for (i = 0; i < len - 6; i++) { - ND_TCHECK(p[6 + i]); - ND_PRINT((ndo, "%02x", p[6 + i])); + ND_TCHECK_1(p + 6 + i); + ND_PRINT((ndo, "%02x", EXTRACT_U_1(p + 6 + i))); } #endif break; @@ -629,29 +642,29 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return len; } - ND_TCHECK2(*(p + 2), 2); - ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); + ND_TCHECK_2(p + 2); + ND_PRINT((ndo, ": %u", EXTRACT_BE_U_2(p + 2))); break; case LCPOPT_ACCM: if (len != 6) { ND_PRINT((ndo, " (length bogus, should be = 6)")); return len; } - ND_TCHECK2(*(p + 2), 4); - ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); + ND_TCHECK_4(p + 2); + ND_PRINT((ndo, ": 0x%08x", EXTRACT_BE_U_4(p + 2))); break; case LCPOPT_AP: if (len < 4) { ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 2); - ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2)))); + ND_TCHECK_2(p + 2); + ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_BE_U_2(p + 2)))); - switch (EXTRACT_16BITS(p+2)) { + switch (EXTRACT_BE_U_2(p + 2)) { case PPP_CHAP: - ND_TCHECK(p[4]); - ND_PRINT((ndo, ", %s", tok2str(authalg_values, "Unknown Auth Alg %u", p[4]))); + ND_TCHECK_1(p + 4); + ND_PRINT((ndo, ", %s", tok2str(authalg_values, "Unknown Auth Alg %u", EXTRACT_U_1(p + 4)))); break; case PPP_PAP: /* fall through */ case PPP_EAP: @@ -667,8 +680,8 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); - if (EXTRACT_16BITS(p+2) == PPP_LQM) + ND_TCHECK_2(p + 2); + if (EXTRACT_BE_U_2(p + 2) == PPP_LQM) ND_PRINT((ndo, ": LQR")); else ND_PRINT((ndo, ": unknown")); @@ -678,8 +691,8 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return 0; } - ND_TCHECK2(*(p + 2), 4); - ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2))); + ND_TCHECK_4(p + 2); + ND_PRINT((ndo, ": 0x%08x", EXTRACT_BE_U_4(p + 2))); break; case LCPOPT_PFC: break; @@ -690,8 +703,8 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); - ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2))); + ND_TCHECK_2(p + 2); + ND_PRINT((ndo, ": 0x%04x", EXTRACT_BE_U_2(p + 2))); break; case LCPOPT_CBACK: if (len < 3) { @@ -699,26 +712,26 @@ print_lcp_config_options(netdissect_options *ndo, return 0; } ND_PRINT((ndo, ": ")); - ND_TCHECK(p[2]); + ND_TCHECK_1(p + 2); ND_PRINT((ndo, ": Callback Operation %s (%u)", - tok2str(ppp_callback_values, "Unknown", p[2]), - p[2])); + tok2str(ppp_callback_values, "Unknown", EXTRACT_U_1(p + 2)), + EXTRACT_U_1(p + 2))); break; case LCPOPT_MLMRRU: if (len != 4) { ND_PRINT((ndo, " (length bogus, should be = 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); - ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2))); + ND_TCHECK_2(p + 2); + ND_PRINT((ndo, ": %u", EXTRACT_BE_U_2(p + 2))); break; case LCPOPT_MLED: if (len < 3) { ND_PRINT((ndo, " (length bogus, should be >= 3)")); return 0; } - ND_TCHECK(p[2]); - switch (p[2]) { /* class */ + ND_TCHECK_1(p + 2); + switch (EXTRACT_U_1(p + 2)) { /* class */ case MEDCLASS_NULL: ND_PRINT((ndo, ": Null")); break; @@ -730,7 +743,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 7)")); return 0; } - ND_TCHECK2(*(p + 3), 4); + ND_TCHECK_4(p + 3); ND_PRINT((ndo, ": IPv4 %s", ipaddr_string(ndo, p + 3))); break; case MEDCLASS_MAC: @@ -738,7 +751,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 9)")); return 0; } - ND_TCHECK2(*(p + 3), 6); + ND_TCHECK_6(p + 3); ND_PRINT((ndo, ": MAC %s", etheraddr_string(ndo, p + 3))); break; case MEDCLASS_MNB: @@ -748,7 +761,7 @@ print_lcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, ": PSNDN")); /* XXX */ break; default: - ND_PRINT((ndo, ": Unknown class %u", p[2])); + ND_PRINT((ndo, ": Unknown class %u", EXTRACT_U_1(p + 2))); break; } break; @@ -782,12 +795,12 @@ print_lcp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; @@ -805,50 +818,59 @@ 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, u_int length) { if (!ndo->ndo_eflag) ND_PRINT((ndo, "MLPPP, ")); + if (length < 2) { + ND_PRINT((ndo, "[|mlppp]")); + return; + } + if (!ND_TTEST_2(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), + (EXTRACT_BE_U_2(p))&0x0fff, /* only support 12-Bit sequence space for now */ + bittok2str(ppp_ml_flag_values, "none", EXTRACT_U_1(p) & 0xc0), length)); } /* CHAP */ static void handle_chap(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { u_int code, len; - int val_size, name_size, msg_size; + u_int val_size, name_size, msg_size; const u_char *p0; - int i; + u_int i; p0 = p; if (length < 1) { ND_PRINT((ndo, "[|chap]")); return; } else if (length < 4) { - ND_TCHECK(*p); - ND_PRINT((ndo, "[|chap 0x%02x]", *p)); + ND_TCHECK_1(p); + ND_PRINT((ndo, "[|chap 0x%02x]", EXTRACT_U_1(p))); return; } - ND_TCHECK(*p); - code = *p; + ND_TCHECK_1(p); + code = EXTRACT_U_1(p); ND_PRINT((ndo, "CHAP, %s (0x%02x)", tok2str(chapcode_values,"unknown",code), code)); p++; - ND_TCHECK(*p); - ND_PRINT((ndo, ", id %u", *p)); /* ID */ + ND_TCHECK_1(p); + ND_PRINT((ndo, ", id %u", EXTRACT_U_1(p))); /* ID */ p++; - ND_TCHECK2(*p, 2); - len = EXTRACT_16BITS(p); + ND_TCHECK_2(p); + len = EXTRACT_BE_U_2(p); p += 2; /* @@ -863,21 +885,23 @@ handle_chap(netdissect_options *ndo, case CHAP_RESP: if (length - (p - p0) < 1) return; - ND_TCHECK(*p); - val_size = *p; /* value size */ + ND_TCHECK_1(p); + val_size = EXTRACT_U_1(p); /* value size */ p++; if (length - (p - p0) < val_size) return; ND_PRINT((ndo, ", Value ")); for (i = 0; i < val_size; i++) { - ND_TCHECK(*p); - ND_PRINT((ndo, "%02x", *p++)); + ND_TCHECK_1(p); + ND_PRINT((ndo, "%02x", EXTRACT_U_1(p))); + p++; } name_size = len - (p - p0); ND_PRINT((ndo, ", Name ")); for (i = 0; i < name_size; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + ND_TCHECK_1(p); + safeputchar(ndo, EXTRACT_U_1(p)); + p++; } break; case CHAP_SUCC: @@ -885,8 +909,9 @@ handle_chap(netdissect_options *ndo, msg_size = len - (p - p0); ND_PRINT((ndo, ", Msg ")); for (i = 0; i< msg_size; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + ND_TCHECK_1(p); + safeputchar(ndo, EXTRACT_U_1(p)); + p++; } break; } @@ -899,89 +924,102 @@ trunc: /* PAP (see RFC 1334) */ static void handle_pap(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { u_int code, len; - int peerid_len, passwd_len, msg_len; + u_int peerid_len, passwd_len, msg_len; const u_char *p0; - int i; + u_int i; p0 = p; if (length < 1) { ND_PRINT((ndo, "[|pap]")); return; } else if (length < 4) { - ND_TCHECK(*p); - ND_PRINT((ndo, "[|pap 0x%02x]", *p)); + ND_TCHECK_1(p); + ND_PRINT((ndo, "[|pap 0x%02x]", EXTRACT_U_1(p))); return; } - ND_TCHECK(*p); - code = *p; + ND_TCHECK_1(p); + code = EXTRACT_U_1(p); ND_PRINT((ndo, "PAP, %s (0x%02x)", tok2str(papcode_values, "unknown", code), code)); p++; - ND_TCHECK(*p); - ND_PRINT((ndo, ", id %u", *p)); /* ID */ + ND_TCHECK_1(p); + ND_PRINT((ndo, ", id %u", EXTRACT_U_1(p))); /* ID */ p++; - ND_TCHECK2(*p, 2); - len = EXTRACT_16BITS(p); + ND_TCHECK_2(p); + len = EXTRACT_BE_U_2(p); p += 2; - if ((int)len > length) { + if (len > length) { ND_PRINT((ndo, ", length %u > packet size", len)); return; } length = len; - if (length < (p - p0)) { + if (length < (size_t)(p - p0)) { ND_PRINT((ndo, ", length %u < PAP header length", length)); return; } 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); - peerid_len = *p; /* Peer-ID Length */ + ND_TCHECK_1(p); + peerid_len = EXTRACT_U_1(p); /* Peer-ID Length */ p++; if (length - (p - p0) < peerid_len) return; ND_PRINT((ndo, ", Peer ")); for (i = 0; i < peerid_len; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + ND_TCHECK_1(p); + safeputchar(ndo, EXTRACT_U_1(p)); + p++; } if (length - (p - p0) < 1) return; - ND_TCHECK(*p); - passwd_len = *p; /* Password Length */ + ND_TCHECK_1(p); + passwd_len = EXTRACT_U_1(p); /* Password Length */ p++; if (length - (p - p0) < passwd_len) return; ND_PRINT((ndo, ", Name ")); for (i = 0; i < passwd_len; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + ND_TCHECK_1(p); + safeputchar(ndo, EXTRACT_U_1(p)); + p++; } 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); - msg_len = *p; /* Msg-Length */ + ND_TCHECK_1(p); + msg_len = EXTRACT_U_1(p); /* Msg-Length */ p++; if (length - (p - p0) < msg_len) return; ND_PRINT((ndo, ", Msg ")); for (i = 0; i< msg_len; i++) { - ND_TCHECK(*p); - safeputchar(ndo, *p++); + ND_TCHECK_1(p); + safeputchar(ndo, EXTRACT_U_1(p)); + p++; } break; } @@ -994,25 +1032,25 @@ trunc: /* BAP */ static void handle_bap(netdissect_options *ndo _U_, - const u_char *p _U_, int length _U_) + const u_char *p _U_, u_int length _U_) { /* XXX: to be supported!! */ } /* IPCP config options */ -static int +static u_int print_ipcp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = EXTRACT_U_1(p); + len = EXTRACT_U_1(p + 1); if (length < len) return 0; if (len < 2) { @@ -1034,7 +1072,7 @@ print_ipcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 10)")); return len; } - ND_TCHECK2(*(p + 6), 4); + ND_TCHECK_4(p + 6); ND_PRINT((ndo, ": src %s, dst %s", ipaddr_string(ndo, p + 2), ipaddr_string(ndo, p + 6))); @@ -1044,8 +1082,8 @@ print_ipcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 4)")); return 0; } - ND_TCHECK2(*(p + 2), 2); - compproto = EXTRACT_16BITS(p+2); + ND_TCHECK_2(p + 2); + compproto = EXTRACT_BE_U_2(p + 2); ND_PRINT((ndo, ": %s (0x%02x):", tok2str(ipcpopt_compproto_values, "Unknown", compproto), @@ -1062,14 +1100,14 @@ print_ipcp_config_options(netdissect_options *ndo, return 0; } - ND_TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN); + ND_TCHECK_LEN(p + 2, IPCPOPT_IPCOMP_MINLEN); ND_PRINT((ndo, "\n\t TCP Space %u, non-TCP Space %u" \ ", maxPeriod %u, maxTime %u, maxHdr %u", - EXTRACT_16BITS(p+4), - EXTRACT_16BITS(p+6), - EXTRACT_16BITS(p+8), - EXTRACT_16BITS(p+10), - EXTRACT_16BITS(p+12))); + EXTRACT_BE_U_2(p + 4), + EXTRACT_BE_U_2(p + 6), + EXTRACT_BE_U_2(p + 8), + EXTRACT_BE_U_2(p + 10), + EXTRACT_BE_U_2(p + 12))); /* suboptions present ? */ if (len > IPCPOPT_IPCOMP_MINLEN) { @@ -1079,9 +1117,9 @@ print_ipcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, "\n\t Suboptions, length %u", ipcomp_subopttotallen)); while (ipcomp_subopttotallen >= 2) { - ND_TCHECK2(*p, 2); - ipcomp_subopt = *p; - ipcomp_suboptlen = *(p+1); + ND_TCHECK_2(p); + ipcomp_subopt = EXTRACT_U_1(p); + ipcomp_suboptlen = EXTRACT_U_1(p + 1); /* sanity check */ if (ipcomp_subopt == 0 || @@ -1116,7 +1154,7 @@ print_ipcp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return 0; } - ND_TCHECK2(*(p + 2), 4); + ND_TCHECK_4(p + 2); ND_PRINT((ndo, ": %s", ipaddr_string(ndo, p + 2))); break; default: @@ -1125,11 +1163,11 @@ print_ipcp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: @@ -1138,17 +1176,17 @@ trunc: } /* IP6CP config options */ -static int +static u_int print_ip6cp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = EXTRACT_U_1(p); + len = EXTRACT_U_1(p + 1); if (length < len) return 0; if (len < 2) { @@ -1170,12 +1208,12 @@ print_ip6cp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 10)")); return len; } - ND_TCHECK2(*(p + 2), 8); + ND_TCHECK_8(p + 2); ND_PRINT((ndo, ": %04x:%04x:%04x:%04x", - EXTRACT_16BITS(p + 2), - EXTRACT_16BITS(p + 4), - EXTRACT_16BITS(p + 6), - EXTRACT_16BITS(p + 8))); + EXTRACT_BE_U_2(p + 2), + EXTRACT_BE_U_2(p + 4), + EXTRACT_BE_U_2(p + 6), + EXTRACT_BE_U_2(p + 8))); break; default: /* @@ -1183,11 +1221,11 @@ print_ip6cp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; @@ -1198,17 +1236,17 @@ trunc: /* CCP config options */ -static int +static u_int print_ccp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = EXTRACT_U_1(p); + len = EXTRACT_U_1(p + 1); if (length < len) return 0; if (len < 2) { @@ -1230,31 +1268,35 @@ print_ccp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be >= 3)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK_1(p + 2); ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u", - p[2] >> 5, p[2] & 0x1f)); + EXTRACT_U_1(p + 2) >> 5, + EXTRACT_U_1(p + 2) & 0x1f)); break; case CCPOPT_MVRCA: if (len < 4) { ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK_1(p + 3); ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u", - (p[2] & 0xc0) >> 6, - (p[2] & 0x20) ? "Enabled" : "Disabled", - p[2] & 0x1f, p[3])); + (EXTRACT_U_1(p + 2) & 0xc0) >> 6, + (EXTRACT_U_1(p + 2) & 0x20) ? "Enabled" : "Disabled", + EXTRACT_U_1(p + 2) & 0x1f, + EXTRACT_U_1(p + 3))); break; case CCPOPT_DEFLATE: if (len < 4) { ND_PRINT((ndo, " (length bogus, should be >= 4)")); return len; } - ND_TCHECK2(*(p + 2), 1); + ND_TCHECK_1(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, (p[3] & 0xfc) >> 2, p[3] & 0x03)); + (EXTRACT_U_1(p + 2) & 0xf0) >> 4, + ((EXTRACT_U_1(p + 2) & 0x0f) == 8) ? "zlib" : "unknown", + EXTRACT_U_1(p + 2) & 0x0f, + (EXTRACT_U_1(p + 3) & 0xfc) >> 2, + EXTRACT_U_1(p + 3) & 0x03)); break; /* XXX: to be supported */ @@ -1279,11 +1321,11 @@ print_ccp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; @@ -1293,17 +1335,17 @@ trunc: } /* BACP config options */ -static int +static u_int print_bacp_config_options(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { - int len, opt; + u_int opt, len; if (length < 2) return 0; - ND_TCHECK2(*p, 2); - len = p[1]; - opt = p[0]; + ND_TCHECK_2(p); + opt = EXTRACT_U_1(p); + len = EXTRACT_U_1(p + 1); if (length < len) return 0; if (len < 2) { @@ -1325,8 +1367,8 @@ print_bacp_config_options(netdissect_options *ndo, ND_PRINT((ndo, " (length bogus, should be = 6)")); return len; } - ND_TCHECK2(*(p + 2), 4); - ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2))); + ND_TCHECK_4(p + 2); + ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_BE_U_4(p + 2))); break; default: /* @@ -1334,11 +1376,11 @@ print_bacp_config_options(netdissect_options *ndo, * not going to do so below. */ if (ndo->ndo_vflag < 2) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) - print_unknown_data(ndo, &p[2], "\n\t ", len - 2); /* exclude TLV header */ + print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; @@ -1349,14 +1391,14 @@ trunc: static void ppp_hdlc(netdissect_options *ndo, - const u_char *p, int length) + const u_char *p, u_int length) { u_char *b, *t, c; const u_char *s; - int i, proto; + u_int i, proto; const void *se; - if (length <= 0) + if (length == 0) return; b = (u_char *)malloc(length); @@ -1368,17 +1410,22 @@ ppp_hdlc(netdissect_options *ndo, * Do this so that we dont overwrite the original packet * contents. */ - for (s = p, t = b, i = length; i > 0 && ND_TTEST(*s); i--) { - c = *s++; + for (s = p, t = b, i = length; i != 0 && ND_TTEST_1(s); i--) { + c = EXTRACT_U_1(s); + s++; if (c == 0x7d) { - if (i <= 1 || !ND_TTEST(*s)) + if (i <= 1 || !ND_TTEST_1(s)) break; i--; - c = *s++ ^ 0x20; + c = EXTRACT_U_1(s) ^ 0x20; + s++; } *t++ = c; } + /* + * Change the end pointer, so bounds checks work. + */ se = ndo->ndo_snapend; ndo->ndo_snapend = t; length = t - b; @@ -1386,7 +1433,7 @@ ppp_hdlc(netdissect_options *ndo, /* now lets guess about the payload codepoint format */ if (length < 1) goto trunc; - proto = *b; /* start with a one-octet codepoint guess */ + proto = EXTRACT_U_1(b); /* start with a one-octet codepoint guess */ switch (proto) { case PPP_IP: @@ -1401,13 +1448,13 @@ ppp_hdlc(netdissect_options *ndo, if (length < 2) goto trunc; - proto = EXTRACT_16BITS(b); /* next guess - load two octets */ + proto = EXTRACT_BE_U_2(b); /* next guess - load two octets */ switch (proto) { case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */ if (length < 4) goto trunc; - proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */ + proto = EXTRACT_BE_U_2(b + 2); /* load the PPP proto-id */ handle_ppp(ndo, proto, b + 4, length - 4); break; default: /* last guess - proto must be a PPP proto-id */ @@ -1430,7 +1477,7 @@ trunc: /* PPP */ static void handle_ppp(netdissect_options *ndo, - u_int proto, const u_char *p, int length) + u_int proto, const u_char *p, u_int length) { if ((proto & 0xff00) == 0x7e00) { /* is this an escape code ? */ ppp_hdlc(ndo, p - 1, length); @@ -1473,7 +1520,7 @@ handle_ppp(netdissect_options *ndo, 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: @@ -1492,7 +1539,7 @@ handle_ppp(netdissect_options *ndo, /* Standard PPP printer */ u_int ppp_print(netdissect_options *ndo, - register const u_char *p, u_int length) + const u_char *p, u_int length) { u_int proto,ppp_header; u_int olen = length; /* _o_riginal length */ @@ -1504,8 +1551,8 @@ ppp_print(netdissect_options *ndo, */ if (length < 2) goto trunc; - ND_TCHECK2(*p, 2); - ppp_header = EXTRACT_16BITS(p); + ND_TCHECK_2(p); + ppp_header = EXTRACT_BE_U_2(p); switch(ppp_header) { case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL): @@ -1532,15 +1579,15 @@ ppp_print(netdissect_options *ndo, if (length < 2) goto trunc; - ND_TCHECK(*p); - if (*p % 2) { - proto = *p; /* PFC is used */ + ND_TCHECK_1(p); + if (EXTRACT_U_1(p) % 2) { + proto = EXTRACT_U_1(p); /* PFC is used */ p++; length--; hdr_len++; } else { - ND_TCHECK2(*p, 2); - proto = EXTRACT_16BITS(p); + ND_TCHECK_2(p); + proto = EXTRACT_BE_U_2(p); p += 2; length -= 2; hdr_len += 2; @@ -1563,10 +1610,10 @@ trunc: /* PPP I/F printer */ u_int ppp_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; + u_int length = h->len; + u_int caplen = h->caplen; if (caplen < PPP_HDRLEN) { ND_PRINT((ndo, "[|ppp]")); @@ -1611,7 +1658,8 @@ ppp_if_print(netdissect_options *ndo, * BSD/OS, is?) */ if (ndo->ndo_eflag) - ND_PRINT((ndo, "%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1])); + ND_PRINT((ndo, "%c %4d %02x ", EXTRACT_U_1(p) ? 'O' : 'I', + length, EXTRACT_U_1(p + 1))); #endif ppp_print(ndo, p, length); @@ -1630,10 +1678,10 @@ ppp_if_print(netdissect_options *ndo, */ u_int ppp_hdlc_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, register const u_char *p) + const struct pcap_pkthdr *h, const u_char *p) { - register u_int length = h->len; - register u_int caplen = h->caplen; + u_int length = h->len; + u_int caplen = h->caplen; u_int proto; u_int hdrlen = 0; @@ -1642,21 +1690,22 @@ ppp_hdlc_if_print(netdissect_options *ndo, return (caplen); } - switch (p[0]) { + switch (EXTRACT_U_1(p)) { case PPP_ADDRESS: - if (caplen < 4) { + if (caplen < 4 || length < 4) { ND_PRINT((ndo, "[|ppp]")); return (caplen); } if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x %02x %d ", p[0], p[1], length)); + ND_PRINT((ndo, "%02x %02x %u ", EXTRACT_U_1(p), + EXTRACT_U_1(p + 1), length)); p += 2; length -= 2; hdrlen += 2; - proto = EXTRACT_16BITS(p); + proto = EXTRACT_BE_U_2(p); p += 2; length -= 2; hdrlen += 2; @@ -1670,8 +1719,14 @@ 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)); + ND_PRINT((ndo, "%02x %02x %d ", EXTRACT_U_1(p), + EXTRACT_U_1(p + 1), length)); p += 2; hdrlen += 2; @@ -1680,7 +1735,8 @@ ppp_hdlc_if_print(netdissect_options *ndo, * the next two octets as an Ethernet type; does that * ever happen? */ - ND_PRINT((ndo, "unknown addr %02x; ctrl %02x", p[0], p[1])); + ND_PRINT((ndo, "unknown addr %02x; ctrl %02x", EXTRACT_U_1(p), + EXTRACT_U_1(p + 1))); break; } @@ -1692,15 +1748,16 @@ ppp_hdlc_if_print(netdissect_options *ndo, /* BSD/OS specific PPP printer */ u_int ppp_bsdos_if_print(netdissect_options *ndo _U_, - const struct pcap_pkthdr *h _U_, register const u_char *p _U_) + const struct pcap_pkthdr *h _U_, const u_char *p _U_) { - register int hdrlength; + u_int hdrlength; #ifdef __bsdi__ - register u_int length = h->len; - register u_int caplen = h->caplen; + u_int length = h->len; + u_int caplen = h->caplen; uint16_t ptype; + uint8_t llhl; const u_char *q; - int i; + u_int i; if (caplen < PPP_BSDI_HDRLEN) { ND_PRINT((ndo, "[|ppp]")); @@ -1710,9 +1767,11 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, hdrlength = 0; #if 0 - if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { + if (EXTRACT_U_1(p) == PPP_ADDRESS && + EXTRACT_U_1(p + 1) == PPP_CONTROL) { if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x %02x ", p[0], p[1])); + ND_PRINT((ndo, "%02x %02x ", EXTRACT_U_1(p), + EXTRACT_U_1(p + 1))); p += 2; hdrlength = 2; } @@ -1720,16 +1779,16 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, if (ndo->ndo_eflag) ND_PRINT((ndo, "%d ", length)); /* Retrieve the protocol type */ - if (*p & 01) { + if (EXTRACT_U_1(p) & 01) { /* Compressed protocol field */ - ptype = *p; + ptype = EXTRACT_U_1(p); if (ndo->ndo_eflag) ND_PRINT((ndo, "%02x ", ptype)); p++; hdrlength += 1; } else { /* Un-compressed protocol field */ - ptype = EXTRACT_16BITS(p); + ptype = EXTRACT_BE_U_2(p); if (ndo->ndo_eflag) ND_PRINT((ndo, "%04x ", ptype)); p += 2; @@ -1738,8 +1797,9 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, #else ptype = 0; /*XXX*/ if (ndo->ndo_eflag) - ND_PRINT((ndo, "%c ", p[SLC_DIR] ? 'O' : 'I')); - if (p[SLC_LLHL]) { + ND_PRINT((ndo, "%c ", EXTRACT_U_1(p + SLC_DIR) ? 'O' : 'I')); + llhl = EXTRACT_U_1(p + SLC_LLHL); + if (llhl) { /* link level header */ struct ppp_header *ph; @@ -1748,8 +1808,9 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, if (ph->phdr_addr == PPP_ADDRESS && ph->phdr_ctl == PPP_CONTROL) { if (ndo->ndo_eflag) - ND_PRINT((ndo, "%02x %02x ", q[0], q[1])); - ptype = EXTRACT_16BITS(&ph->phdr_type); + ND_PRINT((ndo, "%02x %02x ", EXTRACT_U_1(q), + EXTRACT_U_1(q + 1))); + ptype = EXTRACT_BE_U_2(&ph->phdr_type); if (ndo->ndo_eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) { ND_PRINT((ndo, "%s ", tok2str(ppptype2str, "proto-#%d", ptype))); @@ -1757,16 +1818,16 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, } else { if (ndo->ndo_eflag) { ND_PRINT((ndo, "LLH=[")); - for (i = 0; i < p[SLC_LLHL]; i++) - ND_PRINT((ndo, "%02x", q[i])); + for (i = 0; i < llhl; i++) + ND_PRINT((ndo, "%02x", EXTRACT_U_1(q + i))); ND_PRINT((ndo, "] ")); } } } if (ndo->ndo_eflag) ND_PRINT((ndo, "%d ", length)); - if (p[SLC_CHL]) { - q = p + SLC_BPFHDRLEN + p[SLC_LLHL]; + if (EXTRACT_U_1(p + SLC_CHL)) { + q = p + SLC_BPFHDRLEN + llhl; switch (ptype) { case PPP_VJC: @@ -1806,8 +1867,9 @@ ppp_bsdos_if_print(netdissect_options *ndo _U_, default: if (ndo->ndo_eflag) { ND_PRINT((ndo, "CH=[")); - for (i = 0; i < p[SLC_LLHL]; i++) - ND_PRINT((ndo, "%02x", q[i])); + for (i = 0; i < llhl; i++) + ND_PRINT((ndo, "%02x", + EXTRACT_U_1(q + i))); ND_PRINT((ndo, "] ")); } break;