X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/728fd81dac6cc1f1420c7836defc6b01e98c9f61..4c2790a43252b9cac1fe7f6b50b51c3c55d2370a:/print-pppoe.c diff --git a/print-pppoe.c b/print-pppoe.c index d7baa20d..bcc976c4 100644 --- a/print-pppoe.c +++ b/print-pppoe.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] _U_ = -"@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.29 2004-08-27 03:28:58 guy Exp $ (LBL)"; +"@(#) $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,9 +103,15 @@ 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; + 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; @@ -113,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); } @@ -127,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; @@ -155,11 +147,10 @@ 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);