Index: lib/libpcap/gencode.c =================================================================== RCS file: /cvs/src/lib/libpcap/gencode.c,v retrieving revision 1.47 diff -u -p -r1.47 gencode.c --- lib/libpcap/gencode.c 3 Feb 2018 13:39:48 -0000 1.47 +++ lib/libpcap/gencode.c 5 Feb 2018 06:08:37 -0000 @@ -707,6 +707,11 @@ init_linktype(type) off_nl = 4; return; + case DLT_PPP_SERIAL: + off_linktype = -1; + off_nl = 2; + return; + case DLT_PPP_ETHER: /* * This does not include the Ethernet header, and Index: lib/libpcap/pcap.c =================================================================== RCS file: /cvs/src/lib/libpcap/pcap.c,v retrieving revision 1.21 diff -u -p -r1.21 pcap.c --- lib/libpcap/pcap.c 3 Feb 2018 13:39:48 -0000 1.21 +++ lib/libpcap/pcap.c 5 Feb 2018 06:08:37 -0000 @@ -313,6 +313,7 @@ DLT_CHOICE(DLT_IEEE802, "IEEE 802 Networ DLT_CHOICE(DLT_ARCNET, "ARCNET"), DLT_CHOICE(DLT_SLIP, "Serial Line IP"), DLT_CHOICE(DLT_PPP, "Point-to-point Protocol"), +DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), DLT_CHOICE(DLT_FDDI, "FDDI"), DLT_CHOICE(DLT_ATM_RFC1483, "LLC/SNAP encapsulated atm"), DLT_CHOICE(DLT_LOOP, "loopback type (af header)"), Index: lib/libpcap/shlib_version =================================================================== RCS file: /cvs/src/lib/libpcap/shlib_version,v retrieving revision 1.17 diff -u -p -r1.17 shlib_version --- lib/libpcap/shlib_version 29 Nov 2016 18:37:02 -0000 1.17 +++ lib/libpcap/shlib_version 5 Feb 2018 06:08:37 -0000 @@ -1,2 +1,2 @@ major=8 -minor=3 +minor=4 Index: usr.sbin/tcpdump/interface.h =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/interface.h,v retrieving revision 1.70 diff -u -p -r1.70 interface.h --- usr.sbin/tcpdump/interface.h 3 Feb 2018 13:39:48 -0000 1.70 +++ usr.sbin/tcpdump/interface.h 5 Feb 2018 06:08:37 -0000 @@ -244,7 +244,10 @@ extern void ospf_print(const u_char *, u extern void mobile_print(const u_char *, u_int); extern void pim_print(const u_char *, u_int); extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); -extern void ppp_hdlc_print(const u_char *, int); +extern void ppp_hdlc_if_print(u_char *, const struct pcap_pkthdr *, + const u_char *); +extern void ppp_print(const u_char *, u_int); +extern void ppp_hdlc_print(const u_char *, u_int); extern void raw_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); extern void rip_print(const u_char *, u_int); extern void sl_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); Index: usr.sbin/tcpdump/print-gre.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-gre.c,v retrieving revision 1.12 diff -u -p -r1.12 print-gre.c --- usr.sbin/tcpdump/print-gre.c 13 Dec 2016 06:40:21 -0000 1.12 +++ usr.sbin/tcpdump/print-gre.c 5 Feb 2018 06:08:37 -0000 @@ -73,25 +73,25 @@ void gre_sre_ip_print(u_int8_t, u_int8_t void gre_sre_asn_print(u_int8_t, u_int8_t, const u_char *, u_int); void -gre_print(const u_char *bp, u_int length) +gre_print(const u_char *p, u_int length) { - u_int len = length, vers; + uint16_t vers; + int l; - if (bp + len > snapend) - len = snapend - bp; + l = snapend - p; - if (len < 2) { + if (l < sizeof(vers)) { printf("[|gre]"); return; } - vers = EXTRACT_16BITS(bp) & GRE_VERS; + vers = EXTRACT_16BITS(p) & GRE_VERS; switch (vers) { case 0: - gre_print_0(bp, len); + gre_print_0(p, length); break; case 1: - gre_print_1(bp, len); + gre_print_1(p, length); break; default: printf("gre-unknown-version=%u", vers); @@ -100,14 +100,22 @@ gre_print(const u_char *bp, u_int length } void -gre_print_0(const u_char *bp, u_int length) +gre_print_0(const u_char *p, u_int length) { - u_int len = length; - u_int16_t flags, prot; + uint16_t flags, proto; + u_int l; + + l = snapend - p; + + flags = EXTRACT_16BITS(p); + p += sizeof(flags); + l -= sizeof(flags); + length -= sizeof(flags); + + printf("gre"); - flags = EXTRACT_16BITS(bp); if (vflag) { - printf("[%s%s%s%s%s] ", + printf(" [%s%s%s%s%s]", (flags & GRE_CP) ? "C" : "", (flags & GRE_RP) ? "R" : "", (flags & GRE_KP) ? "K" : "", @@ -115,57 +123,54 @@ gre_print_0(const u_char *bp, u_int leng (flags & GRE_sP) ? "s" : ""); } - len -= 2; - bp += 2; - - if (len < 2) + if (l < sizeof(proto)) goto trunc; - prot = EXTRACT_16BITS(bp); - printf("%s", etherproto_string(prot)); - - len -= 2; - bp += 2; + proto = EXTRACT_16BITS(p); + p += sizeof(proto); + l -= sizeof(proto); + length -= sizeof(proto); if ((flags & GRE_CP) | (flags & GRE_RP)) { - if (len < 2) + if (l < 2) goto trunc; - if (vflag) - printf(" sum 0x%x", EXTRACT_16BITS(bp)); - bp += 2; - len -= 2; - - if (len < 2) - goto trunc; - printf(" off 0x%x", EXTRACT_16BITS(bp)); - bp += 2; - len -= 2; + if ((flags & GRE_CP) && vflag) + printf(" sum 0x%x", EXTRACT_16BITS(p)); + p += 2; + l -= 2; + length -= 2; + + if (l < 2) + goto trunc; + if (flags & GRE_RP) + printf(" off 0x%x", EXTRACT_16BITS(p)); + p += 2; + l -= 2; + length -= 2; } if (flags & GRE_KP) { uint32_t key, vsid; - if (len < 4) + if (l < sizeof(key)) goto trunc; - key = EXTRACT_32BITS(bp); - - /* maybe NVGRE? */ - if (flags == (GRE_KP | 0) && prot == ETHERTYPE_TRANSETHER) { - vsid = (key & NVGRE_VSID_MASK) >> NVGRE_VSID_SHIFT; - printf(" NVGRE vsid=%u (0x%x)+flowid=0x%02x /", - vsid, vsid, - (key & NVGRE_FLOWID_MASK) >> NVGRE_FLOWID_SHIFT); - } - printf(" key=%u (0x%x)", key, key); - bp += 4; - len -= 4; + key = EXTRACT_32BITS(p); + p += sizeof(key); + l -= sizeof(key); + length -= sizeof(key); + + /* maybe NVGRE, or key entropy? */ + vsid = (key & NVGRE_VSID_MASK) >> NVGRE_VSID_SHIFT; + printf(" vsid=%u+flow=0x%02x/key=%u", + vsid, (key & NVGRE_FLOWID_MASK) >> NVGRE_FLOWID_SHIFT, key); } if (flags & GRE_SP) { - if (len < 4) + if (l < 4) goto trunc; - printf(" seq %u", EXTRACT_32BITS(bp)); - bp += 4; - len -= 4; + printf(" seq %u", EXTRACT_32BITS(p)); + p += 4; + l -= 4; + length -= 4; } if (flags & GRE_RP) { @@ -174,43 +179,45 @@ gre_print_0(const u_char *bp, u_int leng u_int8_t sreoff; u_int8_t srelen; - if (len < 4) + if (l < 4) goto trunc; - af = EXTRACT_16BITS(bp); - sreoff = *(bp + 2); - srelen = *(bp + 3); - bp += 4; - len -= 4; + af = EXTRACT_16BITS(p); + sreoff = *(p + 2); + srelen = *(p + 3); + p += 4; + l -= 4; + length -= 4; if (af == 0 && srelen == 0) break; - gre_sre_print(af, sreoff, srelen, bp, len); + gre_sre_print(af, sreoff, srelen, p, l); - if (len < srelen) + if (l < srelen) goto trunc; - bp += srelen; - len -= srelen; + p += srelen; + l -= srelen; + length -= srelen; } } - printf(": "); + printf(" "); - switch (prot) { + switch (proto) { case ETHERTYPE_IP: - ip_print(bp, len); + ip_print(p, length); break; case ETHERTYPE_IPV6: - ip6_print(bp, len); + ip6_print(p, length); break; case ETHERTYPE_MPLS: - mpls_print(bp, len); + mpls_print(p, length); break; case ETHERTYPE_TRANSETHER: - ether_print(bp, len); + ether_print(p, length); break; default: - printf("gre-proto-0x%x", prot); + printf("unknown-proto-%04x", proto); } return; @@ -219,17 +226,22 @@ trunc: } void -gre_print_1(const u_char *bp, u_int length) +gre_print_1(const u_char *p, u_int length) { - u_int len = length; - u_int16_t flags, prot; + uint16_t flags, proto, len; + int l; + + l = snapend - p; - flags = EXTRACT_16BITS(bp); - len -= 2; - bp += 2; + flags = EXTRACT_16BITS(p); + p += sizeof(flags); + l -= sizeof(flags); + length -= sizeof(flags); + + printf("pptp"); if (vflag) { - printf("[%s%s%s%s%s%s]", + printf(" [%s%s%s%s%s%s] ", (flags & GRE_CP) ? "C" : "", (flags & GRE_RP) ? "R" : "", (flags & GRE_KP) ? "K" : "", @@ -238,11 +250,13 @@ gre_print_1(const u_char *bp, u_int leng (flags & GRE_AP) ? "A" : ""); } - if (len < 2) + if (l < sizeof(proto)) goto trunc; - prot = EXTRACT_16BITS(bp); - len -= 2; - bp += 2; + + proto = EXTRACT_16BITS(p); + p += sizeof(proto); + l -= sizeof(proto); + length -= sizeof(proto); if (flags & GRE_CP) { printf(" cpset!"); @@ -261,52 +275,65 @@ gre_print_1(const u_char *bp, u_int leng return; } - if (flags & GRE_KP) { - u_int32_t k; + /* GRE_KP */ + if (l < sizeof(len)) + goto trunc; + len = EXTRACT_16BITS(p); + p += sizeof(len); + l -= sizeof(len); + length -= sizeof(len); - if (len < 4) - goto trunc; - k = EXTRACT_32BITS(bp); - printf(" call %d", k & 0xffff); - len -= 4; - bp += 4; - } + if (vflag) + printf(" len %u", EXTRACT_16BITS(p)); + + if (l < 2) + goto trunc; + printf(" callid %u", EXTRACT_16BITS(p)); + p += 2; + l -= 2; + length -= 2; if (flags & GRE_SP) { - if (len < 4) + if (l < 4) goto trunc; - printf(" seq %u", EXTRACT_32BITS(bp)); - bp += 4; - len -= 4; + printf(" seq %u", EXTRACT_32BITS(p)); + p += 4; + l -= 4; + length -= 4; } if (flags & GRE_AP) { - if (len < 4) + if (l < 4) goto trunc; - printf(" ack %u", EXTRACT_32BITS(bp)); - bp += 4; - len -= 4; + printf(" ack %u", EXTRACT_32BITS(p)); + p += 4; + l -= 4; + length -= 4; } - if ((flags & GRE_SP) == 0) { - printf(" no-payload"); + if ((flags & GRE_SP) == 0) return; + + if (length < len) { + (void)printf(" truncated-pptp - %d bytes missing!", + len - length); + len = length; } printf(": "); - switch (prot) { + switch (proto) { case ETHERTYPE_PPP: - printf("gre-ppp-payload"); + ppp_hdlc_print(p, len); break; default: - printf("gre-proto-0x%x", prot); + printf("unknown-proto-%04x", proto); break; } return; trunc: - printf("[|gre]"); + printf("[|pptp]"); } void Index: usr.sbin/tcpdump/print-ip.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-ip.c,v retrieving revision 1.47 diff -u -p -r1.47 print-ip.c --- usr.sbin/tcpdump/print-ip.c 30 Oct 2016 04:10:21 -0000 1.47 +++ usr.sbin/tcpdump/print-ip.c 5 Feb 2018 06:08:37 -0000 @@ -497,16 +497,11 @@ ip_print(const u_char *bp, u_int length) #define IPPROTO_GRE 47 #endif case IPPROTO_GRE: - if (vflag) - (void)printf("gre %s > %s: ", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); + (void)printf("%s > %s: ", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); /* do it */ gre_print(cp, len); - if (! vflag) { - printf(" (gre encap)"); - goto out; - } break; #ifndef IPPROTO_ESP Index: usr.sbin/tcpdump/print-ip6.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-ip6.c,v retrieving revision 1.24 diff -u -p -r1.24 print-ip6.c --- usr.sbin/tcpdump/print-ip6.c 13 Dec 2016 06:40:21 -0000 1.24 +++ usr.sbin/tcpdump/print-ip6.c 5 Feb 2018 06:08:37 -0000 @@ -190,10 +190,6 @@ ip6_print(const u_char *bp, u_int length #endif case IPPROTO_GRE: gre_print(cp, len); - if (! vflag) { - printf(" (gre encap)"); - goto out; - } goto end; case IPPROTO_NONE: Index: usr.sbin/tcpdump/print-ppp.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-ppp.c,v retrieving revision 1.30 diff -u -p -r1.30 print-ppp.c --- usr.sbin/tcpdump/print-ppp.c 25 Jul 2017 16:07:28 -0000 1.30 +++ usr.sbin/tcpdump/print-ppp.c 5 Feb 2018 06:08:37 -0000 @@ -48,30 +48,65 @@ struct rtentry; #include "addrtoname.h" #include "extract.h" +#ifndef nitems +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#endif + +#ifndef PPP_EAP +#define PPP_EAP 0xc227 +#endif + +#ifndef PPP_CDP +#define PPP_CDP 0x0207 +#endif + +#ifndef PPP_CDPCP +#define PPP_CDPCP 0x8207 +#endif + struct protonames { u_short protocol; char *name; }; -static struct protonames protonames[] = { +static const struct protonames protonames[] = { /* * Protocol field values. */ { PPP_IP, "IP" }, /* Internet Protocol */ { PPP_XNS, "XNS" }, /* Xerox NS */ { PPP_IPX, "IPX" }, /* IPX Datagram (RFC1552) */ + { PPP_AT, "AppleTalk" }, /* AppleTalk Protocol */ { PPP_VJC_COMP, "VJC_UNCOMP" }, /* VJ compressed TCP */ { PPP_VJC_UNCOMP,"VJC_UNCOMP" },/* VJ uncompressed TCP */ + { PPP_IPV6, "IPv6" }, /* Internet Protocol version 6 */ { PPP_COMP, "COMP" }, /* compressed packet */ { PPP_IPCP, "IPCP" }, /* IP Control Protocol */ + { PPP_ATCP, "AppleTalkCP" },/* AppleTalk Control Protocol */ { PPP_IPXCP, "IPXCP" }, /* IPX Control Protocol (RFC1552) */ { PPP_IPV6CP, "IPV6CP" }, /* IPv6 Control Protocol */ { PPP_CCP, "CCP" }, /* Compression Control Protocol */ { PPP_LCP, "LCP" }, /* Link Control Protocol */ { PPP_PAP, "PAP" }, /* Password Authentication Protocol */ { PPP_LQR, "LQR" }, /* Link Quality Report protocol */ + { PPP_CBCP, "CBCP" }, /* Callback Control Protocol */ { PPP_CHAP, "CHAP" }, /* Cryptographic Handshake Auth. Proto */ - { PPP_IPV6, "IPV6" }, /* Internet Protocol v6 */ + { PPP_EAP, "EAP" }, /* Extensible Auth. Protocol */ + { PPP_CDP, "CDP" }, + { PPP_CDPCP, "CDPCP" }, +}; + +struct ppp_control { + uint8_t code; + uint8_t id; + uint16_t len; +}; + +struct ppp_cp_type { + const char *unkname; + int mincode; + int maxcode; + const char **codes; }; /* LCP */ @@ -91,7 +126,7 @@ static struct protonames protonames[] = #define LCP_MIN LCP_CONF_REQ #define LCP_MAX LCP_DISC_REQ -static char *lcpcodes[] = { +static const char *lcpcodes[] = { /* * LCP code values (RFC1661, pp26) */ @@ -158,7 +193,7 @@ static char *lcpconfopts[] = { #define CHAP_CODEMIN 1 #define CHAP_CODEMAX 4 -static char *chapcode[] = { +static const char *chapcode[] = { "Challenge", "Response", "Success", @@ -174,12 +209,49 @@ static char *chapcode[] = { #define PAP_CODEMIN 1 #define PAP_CODEMAX 3 -static char *papcode[] = { +static const char *papcode[] = { "Authenticate-Request", "Authenticate-Ack", "Authenticate-Nak", }; +/* EAP */ + +#define EAP_CHAL 1 +#define EAP_RESP 2 +#define EAP_SUCC 3 +#define EAP_FAIL 4 + +#define EAP_CODEMIN EAP_CHAL +#define EAP_CODEMAX EAP_FAIL + +#define EAP_TYPE_IDENTITY 1 +#define EAP_TYPE_NOTIFICATION 2 +#define EAP_TYPE_NAK 3 +#define EAP_TYPE_MD5_CHALLENGE 4 +#define EAP_TYPE_OTP 5 +#define EAP_TYPE_TOKEN 6 + +#define EAP_TYPEMIN EAP_TYPE_IDENTITY +#define EAP_TYPEMAX EAP_TYPE_TOKEN + +static const char *eapcode[] = { + "Challenge", + "Response", + "Success", + "Failure", +}; + +static const char *eaptype[] = { + "Identity", + "Notification", + "Nak", + "MD5-Challenge", + "One-Time-Password", + "Token", +}; + + /* IPCP */ #define IPCP_CODE_CFG_REQ 1 @@ -212,12 +284,15 @@ static char *papcode[] = { #define IPV6CP_IFID 1 -static int print_lcp_config_options(u_char *p); -static void handle_lcp(const u_char *p, int length); -static void handle_chap(const u_char *p, int length); -static void handle_ipcp(const u_char *p, int length); -static void handle_ipv6cp(const u_char *p, int length); -static void handle_pap(const u_char *p, int length); +static int print_lcp_config_options(const u_char *p, int); +static void handle_lcp(const u_char *, int); +static void handle_chap(const u_char *p, int); +static void handle_eap(const u_char *p, int); +static void handle_ipcp(const u_char *p, int); +static int print_ipcp_config_options(const u_char *, int); +static void handle_ipv6cp(const u_char *p, int); +static int print_ipv6cp_config_options(const u_char *, int); +static void handle_pap(const u_char *p, int); struct pppoe_header { u_int8_t vertype; /* PPPoE version/type */ @@ -243,87 +318,162 @@ struct pppoe_header { #define PPPOE_TAG_AC_SYSTEM_ERROR 0x0202 /* Acc. Concentrator Error */ #define PPPOE_TAG_GENERIC_ERROR 0x0203 /* Generic Error */ -void -ppp_hdlc_print(p, length) - const u_char *p; - int length; +static void +ppp_protoname(uint16_t proto) { - int proto = PPP_PROTOCOL(p); + const struct protonames *protoname; int i; - for (i = sizeof(protonames) / sizeof(protonames[0]) - 1; i >= 0; i--) { - if (proto == protonames[i].protocol) { - printf("%s: ", protonames[i].name); + /* bsearch? */ + for (i = 0; i < nitems(protonames); i++) { + protoname = &protonames[i]; + + if (proto == protoname->protocol) { + printf("%s ", protoname->name); + return; + } + } - switch(proto) { + printf("unknown-ppp-%04x", proto); +} - case PPP_LCP: - handle_lcp(p, length); - break; - case PPP_CHAP: - handle_chap(p, length); - break; - case PPP_PAP: - handle_pap(p, length); - break; - case PPP_IPCP: - handle_ipcp(p, length); - break; - case PPP_IPV6CP: - handle_ipv6cp(p, length); - break; - } - break; - } +void +ppp_print(const u_char *p, u_int length) +{ + uint16_t proto; + int l; + + l = snapend - p; + + if (l < sizeof(proto)) { + printf("[|ppp]"); + return; } - if (i < 0) - printf("%04x: ", proto); + + proto = EXTRACT_16BITS(p); + + p += sizeof(proto); + l -= sizeof(proto); + length -= sizeof(proto); + + if (eflag) + ppp_protoname(proto); + + switch (proto) { + case PPP_IP: + ip_print(p, length); + return; + case PPP_IPV6: + ip6_print(p, length); + return; + } + + if (!eflag) + ppp_protoname(proto); + + switch(proto) { + case PPP_LCP: + handle_lcp(p, l); + break; + case PPP_CHAP: + handle_chap(p, l); + break; + case PPP_EAP: + handle_eap(p, l); + break; + case PPP_PAP: + handle_pap(p, l); + break; + case PPP_IPCP: + handle_ipcp(p, l); + break; + case PPP_IPV6CP: + handle_ipv6cp(p, l); + break; + } +} + +static int +ppp_cp_header(struct ppp_control *pc, const u_char *p, int l, + const struct ppp_cp_type *t) +{ + uint8_t code; + int off = 0; + int len; + + len = sizeof(pc->code); + if (l < len) + return (-1); + + pc->code = code = *(p + off); + if (code >= t->mincode && code <= t->maxcode) + printf("%s ", t->codes[code - 1]); + else + printf("unknown-%s-%u ", t->unkname, pc->code); + + off = len; + len += sizeof(pc->id); + if (l < len) + return (-1); + + pc->id = *(p + off); + printf("Id=0x%02x:", pc->id); + + off = len; + len += sizeof(pc->len); + if (l < len) + return (-1); + + pc->len = EXTRACT_16BITS(p + off); + + return (len); } /* print LCP frame */ +static const struct ppp_cp_type ppp_cp_lcp = { + "lcp", + LCP_MIN, LCP_MAX, + lcpcodes, +}; + static void -handle_lcp(p, length) - const u_char *p; - int length; -{ - int x, j; - u_char *ptr; - - TCHECK(*(p + 4)); - x = *(p + 4); - - if ((x >= LCP_MIN) && (x <= LCP_MAX)) - printf("%s", lcpcodes[x-1]); - else { - printf("0x%02x", x); - return; - } +handle_lcp(const u_char *p, int l) +{ + struct ppp_control pc; - length -= 4; - - switch(x) { + if (ppp_cp_header(&pc, p, l, &ppp_cp_lcp) == -1) + goto trunc; + if (l > pc.len) + l = pc.len; + + p += sizeof(pc); + l -= sizeof(pc); + + switch (pc.code) { case LCP_CONF_REQ: case LCP_CONF_ACK: case LCP_CONF_NAK: case LCP_CONF_REJ: - x = length; - ptr = (u_char *)p+8; - do { - if((j = print_lcp_config_options(ptr)) == 0) + while (l > 0) { + int optlen; + + optlen = print_lcp_config_options(p, l); + if (optlen == -1) + goto trunc; + if (optlen == 0) break; - x -= j; - ptr += j; + + p += optlen; + l -= optlen; } - while(x > 0); break; - case LCP_ECHO_REQ: case LCP_ECHO_RPL: - TCHECK2(*(p + 8), 4); - printf(", Magic-Number=%d", ((*(p+ 8) << 24) + (*(p+9) << 16) + - (*(p+10) << 8) + (*(p+11)))); + if (l < 4) + goto trunc; + printf(" Magic-Number=%u", EXTRACT_32BITS(p)); break; case LCP_TERM_REQ: case LCP_TERM_ACK: @@ -342,69 +492,111 @@ trunc: /* LCP config options */ static int -print_lcp_config_options(p) - u_char *p; +print_lcp_config_options(const u_char *p, int l) { - int len, opt; + uint8_t type, length; + uint16_t proto; + + if (l < sizeof(type)) + return (-1); - TCHECK2(*p, 2); - len = *(p+1); - opt = *p; + type = p[0]; + if (type <= LCPOPT_MAX) + printf(" %s", lcpconfopts[type]); + else + printf(" unknown-lcp-%u", type); + + if (l < sizeof(type) + sizeof(length)) + return (-1); + + length = p[1]; - if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) - printf(", %s", lcpconfopts[opt]); + if (length < sizeof(type) + sizeof(length)) + return (0); - switch(opt) { + if (l > length) + l = length; + + p += sizeof(type) + sizeof(length); + l -= sizeof(type) + sizeof(length); + + switch (type) { case LCPOPT_MRU: - if(len == 4) { - TCHECK2(*(p + 2), 2); - printf("=%d", (*(p+2) << 8) + *(p+3)); - } + if (length != 4) + goto invalid; + if (l < 2) + return (-1); + + printf("=%u", EXTRACT_16BITS(p)); break; case LCPOPT_AP: - if(len >= 4) { - TCHECK2(*(p + 2), 2); - if(*(p+2) == 0xc0 && *(p+3) == 0x23) - printf(" PAP"); - else if(*(p+2) == 0xc2 && *(p+3) == 0x23) { - printf(" CHAP/"); - TCHECK(*(p+4)); - switch(*(p+4)) { - default: - printf("unknown-algorithm-%d", *(p+4)); - break; - case 5: - printf("MD5"); - break; - case 0x80: - printf("Microsoft"); - break; - } - } else if(*(p+2) == 0xc2 && *(p+3) == 0x27) - printf(" EAP"); - else if(*(p+2) == 0xc0 && *(p+3) == 0x27) - printf(" SPAP"); - else if(*(p+2) == 0xc1 && *(p+3) == 0x23) - printf(" Old-SPAP"); - else - printf("unknown"); + if (length < 4) + goto invalid; + if (l < sizeof(proto)) + return (-1); + + proto = EXTRACT_16BITS(p); + switch (proto) { + case PPP_PAP: + printf("=PAP"); + break; + case PPP_CHAP: + printf("=CHAP"); + if (length < 5) + goto invalid; + + p += sizeof(proto); + l -= sizeof(proto); + + type = *p; + switch (type) { + case 0x05: + printf("/MD5"); + break; + case 0x80: + printf("/Microsoft"); + break; + default: + printf("/unknown-algorithm-%02x", type); + break; + } + break; + case PPP_EAP: + printf("=EAP"); + break; + case 0xc027: + printf("=SPAP"); + break; + case 0xc127: + printf("=Old-SPAP"); + break; + default: + printf("=unknown-ap-%04x", proto); + break; } break; case LCPOPT_QP: - if(len >= 4) { - TCHECK2(*(p + 2), 2); - if(*(p+2) == 0xc0 && *(p+3) == 0x25) - printf(" LQR"); - else - printf(" unknown"); + if (length < 4) + goto invalid; + if (l < sizeof(proto)) + return (-1); + + proto = EXTRACT_16BITS(p); + switch (proto) { + case PPP_LQR: + printf(" LQR"); + break; + default: + printf(" unknown-qp-%u", proto); } break; case LCPOPT_MN: - if(len == 6) { - TCHECK2(*(p + 2), 4); - printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) + - (*(p+4) << 8) + (*(p+5)))); - } + if (length < 6) + goto invalid; + if (l < 4) + return (-1); + + printf("=%u", EXTRACT_32BITS(p)); break; case LCPOPT_PFC: printf(" PFC"); @@ -413,51 +605,86 @@ print_lcp_config_options(p) printf(" ACFC"); break; } - return(len); -trunc: - printf("[|lcp]"); - return 0; + return (length); + +invalid: + printf(" invalid opt len %u", length); + return (length); } /* CHAP */ +static const struct ppp_cp_type ppp_cp_chap = { + "chap", + CHAP_CODEMIN, CHAP_CODEMAX, + chapcode, +}; + static void -handle_chap(p, length) - const u_char *p; - int length; -{ - int x; - u_char *ptr; - - TCHECK(*(p+4)); - x = *(p+4); - - if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX)) - printf("%s", chapcode[x-1]); - else { - printf("0x%02x", x); - return; - } +handle_chap(const u_char *p, int l) +{ + struct ppp_control pc; + uint8_t vsize; + int i; - length -= 4; - - switch(x) { + if (ppp_cp_header(&pc, p, l, &ppp_cp_chap) == -1) + goto trunc; + + if (l > pc.len) + l = pc.len; + + p += sizeof(pc); + l -= sizeof(pc); + + switch (pc.code) { case CHAP_CHAL: case CHAP_RESP: - printf(", Value="); - TCHECK(*(p+8)); - x = *(p+8); /* value size */ - ptr = (u_char *)p+9; - while(--x >= 0) { - TCHECK(*ptr); - printf("%02x", *ptr++); - } - x = length - *(p+8) - 1; - printf(", Name="); - while(--x >= 0) { - TCHECK(*ptr); - safeputchar(*ptr++); + if (l < sizeof(vsize)) + goto trunc; + + vsize = *p; + if (vsize < 1) { + printf(" invalid Value-Size"); + return; + } + + p += sizeof(vsize); + l -= sizeof(vsize); + + printf(" Value="); + for (i = 0; i < vsize; i++) { + if (l == 0) + goto trunc; + + printf("%02x", *p); + + p++; + l--; + } + + printf(" Name="); + for (i += sizeof(pc) + sizeof(vsize); i < pc.len; i++) { + if (l == 0) + goto trunc; + + safeputchar(*p); + + p++; + l--; + } + break; + case CHAP_SUCC: + case CHAP_FAIL: + printf(" Message="); + for (i = sizeof(pc); i < pc.len; i++) { + if (l == 0) + goto trunc; + + safeputchar(*p); + + p++; + l--; } break; } @@ -467,50 +694,195 @@ trunc: printf("[|chap]"); } -/* PAP */ +/* EAP */ + +static const struct ppp_cp_type ppp_cp_eap = { + "eap", + EAP_CODEMIN, EAP_CODEMAX, + eapcode, +}; static void -handle_pap(p, length) - const u_char *p; - int length; -{ - int x; - u_char *ptr; - - TCHECK(*(p+4)); - x = *(p+4); - - if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX)) - printf("%s", papcode[x-1]); - else { - printf("0x%02x", x); - return; +handle_eap(const u_char *p, int l) +{ + struct ppp_control pc; + uint8_t type, vsize; + int i; + + if (ppp_cp_header(&pc, p, l, &ppp_cp_eap) == -1) + goto trunc; + + if (l > pc.len) + l = pc.len; + + p += sizeof(pc); + l -= sizeof(pc); + + switch (pc.code) { + case EAP_CHAL: + case EAP_RESP: + if (l < sizeof(type)) + goto trunc; + + type = *p; + p += sizeof(type); + l -= sizeof(type); + + if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX) + printf(" %s", eaptype[type - 1]); + else { + printf(" unknown-eap-type-%u", type); + return; + } + + switch (type) { + case EAP_TYPE_IDENTITY: + case EAP_TYPE_NOTIFICATION: + case EAP_TYPE_OTP: + i = sizeof(pc) + sizeof(type); + if (i == pc.len) + break; + + printf("="); + do { + if (l == 0) + goto trunc; + + safeputchar(*p); + + p++; + l--; + } while (++i < pc.len); + break; + + case EAP_TYPE_NAK: + if (l < sizeof(type)) + goto trunc; + type = *p; + if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX) + printf(" %s", eaptype[type - 1]); + else + printf(" unknown-eap-type-%u", type); + break; + case EAP_TYPE_MD5_CHALLENGE: + if (l < sizeof(vsize)) + goto trunc; + + vsize = *p; + p += sizeof(vsize); + l -= sizeof(vsize); + + printf("="); + for (i = 0; i < vsize; i++) { + if (l == 0) + goto trunc; + + printf("%02x", *p); + + p++; + l--; + } + break; + } + break; + case CHAP_SUCC: + case CHAP_FAIL: + break; } + return; + +trunc: + printf("[|eap]"); +} + +/* PAP */ + +static const struct ppp_cp_type ppp_cp_pap = { + "pap", + PAP_CODEMIN, PAP_CODEMAX, + papcode, +}; + +static void +handle_pap(const u_char *p, int l) +{ + struct ppp_control pc; + uint8_t x; + int i; - length -= 4; + if (ppp_cp_header(&pc, p, l, &ppp_cp_pap) == -1) + goto trunc; - switch(x) { + if (l > pc.len) + l = pc.len; + + p += sizeof(pc); + l -= sizeof(pc); + + switch (pc.code) { case PAP_AREQ: - printf(", Peer-Id="); - TCHECK(*(p+8)); - x = *(p+8); /* peerid size */ - ptr = (u_char *)p+9; - while(--x >= 0) { - TCHECK(*ptr); - safeputchar(*ptr++); - } - TCHECK(*ptr); - x = *ptr++; - printf(", Passwd="); - while(--x >= 0) { - TCHECK(*ptr); - safeputchar(*ptr++); + if (l < sizeof(x)) /* Peer-ID Length */ + goto trunc; + + x = *p; + + p += sizeof(x); + l -= sizeof(x); + + printf(" Peer-Id="); + for (i = 0; i < x; i++) { + if (l == 0) + goto trunc; + + safeputchar(*p); + + p++; + l--; + } + + if (l < sizeof(x)) /* Passwd-Length */ + goto trunc; + + x = *p; + + p += sizeof(x); + l -= sizeof(x); + + printf(" Passwd="); + for (i = 0; i < x; i++) { + if (l == 0) + goto trunc; + + safeputchar(*p); + + p++; + l--; } break; + case PAP_AACK: - case PAP_ANAK: - break; + case PAP_ANAK: + if (l < sizeof(x)) /* Msg-Length */ + goto trunc; + + x = *p; + + p += sizeof(x); + l -= sizeof(x); + + printf(" Message="); + for (i = 0; i < x; i++) { + if (l == 0) + goto trunc; + + safeputchar(*p); + + p++; + l--; + } + break; } + return; trunc: @@ -519,187 +891,289 @@ trunc: /* IPCP */ +#define IP_LEN 4 +#define IP_FMT "%u.%u.%u.%u" +#define IP_ARG(_p) (_p)[0], (_p)[1], (_p)[2], (_p)[3] + +static const struct ppp_cp_type ppp_cp_ipcp = { + "ipcp", + IPCP_CODE_MIN, IPCP_CODE_MAX, + lcpcodes, +}; + static void -handle_ipcp(p, length) - const u_char *p; - int length; -{ - int x; - - TCHECK(*(p+4)); - x = *(p+4); - - if((x >= IPCP_CODE_MIN) && (x <= IPCP_CODE_MAX)) - printf("%s", lcpcodes[x-1]); /* share table with LCP */ - else { - printf("0x%02x", x); - return; +handle_ipcp(const u_char *p, int l) +{ + struct ppp_control pc; + + if (ppp_cp_header(&pc, p, l, &ppp_cp_ipcp) == -1) + goto trunc; + + if (l > pc.len) + l = pc.len; + + p += sizeof(pc); + l -= sizeof(pc); + + switch (pc.code) { + case IPCP_CODE_CFG_REQ: + case IPCP_CODE_CFG_ACK: + case IPCP_CODE_CFG_NAK: + case IPCP_CODE_CFG_REJ: + while (l > 0) { + int optlen; + + optlen = print_ipcp_config_options(p, l); + if (optlen == -1) + goto trunc; + if (optlen == 0) + break; + + p += optlen; + l -= optlen; + } + break; + + case IPCP_CODE_TRM_REQ: + case IPCP_CODE_TRM_ACK: + case IPCP_CODE_COD_REJ: + default: + break; } - length -= 4; + return; - TCHECK(*(p+8)); - switch(*(p+8)) { +trunc: + printf("[|ipcp]"); +} + +static int +print_ipcp_config_options(const u_char *p, int l) +{ + uint8_t type, length; + + if (l < sizeof(type)) + return (-1); + + type = p[0]; + switch (type) { case IPCP_2ADDR: - printf(", IP-Addresses"); - TCHECK2(*(p+10), 8); - printf(", Src=%d.%d.%d.%d", - *(p+10), *(p+11), *(p+12), *(p+13)); - printf(", Dst=%d.%d.%d.%d", - *(p+14), *(p+15), *(p+16), *(p+17)); + printf(" IP-Addresses"); break; - case IPCP_CP: - printf(", IP-Compression-Protocol"); + printf(" IP-Compression-Protocol"); break; - case IPCP_ADDR: - TCHECK2(*(p+10), 4); - printf(", IP-Address=%d.%d.%d.%d", - *(p+10), *(p+11), *(p+12), *(p+13)); + printf(" IP-Address"); break; default: - printf(", Unknown IPCP code 0x%x", *(p+8)); + printf(" ipcp-type-%u", type); break; } - return; -trunc: - printf("[|ipcp]"); + if (l < sizeof(type) + sizeof(length)) + return (-1); + + length = p[1]; + + p += (sizeof(type) + sizeof(length)); + l -= (sizeof(type) + sizeof(length)); + + switch (type) { + case IPCP_2ADDR: + if (length != 10) + goto invalid; + if (l < IP_LEN) + return (-1); + + printf(" Src=" IP_FMT, IP_ARG(p)); + + p += IP_LEN; + l -= IP_LEN; + + if (l < IP_LEN) + return (-1); + + printf(" Dst=" IP_FMT, IP_ARG(p)); + break; + case IPCP_CP: + if (length < 4) + goto invalid; + if (l < sizeof(type)) + return (-1); + + type = EXTRACT_16BITS(p); + switch (type) { + case 0x0037: + printf(" Van Jacobsen Compressed TCP/IP"); + break; + default: + printf("ipcp-compression-type-%u", type); + break; + } + break; + case IPCP_ADDR: + if (length != 6) + goto invalid; + if (l < IP_LEN) + return (-1); + + printf("=" IP_FMT, IP_ARG(p)); + break; + } + + return (length); + +invalid: + printf(" invalid opt len %u", length); + return (length); } /* IPV6CP */ +static const struct ppp_cp_type ppp_cp_ipv6cp = { + "ipv6cp", + IPV6CP_CODE_MIN, IPV6CP_CODE_MAX, + lcpcodes, +}; + static void -handle_ipv6cp(p, length) - const u_char *p; - int length; -{ - int x; - - TCHECK(*(p+4)); - x = *(p+4); - - if((x >= IPV6CP_CODE_MIN) && (x <= IPV6CP_CODE_MAX)) - printf("%s", lcpcodes[x-1]); /* share table with LCP */ - else { - printf("0x%02x", x); - return; - } +handle_ipv6cp(const u_char *p, int l) +{ + struct ppp_control pc; - TCHECK(*(p+8)); - switch(*(p+8)) { - case IPV6CP_IFID: - TCHECK2(*(p + 10), 8); - printf(", Interface-ID=%04x:%04x:%04x:%04x", - EXTRACT_16BITS(p + 10), - EXTRACT_16BITS(p + 12), - EXTRACT_16BITS(p + 14), - EXTRACT_16BITS(p + 16)); + if (ppp_cp_header(&pc, p, l, &ppp_cp_ipv6cp) == -1) + goto trunc; + + if (l > pc.len) + l = pc.len; + + p += sizeof(pc); + l -= sizeof(pc); + + switch (pc.code) { + case IPV6CP_CODE_CFG_REQ: + case IPV6CP_CODE_CFG_ACK: + case IPV6CP_CODE_CFG_NAK: + case IPV6CP_CODE_CFG_REJ: + while (l > 0) { + int optlen; + + optlen = print_ipv6cp_config_options(p, l); + if (optlen == -1) + goto trunc; + if (optlen == 0) + break; + + p += optlen; + l -= optlen; + } break; + case IPV6CP_CODE_TRM_REQ: + case IPV6CP_CODE_TRM_ACK: + case IPV6CP_CODE_COD_REJ: default: - printf(", Unknown IPV6CP code 0x%x", *(p+8)); break; } + return; trunc: printf("[|ipv6cp]"); } -void -ppp_if_print(user, h, p) - u_char *user; - const struct pcap_pkthdr *h; - const u_char *p; +static int +print_ipv6cp_config_options(const u_char *p, int l) { - u_int length = h->len; - u_int caplen = h->caplen; + uint8_t type, length; - ts_print(&h->ts); + if (l < sizeof(type)) + return (-1); - if (caplen < PPP_HDRLEN) { - printf("[|ppp]"); - goto out; + type = p[0]; + switch (type) { + case IPV6CP_IFID: + printf(" IPv6-Interface-Id"); + break; + default: + printf(" ipv6cp-type-%u", type); + break; } - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; + if (l < sizeof(type) + sizeof(length)) + return (-1); - if (eflag) - ppp_hdlc_print(p, length); + length = p[1]; - length -= PPP_HDRLEN; + p += (sizeof(type) + sizeof(length)); + l -= (sizeof(type) + sizeof(length)); - switch(PPP_PROTOCOL(p)) { - case PPP_IP: - case ETHERTYPE_IP: - ip_print((const u_char *)(p + PPP_HDRLEN), length); - break; - case PPP_IPV6: - case ETHERTYPE_IPV6: - ip6_print((const u_char *)(p + PPP_HDRLEN), length); + switch (type) { + case IPV6CP_IFID: + if (length != 10) + goto invalid; + if (l < 8) + return (-1); + + printf("=%04x:%04x:%04x:%04x", EXTRACT_16BITS(p + 0), + EXTRACT_16BITS(p + 2), EXTRACT_16BITS(p + 4), + EXTRACT_16BITS(p + 6)); break; - case PPP_IPX: - case ETHERTYPE_IPX: - ipx_print((const u_char *)(p + PPP_HDRLEN), length); + default: break; + } -#ifndef PPP_MPLS -#define PPP_MPLS 0x0281 -#endif - case PPP_MPLS: - mpls_print((const u_char *)(p + PPP_HDRLEN), length); - break; + return (length); +invalid: + printf(" invalid opt len %u", length); + return (length); +} - default: - if(!eflag) - ppp_hdlc_print(p, length); - if(!xflag) - default_print((const u_char *)(p + PPP_HDRLEN), - caplen - PPP_HDRLEN); - } +void +ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + + packetp = p; + snapend = p + caplen; + + ts_print(&h->ts); + + ppp_hdlc_print(p, length); if (xflag) default_print((const u_char *)(p + PPP_HDRLEN), - caplen - PPP_HDRLEN); -out: + caplen - PPP_HDRLEN); + putchar('\n'); } void -ppp_ether_if_print(user, h, p) - u_char *user; - const struct pcap_pkthdr *h; - const u_char *p; +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 caplen = h->caplen; - u_int16_t length = h->len; - u_int16_t proto; - int i; - - ts_print(&h->ts); + u_int l = h->caplen; + u_int length = h->len; packetp = p; - snapend = p + caplen; + snapend = p + l; + + ts_print(&h->ts); if (eflag) printf("PPPoE "); - if (caplen < sizeof(struct pppoe_header)) { + if (l < sizeof(struct pppoe_header)) { printf("[|pppoe]"); return; } - if(eflag) - { + pppoe_sid = EXTRACT_16BITS(p + 2); + pppoe_len = EXTRACT_16BITS(p + 4); + + if (eflag) { printf("\n\tcode "); switch (p[1]) { case PPPOE_CODE_PADI: @@ -724,82 +1198,36 @@ ppp_ether_if_print(user, h, p) printf("Unknown(0x%02x)", p[1]); break; } - } - - pppoe_sid = EXTRACT_16BITS(p + 2); - pppoe_len = EXTRACT_16BITS(p + 4); - - if(eflag) - printf(", version %d, type %d, id 0x%04x, length %d", + printf(", version %d, type %d, id 0x%04x, length %d\n\t", (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len); - - length -= sizeof(struct pppoe_header); - caplen -= sizeof(struct pppoe_header); - p += sizeof(struct pppoe_header); - - if (pppoe_len > caplen) - pppoe_len = caplen; - - if (pppoe_len < 2) { - printf("[|pppoe]"); - return; } - proto = EXTRACT_16BITS(p); - for (i = sizeof(protonames)/sizeof(protonames[0]) - 1; i >= 0; i--) { - if (proto == protonames[i].protocol) { - if (eflag) - printf("\n\t%s: ", protonames[i].name); - switch (proto) { - case PPP_LCP: - handle_lcp(p - 2, length + 2); - break; - case PPP_CHAP: - handle_chap(p - 2, length + 2); - break; - case PPP_PAP: - handle_pap(p - 2, length + 2); - break; - case PPP_IPCP: - handle_ipcp(p - 2, length + 2); - break; - case PPP_IPV6CP: - handle_ipv6cp(p - 2, length + 2); - break; - case PPP_IP: - ip_print(p + 2, length - 2); - break; - case PPP_IPV6: - ip6_print(p + 2, length - 2); - break; - case PPP_IPX: - ipx_print(p + 2, length - 2); - } - break; - } - } - if (i < 0) - printf("\n\t%04x: ", proto); + if (length < pppoe_len) { + (void)printf(" truncated-pppoe - %d bytes missing!", + pppoe_len - length); + pppoe_len = length; + } + + ppp_print(p + sizeof(struct pppoe_header), pppoe_len); if (xflag) - default_print(p + 2, caplen - 2); + default_print(p, h->caplen); + putchar('\n'); } int -pppoe_if_print(u_short ethertype, const u_char *p, u_int length, u_int caplen) +pppoe_if_print(u_short ethertype, const u_char *p, u_int length, u_int l) { - u_int16_t pppoe_sid, pppoe_len; + uint16_t pppoe_sid, pppoe_len; if (ethertype == ETHERTYPE_PPPOEDISC) printf("PPPoE-Discovery"); else printf("PPPoE-Session"); - if (caplen < sizeof(struct pppoe_header)) { - printf("[|pppoe]"); - return (1); - } + if (l < sizeof(struct pppoe_header)) + goto trunc; printf("\n\tcode "); switch (p[1]) { @@ -831,31 +1259,33 @@ pppoe_if_print(u_short ethertype, const printf(", version %d, type %d, id 0x%04x, length %d", (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len); - length -= sizeof(struct pppoe_header); - caplen -= sizeof(struct pppoe_header); 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 (pppoe_len > caplen) - pppoe_len = caplen; + if (l > pppoe_len) + l = pppoe_len; if (ethertype == ETHERTYPE_PPPOEDISC) { - while (pppoe_len > 0) { + while (l > 0) { u_int16_t t_type, t_len; - if (pppoe_len < 4) { - printf("\n\t[|pppoe]"); - break; - } + if (l < 4) + goto trunc; t_type = EXTRACT_16BITS(p); t_len = EXTRACT_16BITS(p + 2); - pppoe_len -= 4; p += 4; + l -= 4; - if (pppoe_len < t_len) { - printf("\n\t[|pppoe]"); - break; - } + if (l < t_len) + goto trunc; printf("\n\ttag "); switch (t_type) { @@ -905,57 +1335,82 @@ pppoe_if_print(u_short ethertype, const printf("\\%03o", p[t_type]); } } - pppoe_len -= t_len; p += t_len; + l -= t_len; } + } else if (ethertype == ETHERTYPE_PPPOE) { + printf("\n\t"); + ppp_print(p, pppoe_len); } - else if (ethertype == ETHERTYPE_PPPOE) { - u_int16_t proto; - int i; - - if (pppoe_len < 2) { - printf("[|pppoe]"); - return (1); - } - proto = EXTRACT_16BITS(p); - for (i = sizeof(protonames)/sizeof(protonames[0]) - 1; i >= 0; - i--) { - if (proto == protonames[i].protocol) { - printf("\n\t%s: ", protonames[i].name); - switch (proto) { - case PPP_LCP: - handle_lcp(p - 2, length + 2); - break; - case PPP_CHAP: - handle_chap(p - 2, length + 2); - break; - case PPP_PAP: - handle_pap(p - 2, length + 2); - break; - case PPP_IPCP: - handle_ipcp(p - 2, length + 2); - break; - case PPP_IPV6CP: - handle_ipv6cp(p - 2, length + 2); - break; - case PPP_IP: - ip_print(p + 2, length - 2); - break; - case PPP_IPV6: - ip6_print(p + 2, length - 2); - break; - case PPP_IPX: - ipx_print(p + 2, length - 2); - } - break; - } + return (1); + +trunc: + printf("[|pppoe]"); + return (1); +} + +void +ppp_hdlc_print(const u_char *p, u_int length) +{ + uint8_t address, control; + int l; + + l = snapend - p; + + if (l < sizeof(address) + sizeof(control)) + goto trunc; + + address = p[0]; + control = p[1]; + + p += sizeof(address) + sizeof(control); + l -= sizeof(address) + sizeof(control); + length -= sizeof(address) + sizeof(control); + + switch (address) { + case 0xff: /* All-Stations */ + if (eflag) + printf("%02x %02x %u ", address, control, length); + + if (control != 0x3) { + printf(" discard"); + break; } - if (i < 0) - printf("\n\t%04x: ", proto); + + ppp_print(p, length); + break; + + default: + printf("ppp address 0x%02x unknown", address); + break; } + return; - return (1); +trunc: + printf("[|ppp]"); +} + +void +ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h, + const u_char *p) +{ + int l = h->caplen; + + packetp = p; + snapend = p + l; + + ts_print(&h->ts); + + if (eflag) + printf("PPP "); + + ppp_hdlc_print(p, h->len); + + if (xflag) + default_print(p, l); + + printf("\n"); } #else Index: usr.sbin/tcpdump/tcpdump.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/tcpdump.c,v retrieving revision 1.82 diff -u -p -r1.82 tcpdump.c --- usr.sbin/tcpdump/tcpdump.c 3 Feb 2018 13:39:48 -0000 1.82 +++ usr.sbin/tcpdump/tcpdump.c 5 Feb 2018 06:08:37 -0000 @@ -115,6 +115,7 @@ static struct printer printers[] = { { sl_if_print, DLT_SLIP }, { sl_bsdos_if_print, DLT_SLIP_BSDOS }, { ppp_if_print, DLT_PPP }, + { ppp_hdlc_if_print, DLT_PPP_SERIAL }, { fddi_if_print, DLT_FDDI }, { null_if_print, DLT_NULL }, { raw_if_print, DLT_RAW },