X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/dc0522fcb14a434bd83a2629e231688019764619..4c2790a43252b9cac1fe7f6b50b51c3c55d2370a:/print-pppoe.c diff --git a/print-pppoe.c b/print-pppoe.c index ef031331..bcc976c4 100644 --- a/print-pppoe.c +++ b/print-pppoe.c @@ -22,8 +22,8 @@ */ #ifndef lint -static const char rcsid[] = -"@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.24 2003-07-01 08:36:53 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.31 2005-04-26 19:48:38 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -70,6 +70,7 @@ enum { PPPOE_AC_COOKIE = 0x0104, PPPOE_VENDOR = 0x0105, PPPOE_RELAY_SID = 0x0110, + PPPOE_MAX_PAYLOAD = 0x0120, PPPOE_SERVICE_NAME_ERROR = 0x0201, PPPOE_AC_SYSTEM_ERROR = 0x0202, PPPOE_GENERIC_ERROR = 0x0203 @@ -83,6 +84,7 @@ static struct tok pppoetag2str[] = { { PPPOE_AC_COOKIE, "AC-Cookie" }, { PPPOE_VENDOR, "Vendor-Specific" }, { PPPOE_RELAY_SID, "Relay-Session-ID" }, + { PPPOE_MAX_PAYLOAD, "PPP-Max-Payload" }, { PPPOE_SERVICE_NAME_ERROR, "Service-Name-Error" }, { PPPOE_AC_SYSTEM_ERROR, "AC-System-Error" }, { PPPOE_GENERIC_ERROR, "Generic-Error" }, @@ -101,15 +103,17 @@ pppoe_if_print(const struct pcap_pkthdr *h, register const u_char *p) u_int pppoe_print(register const u_char *bp, u_int length) { - u_short pppoe_ver, pppoe_type, pppoe_code, pppoe_sessionid, pppoe_length; + u_int16_t pppoe_ver, pppoe_type, pppoe_code, pppoe_sessionid; + u_int pppoe_length; const u_char *pppoe_packet, *pppoe_payload; - pppoe_packet = bp; - if (pppoe_packet > snapend) { - printf("[|pppoe]"); - return (PPPOE_HDRLEN); + if (length < PPPOE_HDRLEN) { + (void)printf("truncated-pppoe %u", length); + return (length); } - + length -= PPPOE_HDRLEN; + pppoe_packet = bp; + TCHECK2(*pppoe_packet, PPPOE_HDRLEN); pppoe_ver = (pppoe_packet[0] & 0xF0) >> 4; pppoe_type = (pppoe_packet[0] & 0x0F); pppoe_code = pppoe_packet[1]; @@ -117,11 +121,6 @@ pppoe_print(register const u_char *bp, u_int length) pppoe_length = EXTRACT_16BITS(pppoe_packet + 4); pppoe_payload = pppoe_packet + PPPOE_HDRLEN; - if (snapend < pppoe_payload) { - printf(" truncated PPPoE"); - return (PPPOE_HDRLEN); - } - if (pppoe_ver != 1) { printf(" [ver %d]",pppoe_ver); } @@ -131,27 +130,16 @@ pppoe_print(register const u_char *bp, u_int length) printf("PPPoE %s", tok2str(pppoecode2str, "PAD-%x", pppoe_code)); if (pppoe_code == PPPOE_PADI && pppoe_length > 1484 - PPPOE_HDRLEN) { - printf(" [len %d!]",pppoe_length); + printf(" [len %u!]",pppoe_length); + } + if (pppoe_length > length) { + printf(" [len %u > %u!]", pppoe_length, length); + pppoe_length = length; } if (pppoe_sessionid) { printf(" [ses 0x%x]", pppoe_sessionid); } - if (pppoe_payload + pppoe_length < snapend && snapend-pppoe_payload+14 > 64) { - /* (small packets are probably just padded up to the ethernet - minimum of 64 bytes) */ - printf(" [length %d (%d extra bytes)]", - pppoe_length, snapend - pppoe_payload - pppoe_length); -#if RESPECT_PAYLOAD_LENGTH - snapend = pppoe_payload+pppoe_length; -#else - /* Actual PPPoE implementations appear to ignore the payload - length and use the full ethernet frame anyways */ - pppoe_length = snapend-pppoe_payload; -#endif - - } - if (pppoe_code) { /* PPP session packets don't contain tags */ u_short tag_type = 0xffff, tag_len; @@ -159,11 +147,11 @@ pppoe_print(register const u_char *bp, u_int length) /* * loop invariant: - * p points to next tag, + * p points to current tag, * tag_type is previous tag or 0xffff for first iteration */ - while (tag_type && p + 4 < pppoe_payload + length && - p + 4 < snapend) { + while (tag_type && p < pppoe_payload + pppoe_length) { + TCHECK2(*p, 4); tag_type = EXTRACT_16BITS(p); tag_len = EXTRACT_16BITS(p + 2); p += 4; @@ -176,6 +164,7 @@ pppoe_print(register const u_char *bp, u_int length) unsigned tag_str_len = 0; /* TODO print UTF-8 decoded text */ + TCHECK2(*p, tag_len); for (v = p; v < p + tag_len && tag_str_len < MAXTAGPRINT-1; v++) if (*v >= 32 && *v < 127) { tag_str[tag_str_len++] = *v; @@ -196,7 +185,7 @@ pppoe_print(register const u_char *bp, u_int length) /* Print hex, not fast to abuse printf but this doesn't get used much */ printf(" [%s 0x", tok2str(pppoetag2str, "TAG-0x%x", tag_type)); for (v=p; v