Index: interface.h =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/interface.h,v retrieving revision 1.71 diff -u -p -r1.71 interface.h --- interface.h 6 Feb 2018 03:07:51 -0000 1.71 +++ interface.h 6 Feb 2018 19:53:05 -0000 @@ -182,7 +182,8 @@ struct pcap_pkthdr; extern int ether_encap_print(u_short, const u_char *, u_int, u_int); extern int llc_print(const u_char *, u_int, u_int, const u_char *, const u_char *); -extern int pppoe_if_print(u_short, const u_char *, u_int, u_int); +extern void pppoe_disc_print(const u_char *, u_int, u_int); +extern void pppoe_print(const u_char *, u_int, u_int); extern void aarp_print(const u_char *, u_int); extern void arp_print(const u_char *, u_int, u_int); extern void atalk_print(const u_char *, u_int); Index: print-ether.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-ether.c,v retrieving revision 1.31 diff -u -p -r1.31 print-ether.c --- print-ether.c 11 Jul 2016 00:27:50 -0000 1.31 +++ print-ether.c 6 Feb 2018 19:53:05 -0000 @@ -249,8 +249,10 @@ recurse: #ifdef PPP case ETHERTYPE_PPPOEDISC: + pppoe_disc_print(p, length, caplen); + return (1); case ETHERTYPE_PPPOE: - pppoe_if_print(ethertype, p, length, caplen); + pppoe_print(p, length, caplen); return (1); #endif Index: print-ppp.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-ppp.c,v retrieving revision 1.32 diff -u -p -r1.32 print-ppp.c --- print-ppp.c 6 Feb 2018 03:41:58 -0000 1.32 +++ print-ppp.c 6 Feb 2018 19:53:05 -0000 @@ -1171,7 +1171,6 @@ ppp_if_print(u_char *user, const struct void ppp_ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { - u_int16_t pppoe_sid, pppoe_len; u_int l = h->caplen; u_int length = h->len; @@ -1180,192 +1179,213 @@ ppp_ether_if_print(u_char *user, const s ts_print(&h->ts); - if (eflag) - printf("PPPoE "); - - if (l < sizeof(struct pppoe_header)) { - printf("[|pppoe]"); - return; - } + pppoe_print(p, length, l); - pppoe_sid = EXTRACT_16BITS(p + 2); - pppoe_len = EXTRACT_16BITS(p + 4); - - if (eflag) { - printf("\n\tcode "); - switch (p[1]) { - case PPPOE_CODE_PADI: - printf("Initiation"); - break; - case PPPOE_CODE_PADO: - printf("Offer"); - break; - case PPPOE_CODE_PADR: - printf("Request"); - break; - case PPPOE_CODE_PADS: - printf("Confirm"); - break; - case PPPOE_CODE_PADT: - printf("Terminate"); - break; - case PPPOE_CODE_SESSION: - printf("Session"); - break; - default: - printf("Unknown(0x%02x)", p[1]); - break; - } - printf(", version %d, type %d, id 0x%04x, length %d\n\t", - (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len); - } + if (xflag) + default_print(p, l); - if (length < pppoe_len) { - (void)printf(" truncated-pppoe - %d bytes missing!", - pppoe_len - length); - pppoe_len = length; - } + putchar('\n'); +} - ppp_print(p + sizeof(struct pppoe_header), pppoe_len); +static int +pppoe_header_read(struct pppoe_header *ph, const u_char *p, u_int l) +{ + if (l < sizeof(*ph)) + return (-1); - if (xflag) - default_print(p, h->caplen); + ph->vertype = *(p + 0); + ph->code = *(p + 1); + ph->sessionid = EXTRACT_16BITS(p + 2); + ph->len = EXTRACT_16BITS(p + 4); - putchar('\n'); + return (0); } -int -pppoe_if_print(u_short ethertype, const u_char *p, u_int length, u_int l) +void +pppoe_disc_print(const u_char *p, u_int length, u_int l) { - uint16_t pppoe_sid, pppoe_len; + struct pppoe_header ph; + uint8_t ver, type; + const char *code; - if (ethertype == ETHERTYPE_PPPOEDISC) - printf("PPPoE-Discovery"); - else - printf("PPPoE-Session"); + printf("PPPoE-Discovery"); - if (l < sizeof(struct pppoe_header)) + if (pppoe_header_read(&ph, p, l) == -1) goto trunc; - printf("\n\tcode "); - switch (p[1]) { + ver = ph.vertype >> 4; + if (ver != 0x1) { + printf(" pppoe-version != %u! (%u)", 0x1, ver); + return; + } + type = ph.vertype & 0x0f; + if (type != 0x1) { + printf(" pppoe-type != %u! (%u)", 0x1, type); + return; + } + + switch (ph.code) { case PPPOE_CODE_PADI: - printf("Initiation"); + code = "Initiation"; break; case PPPOE_CODE_PADO: - printf("Offer"); + code = "Offer"; break; case PPPOE_CODE_PADR: - printf("Request"); + code = "Request"; break; case PPPOE_CODE_PADS: - printf("Confirm"); + code = "Confirm"; break; case PPPOE_CODE_PADT: - printf("Terminate"); + code = "Terminate"; break; case PPPOE_CODE_SESSION: - printf("Session"); - break; + printf(" Session!"); + return; default: - printf("Unknown(0x%02x)", p[1]); - break; + printf(" pppoe-code=0x%02x!", ph.code); + return; + } + printf(" %s", code); + + if (vflag) + printf(" ver=%u type=%u", ver, type); + + printf(" sid=0x%04x", ph.sessionid); + if (vflag) + printf(" len=%u", ph.len); + + if (length < ph.len) { + (void)printf(" truncated-pppoe - %d bytes missing!", + ph.len - length); + ph.len = length; } - pppoe_sid = EXTRACT_16BITS(p + 2); - pppoe_len = EXTRACT_16BITS(p + 4); - printf(", version %d, type %d, id 0x%04x, length %d", - (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len); - - p += sizeof(struct pppoe_header); - l -= sizeof(struct pppoe_header); - length -= sizeof(struct pppoe_header); - - if (length < pppoe_len) { - (void)printf(" truncated-pppoe - %d bytes missing!", - pppoe_len - length); - pppoe_len = length; - } - - if (l > pppoe_len) - l = pppoe_len; - - if (ethertype == ETHERTYPE_PPPOEDISC) { - while (l > 0) { - u_int16_t t_type, t_len; - - if (l < 4) - goto trunc; - t_type = EXTRACT_16BITS(p); - t_len = EXTRACT_16BITS(p + 2); - - p += 4; - l -= 4; - - if (l < t_len) - goto trunc; - - printf("\n\ttag "); - switch (t_type) { - case PPPOE_TAG_END_OF_LIST: - printf("End-Of-List"); - break; - case PPPOE_TAG_SERVICE_NAME: - printf("Service-Name"); - break; - case PPPOE_TAG_AC_NAME: - printf("AC-Name"); - break; - case PPPOE_TAG_HOST_UNIQ: - printf("Host-Uniq"); - break; - case PPPOE_TAG_AC_COOKIE: - printf("AC-Cookie"); - break; - case PPPOE_TAG_VENDOR_SPEC: - printf("Vendor-Specific"); - break; - case PPPOE_TAG_RELAY_SESSION: - printf("Relay-Session"); - break; - case PPPOE_TAG_MAX_PAYLOAD: - printf("PPP-Max-Payload"); - break; - case PPPOE_TAG_SERVICE_NAME_ERROR: - printf("Service-Name-Error"); - break; - case PPPOE_TAG_AC_SYSTEM_ERROR: - printf("AC-System-Error"); - break; - case PPPOE_TAG_GENERIC_ERROR: - printf("Generic-Error"); - break; - default: - printf("Unknown(0x%04x)", t_type); - } - printf(", length %u%s", t_len, t_len ? " " : ""); - - if (t_len) { - for (t_type = 0; t_type < t_len; t_type++) { - if (isprint(p[t_type])) - printf("%c", p[t_type]); - else - printf("\\%03o", p[t_type]); - } - } - p += t_len; - l -= t_len; + p += sizeof(ph); + l -= sizeof(ph); + + if (l > ph.len) + l = ph.len; + + while (l > 0) { + u_int16_t t_type, t_len; + + if (l < 4) + goto trunc; + t_type = EXTRACT_16BITS(p); + t_len = EXTRACT_16BITS(p + 2); + + p += 4; + l -= 4; + + if (l < t_len) + goto trunc; + + printf("\n\ttag "); + switch (t_type) { + case PPPOE_TAG_END_OF_LIST: + printf("End-Of-List"); + break; + case PPPOE_TAG_SERVICE_NAME: + printf("Service-Name"); + break; + case PPPOE_TAG_AC_NAME: + printf("AC-Name"); + break; + case PPPOE_TAG_HOST_UNIQ: + printf("Host-Uniq"); + break; + case PPPOE_TAG_AC_COOKIE: + printf("AC-Cookie"); + break; + case PPPOE_TAG_VENDOR_SPEC: + printf("Vendor-Specific"); + break; + case PPPOE_TAG_RELAY_SESSION: + printf("Relay-Session"); + break; + case PPPOE_TAG_MAX_PAYLOAD: + printf("PPP-Max-Payload"); + break; + case PPPOE_TAG_SERVICE_NAME_ERROR: + printf("Service-Name-Error"); + break; + case PPPOE_TAG_AC_SYSTEM_ERROR: + printf("AC-System-Error"); + break; + case PPPOE_TAG_GENERIC_ERROR: + printf("Generic-Error"); + break; + default: + printf("Unknown(0x%04x)", t_type); + } + + if (t_len) { + int i; + putchar('='); + for (i = 0; i < t_len; i++) + safeputchar(p[i]); } - } else if (ethertype == ETHERTYPE_PPPOE) { - printf("\n\t"); - ppp_print(p, pppoe_len); + + p += t_len; + l -= t_len; + } + return; + +trunc: + printf("[!pppoe]"); +} + +void +pppoe_print(const u_char *p, u_int length, u_int l) +{ + struct pppoe_header ph; + uint8_t ver, type; + + if (eflag) + printf("PPPoE "); + + if (pppoe_header_read(&ph, p, l) == -1) + goto trunc; + + ver = ph.vertype >> 4; + if (ver != 0x1) { + printf("pppoe-version (%u) != %u!", ver, 0x1); + return; + } + type = ph.vertype & 0x0f; + if (type != 0x1) { + printf("pppoe-type (%u) != %u", type, 0x1); + return; + } + + if (ph.code != PPPOE_CODE_SESSION) { + printf("pppoe-code (%u) != %u!", ph.code, PPPOE_CODE_SESSION); + return; + } + + if (eflag) { + if (vflag) + printf("ver=%u type=%u code=Session ", ver, type); + printf("sid=0x%04x", ph.sessionid); + if (vflag) + printf(" len=%u", ph.len); + printf(": "); } - return (1); + if (length < ph.len) { + (void)printf("truncated-pppoe - %d bytes missing! ", + ph.len - length); + ph.len = length; + } + + ppp_print(p + sizeof(ph), ph.len); + + return; trunc: printf("[|pppoe]"); - return (1); } void