From: Peter Avalos Date: Wed, 11 Jul 2012 01:22:41 +0000 (-0700) Subject: Import tcpdump-4.3.0. X-Git-Tag: v3.2.0~622^2 X-Git-Url: https://gitweb.dragonflybsd.org/~nant/dragonfly.git/commitdiff_plain/6263709f418fb6c2a0a47a49018ce1b6fa0894f6?hp=-c Import tcpdump-4.3.0. See CHANGES for details. --- 6263709f418fb6c2a0a47a49018ce1b6fa0894f6 diff --git a/contrib/tcpdump/CHANGES b/contrib/tcpdump/CHANGES index 2fa51b9d00..0031431b28 100644 --- a/contrib/tcpdump/CHANGES +++ b/contrib/tcpdump/CHANGES @@ -1,3 +1,19 @@ +Friday April 3, 2011. mcr@sandelman.ca. + Summary for 4.3.0 tcpdump release + fixes for forces: SPARSE data (per RFC 5810) + some more test cases added + updates to documentation on -l, -U and -w flags. + Fix printing of BGP optional headers. + Tried to include DLT_PFSYNC support, failed due to headers required. + added TIPC support. + Fix LLDP Network Policy bit definitions. + fixes for IGMPv3's Max Response Time: it is in units of 0.1 second. + SIGUSR1 can be used rather than SIGINFO for stats + permit -n flag to affect print-ip for protocol numbers + ND_OPT_ADVINTERVAL is in milliseconds, not seconds + Teach PPPoE parser about RFC 4638 + + Friday December 9, 2011. guy@alum.mit.edu. Summary for 4.2.1 tcpdump release Only build the Babel printer if IPv6 is enabled. diff --git a/contrib/tcpdump/VERSION b/contrib/tcpdump/VERSION index fae6e3d04b..80895903a1 100644 --- a/contrib/tcpdump/VERSION +++ b/contrib/tcpdump/VERSION @@ -1 +1 @@ -4.2.1 +4.3.0 diff --git a/contrib/tcpdump/bgp.h b/contrib/tcpdump/bgp.h old mode 100755 new mode 100644 diff --git a/contrib/tcpdump/decode_prefix.h b/contrib/tcpdump/decode_prefix.h index b73847142f..8bb4a76750 100644 --- a/contrib/tcpdump/decode_prefix.h +++ b/contrib/tcpdump/decode_prefix.h @@ -33,9 +33,9 @@ #ifndef tcpdump_decode_prefix_h #define tcpdump_decode_prefix_h -extern int decode_prefix4(const u_char *pptr, char *buf, u_int buflen); +extern int decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen); #ifdef INET6 -extern int decode_prefix6(const u_char *pd, char *buf, u_int buflen); +extern int decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen); #endif #endif diff --git a/contrib/tcpdump/ethertype.h b/contrib/tcpdump/ethertype.h index fc5e515c6b..8c063396d9 100644 --- a/contrib/tcpdump/ethertype.h +++ b/contrib/tcpdump/ethertype.h @@ -100,6 +100,9 @@ #ifndef ETHERTYPE_AARP #define ETHERTYPE_AARP 0x80f3 #endif +#ifndef ETHERTYPE_TIPC +#define ETHERTYPE_TIPC 0x88ca +#endif #ifndef ETHERTYPE_8021Q #define ETHERTYPE_8021Q 0x8100 #endif diff --git a/contrib/tcpdump/forces.h b/contrib/tcpdump/forces.h index ed497d41d7..d41475f908 100644 --- a/contrib/tcpdump/forces.h +++ b/contrib/tcpdump/forces.h @@ -308,7 +308,7 @@ static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = { /* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print}, /* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print}, /* F_OP_GETRESP */ - {TTLV_T2, B_FULLD | B_RESTV, " GetResp", recpdoptlv_print}, + {TTLV_T2, B_FULLD | B_SPARD | B_RESTV, " GetResp", recpdoptlv_print}, /* F_OP_GETPRESP */ {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print}, /* F_OP_REPORT */ diff --git a/contrib/tcpdump/ipproto.c b/contrib/tcpdump/ipproto.c old mode 100755 new mode 100644 diff --git a/contrib/tcpdump/l2vpn.c b/contrib/tcpdump/l2vpn.c old mode 100755 new mode 100644 diff --git a/contrib/tcpdump/l2vpn.h b/contrib/tcpdump/l2vpn.h old mode 100755 new mode 100644 diff --git a/contrib/tcpdump/netdissect.h b/contrib/tcpdump/netdissect.h index 0c66dfaf80..821949fab4 100644 --- a/contrib/tcpdump/netdissect.h +++ b/contrib/tcpdump/netdissect.h @@ -280,6 +280,7 @@ extern int esp_print(netdissect_options *, register const u_char *bp, int len, register const u_char *bp2, int *nhdr, int *padlen); extern void arp_print(netdissect_options *,const u_char *, u_int, u_int); +extern void tipc_print(netdissect_options *, const u_char *, u_int, u_int); extern void icmp6_print(netdissect_options *ndo, const u_char *, u_int, const u_char *, int); extern void isakmp_print(netdissect_options *,const u_char *, diff --git a/contrib/tcpdump/nlpid.c b/contrib/tcpdump/nlpid.c old mode 100755 new mode 100644 diff --git a/contrib/tcpdump/print-802_11.c b/contrib/tcpdump/print-802_11.c index 24ab625a61..6f2231d7dc 100644 --- a/contrib/tcpdump/print-802_11.c +++ b/contrib/tcpdump/print-802_11.c @@ -485,7 +485,7 @@ static const char *auth_alg_text[]={"Open System","Shared Key","EAP"}; #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0]) static const char *status_text[] = { - "Succesful", /* 0 */ + "Successful", /* 0 */ "Unspecified failure", /* 1 */ "Reserved", /* 2 */ "Reserved", /* 3 */ diff --git a/contrib/tcpdump/print-bgp.c b/contrib/tcpdump/print-bgp.c index 6460a59e0c..c1e382fd76 100644 --- a/contrib/tcpdump/print-bgp.c +++ b/contrib/tcpdump/print-bgp.c @@ -93,8 +93,7 @@ struct bgp_opt { /* variable length */ }; #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ - -#define BGP_UPDATE_MINSIZE 23 +#define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */ struct bgp_notification { u_int8_t bgpn_marker[16]; @@ -115,19 +114,10 @@ struct bgp_route_refresh { }; /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh) */ #define BGP_ROUTE_REFRESH_SIZE 23 -struct bgp_attr { - u_int8_t bgpa_flags; - u_int8_t bgpa_type; - union { - u_int8_t len; - u_int16_t elen; - } bgpa_len; -#define bgp_attr_len(p) \ - (((p)->bgpa_flags & 0x10) ? \ - EXTRACT_16BITS(&(p)->bgpa_len.elen) : (p)->bgpa_len.len) -#define bgp_attr_off(p) \ - (((p)->bgpa_flags & 0x10) ? 4 : 3) -}; +#define bgp_attr_lenlen(flags, p) \ + (((flags) & 0x10) ? 2 : 1) +#define bgp_attr_len(flags, p) \ + (((flags) & 0x10) ? EXTRACT_16BITS(p) : *(p)) #define BGPTYPE_ORIGIN 1 #define BGPTYPE_AS_PATH 2 @@ -493,38 +483,49 @@ as_printf (char *str, int size, u_int asnum) return str; } +#define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv; + int -decode_prefix4(const u_char *pptr, char *buf, u_int buflen) +decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen) { struct in_addr addr; - u_int plen; + u_int plen, plenbytes; TCHECK(pptr[0]); + ITEMCHECK(1); plen = pptr[0]; if (32 < plen) return -1; + itemlen -= 1; memset(&addr, 0, sizeof(addr)); - TCHECK2(pptr[1], (plen + 7) / 8); - memcpy(&addr, &pptr[1], (plen + 7) / 8); + plenbytes = (plen + 7) / 8; + TCHECK2(pptr[1], plenbytes); + ITEMCHECK(plenbytes); + memcpy(&addr, &pptr[1], plenbytes); if (plen % 8) { - ((u_char *)&addr)[(plen + 7) / 8 - 1] &= + ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "%s/%d", getname((u_char *)&addr), plen); - return 1 + (plen + 7) / 8; + return 1 + plenbytes; trunc: return -2; + +badtlv: + return -3; } static int -decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen) +decode_labeled_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen) { struct in_addr addr; - u_int plen; + u_int plen, plenbytes; - TCHECK(pptr[0]); + /* prefix length and label = 4 bytes */ + TCHECK2(pptr[0], 4); + ITEMCHECK(4); plen = pptr[0]; /* get prefix length */ /* this is one of the weirdnesses of rfc3107 @@ -542,12 +543,15 @@ decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen) if (32 < plen) return -1; + itemlen -= 4; memset(&addr, 0, sizeof(addr)); - TCHECK2(pptr[4], (plen + 7) / 8); - memcpy(&addr, &pptr[4], (plen + 7) / 8); + plenbytes = (plen + 7) / 8; + TCHECK2(pptr[4], plenbytes); + ITEMCHECK(plenbytes); + memcpy(&addr, &pptr[4], plenbytes); if (plen % 8) { - ((u_char *)&addr)[(plen + 7) / 8 - 1] &= + ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ @@ -557,10 +561,13 @@ decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen) EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); - return 4 + (plen + 7) / 8; + return 4 + plenbytes; trunc: return -2; + +badtlv: + return -3; } /* @@ -1041,37 +1048,46 @@ trunc: #ifdef INET6 int -decode_prefix6(const u_char *pd, char *buf, u_int buflen) +decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen) { struct in6_addr addr; - u_int plen; + u_int plen, plenbytes; TCHECK(pd[0]); + ITEMCHECK(1); plen = pd[0]; if (128 < plen) return -1; + itemlen -= 1; memset(&addr, 0, sizeof(addr)); - TCHECK2(pd[1], (plen + 7) / 8); - memcpy(&addr, &pd[1], (plen + 7) / 8); + plenbytes = (plen + 7) / 8; + TCHECK2(pd[1], plenbytes); + ITEMCHECK(plenbytes); + memcpy(&addr, &pd[1], plenbytes); if (plen % 8) { - addr.s6_addr[(plen + 7) / 8 - 1] &= + addr.s6_addr[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "%s/%d", getname6((u_char *)&addr), plen); - return 1 + (plen + 7) / 8; + return 1 + plenbytes; trunc: return -2; + +badtlv: + return -3; } static int -decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen) +decode_labeled_prefix6(const u_char *pptr, u_int itemlen, char *buf, u_int buflen) { struct in6_addr addr; - u_int plen; + u_int plen, plenbytes; - TCHECK(pptr[0]); + /* prefix length and label = 4 bytes */ + TCHECK2(pptr[0], 4); + ITEMCHECK(4); plen = pptr[0]; /* get prefix length */ if (24 > plen) @@ -1081,12 +1097,14 @@ decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen) if (128 < plen) return -1; + itemlen -= 4; memset(&addr, 0, sizeof(addr)); - TCHECK2(pptr[4], (plen + 7) / 8); - memcpy(&addr, &pptr[4], (plen + 7) / 8); + plenbytes = (plen + 7) / 8; + TCHECK2(pptr[4], plenbytes); + memcpy(&addr, &pptr[4], plenbytes); if (plen % 8) { - addr.s6_addr[(plen + 7) / 8 - 1] &= + addr.s6_addr[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ @@ -1096,10 +1114,13 @@ decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen) EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); - return 4 + (plen + 7) / 8; + return 4 + plenbytes; trunc: return -2; + +badtlv: + return -3; } static int @@ -1266,7 +1287,7 @@ trunc: } static int -bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) +bgp_attr_print(u_int atype, const u_char *pptr, u_int len) { int i; u_int16_t af; @@ -1276,7 +1297,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) u_int32_t i; } bw; int advance; - int tlen; + u_int tlen; const u_char *tptr; char buf[MAXHOSTNAMELEN + 100]; char tokbuf[TOKBUFSIZE]; @@ -1285,7 +1306,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) tptr = pptr; tlen=len; - switch (attr->bgpa_type) { + switch (atype) { case BGPTYPE_ORIGIN: if (len != 1) printf("invalid len"); @@ -1321,7 +1342,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) * 2 bytes first, and it does not pass, assume that ASs are * encoded in 4 bytes format and move on. */ - as_size = bgp_attr_get_as_size(attr->bgpa_type, pptr, len); + as_size = bgp_attr_get_as_size(atype, pptr, len); while (tptr < pptr + len) { TCHECK(tptr[0]); @@ -1657,20 +1678,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix4(tptr, buf, sizeof(buf)); + advance = decode_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); + advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; @@ -1718,20 +1743,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix6(tptr, buf, sizeof(buf)); + advance = decode_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); + advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; @@ -1821,20 +1850,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix4(tptr, buf, sizeof(buf)); + advance = decode_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); + advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; @@ -1853,20 +1886,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): - advance = decode_prefix6(tptr, buf, sizeof(buf)); + advance = decode_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): - advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); + advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; + else if (advance == -3) + break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; @@ -2097,40 +2134,50 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) } case BGPTYPE_ATTR_SET: TCHECK2(tptr[0], 4); + if (len < 4) + goto trunc; printf("\n\t Origin AS: %s", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr))); tptr+=4; len -=4; - while (len >= 2 ) { - int alen; - struct bgp_attr bgpa; + while (len) { + u_int aflags, atype, alenlen, alen; - TCHECK2(tptr[0], sizeof(bgpa)); - memcpy(&bgpa, tptr, sizeof(bgpa)); - alen = bgp_attr_len(&bgpa); - tptr += bgp_attr_off(&bgpa); - len -= bgp_attr_off(&bgpa); + TCHECK2(tptr[0], 2); + if (len < 2) + goto trunc; + aflags = *tptr; + atype = *(tptr + 1); + tptr += 2; + len -= 2; + alenlen = bgp_attr_lenlen(aflags, tptr); + TCHECK2(tptr[0], alenlen); + if (len < alenlen) + goto trunc; + alen = bgp_attr_len(aflags, tptr); + tptr += alenlen; + len -= alenlen; printf("\n\t %s (%u), length: %u", tok2strbuf(bgp_attr_values, - "Unknown Attribute", bgpa.bgpa_type, - tokbuf, sizeof(tokbuf)), - bgpa.bgpa_type, + "Unknown Attribute", atype, + tokbuf, sizeof(tokbuf)), + atype, alen); - if (bgpa.bgpa_flags) { + if (aflags) { printf(", Flags [%s%s%s%s", - bgpa.bgpa_flags & 0x80 ? "O" : "", - bgpa.bgpa_flags & 0x40 ? "T" : "", - bgpa.bgpa_flags & 0x20 ? "P" : "", - bgpa.bgpa_flags & 0x10 ? "E" : ""); - if (bgpa.bgpa_flags & 0xf) - printf("+%x", bgpa.bgpa_flags & 0xf); + aflags & 0x80 ? "O" : "", + aflags & 0x40 ? "T" : "", + aflags & 0x20 ? "P" : "", + aflags & 0x10 ? "E" : ""); + if (aflags & 0xf) + printf("+%x", aflags & 0xf); printf("]: "); } /* FIXME check for recursion */ - if (!bgp_attr_print(&bgpa, tptr, alen)) + if (!bgp_attr_print(atype, tptr, alen)) return 0; tptr += alen; len -= alen; @@ -2140,7 +2187,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) default: TCHECK2(*pptr,len); - printf("\n\t no Attribute %u decoder",attr->bgpa_type); /* we have no decoder for the attribute */ + printf("\n\t no Attribute %u decoder",atype); /* we have no decoder for the attribute */ if (vflag <= 1) print_unknown_data(pptr,"\n\t ",len); break; @@ -2155,15 +2202,98 @@ trunc: return 0; } +static void +bgp_capabilities_print(const u_char *opt, int caps_len) +{ + char tokbuf[TOKBUFSIZE]; + char tokbuf2[TOKBUFSIZE]; + int cap_type, cap_len, tcap_len, cap_offset; + int i = 0; + + while (i < caps_len) { + TCHECK2(opt[i], BGP_CAP_HEADER_SIZE); + cap_type=opt[i]; + cap_len=opt[i+1]; + tcap_len=cap_len; + printf("\n\t %s (%u), length: %u", + tok2strbuf(bgp_capcode_values, "Unknown", + cap_type, tokbuf, sizeof(tokbuf)), + cap_type, + cap_len); + TCHECK2(opt[i+2], cap_len); + switch (cap_type) { + case BGP_CAPCODE_MP: + printf("\n\t\tAFI %s (%u), SAFI %s (%u)", + tok2strbuf(af_values, "Unknown", + EXTRACT_16BITS(opt+i+2), + tokbuf, sizeof(tokbuf)), + EXTRACT_16BITS(opt+i+2), + tok2strbuf(bgp_safi_values, "Unknown", + opt[i+5], + tokbuf, sizeof(tokbuf)), + opt[i+5]); + break; + case BGP_CAPCODE_RESTART: + printf("\n\t\tRestart Flags: [%s], Restart Time %us", + ((opt[i+2])&0x80) ? "R" : "none", + EXTRACT_16BITS(opt+i+2)&0xfff); + tcap_len-=2; + cap_offset=4; + while(tcap_len>=4) { + printf("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", + tok2strbuf(af_values,"Unknown", + EXTRACT_16BITS(opt+i+cap_offset), + tokbuf, sizeof(tokbuf)), + EXTRACT_16BITS(opt+i+cap_offset), + tok2strbuf(bgp_safi_values,"Unknown", + opt[i+cap_offset+2], + tokbuf2, sizeof(tokbuf2)), + opt[i+cap_offset+2], + ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" ); + tcap_len-=4; + cap_offset+=4; + } + break; + case BGP_CAPCODE_RR: + case BGP_CAPCODE_RR_CISCO: + break; + case BGP_CAPCODE_AS_NEW: + + /* + * Extract the 4 byte AS number encoded. + */ + if (cap_len == 4) { + printf("\n\t\t 4 Byte AS %s", + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(opt + i + 2))); + } + break; + default: + printf("\n\t\tno decoder for Capability %u", + cap_type); + if (vflag <= 1) + print_unknown_data(&opt[i+2],"\n\t\t",cap_len); + break; + } + if (vflag > 1 && cap_len > 0) { + print_unknown_data(&opt[i+2],"\n\t\t",cap_len); + } + i += BGP_CAP_HEADER_SIZE + cap_len; + } + return; + +trunc: + printf("[|BGP]"); +} + static void bgp_open_print(const u_char *dat, int length) { struct bgp_open bgpo; struct bgp_opt bgpopt; const u_char *opt; - int i,cap_type,cap_len,tcap_len,cap_offset; + int i; char tokbuf[TOKBUFSIZE]; - char tokbuf2[TOKBUFSIZE]; TCHECK2(dat[0], BGP_OPEN_SIZE); memcpy(&bgpo, dat, BGP_OPEN_SIZE); @@ -2188,96 +2318,31 @@ bgp_open_print(const u_char *dat, int length) TCHECK2(opt[i], BGP_OPT_SIZE); memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE); if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) { - printf("\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len); + printf("\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len); break; } printf("\n\t Option %s (%u), length: %u", - tok2strbuf(bgp_opt_values,"Unknown", + tok2strbuf(bgp_opt_values,"Unknown", bgpopt.bgpopt_type, tokbuf, sizeof(tokbuf)), - bgpopt.bgpopt_type, - bgpopt.bgpopt_len); - - /* now lets decode the options we know*/ - switch(bgpopt.bgpopt_type) { - case BGP_OPT_CAP: - cap_type=opt[i+BGP_OPT_SIZE]; - cap_len=opt[i+BGP_OPT_SIZE+1]; - tcap_len=cap_len; - printf("\n\t %s (%u), length: %u", - tok2strbuf(bgp_capcode_values, "Unknown", - cap_type, tokbuf, sizeof(tokbuf)), - cap_type, - cap_len); - switch(cap_type) { - case BGP_CAPCODE_MP: - printf("\n\t\tAFI %s (%u), SAFI %s (%u)", - tok2strbuf(af_values, "Unknown", - EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), - tokbuf, sizeof(tokbuf)), - EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), - tok2strbuf(bgp_safi_values, "Unknown", - opt[i+BGP_OPT_SIZE+5], - tokbuf, sizeof(tokbuf)), - opt[i+BGP_OPT_SIZE+5]); - break; - case BGP_CAPCODE_RESTART: - printf("\n\t\tRestart Flags: [%s], Restart Time %us", - ((opt[i+BGP_OPT_SIZE+2])&0x80) ? "R" : "none", - EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2)&0xfff); - tcap_len-=2; - cap_offset=4; - while(tcap_len>=4) { - printf("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", - tok2strbuf(af_values,"Unknown", - EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), - tokbuf, sizeof(tokbuf)), - EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), - tok2strbuf(bgp_safi_values,"Unknown", - opt[i+BGP_OPT_SIZE+cap_offset+2], - tokbuf2, sizeof(tokbuf2)), - opt[i+BGP_OPT_SIZE+cap_offset+2], - ((opt[i+BGP_OPT_SIZE+cap_offset+3])&0x80) ? "yes" : "no" ); - tcap_len-=4; - cap_offset+=4; - } - break; - case BGP_CAPCODE_RR: - case BGP_CAPCODE_RR_CISCO: - break; - case BGP_CAPCODE_AS_NEW: - - /* - * Extract the 4 byte AS number encoded. - */ - TCHECK2(opt[i + BGP_OPT_SIZE + 2], cap_len); - if (cap_len == 4) { - printf("\n\t\t 4 Byte AS %s", - as_printf(astostr, sizeof(astostr), - EXTRACT_32BITS(opt + i + BGP_OPT_SIZE + 2))); - } - break; - default: - TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); - printf("\n\t\tno decoder for Capability %u", - cap_type); - if (vflag <= 1) - print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); - break; - } - if (vflag > 1) { - TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); - print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); - } - break; - case BGP_OPT_AUTH: - default: - printf("\n\t no decoder for option %u", - bgpopt.bgpopt_type); - break; - } + bgpopt.bgpopt_type, + bgpopt.bgpopt_len); + + /* now let's decode the options we know*/ + switch(bgpopt.bgpopt_type) { + case BGP_OPT_CAP: + bgp_capabilities_print(&opt[i+BGP_OPT_SIZE], + bgpopt.bgpopt_len); + break; + + case BGP_OPT_AUTH: + default: + printf("\n\t no decoder for option %u", + bgpopt.bgpopt_type); + break; + } i += BGP_OPT_SIZE + bgpopt.bgpopt_len; } return; @@ -2289,107 +2354,163 @@ static void bgp_update_print(const u_char *dat, int length) { struct bgp bgp; - struct bgp_attr bgpa; const u_char *p; + int withdrawn_routes_len; int len; int i; char tokbuf[TOKBUFSIZE]; +#ifndef INET6 + char buf[MAXHOSTNAMELEN + 100]; + int wpfx; +#endif TCHECK2(dat[0], BGP_SIZE); + if (length < BGP_SIZE) + goto trunc; memcpy(&bgp, dat, BGP_SIZE); p = dat + BGP_SIZE; /*XXX*/ + length -= BGP_SIZE; /* Unfeasible routes */ - len = EXTRACT_16BITS(p); - if (len) { + TCHECK2(p[0], 2); + if (length < 2) + goto trunc; + withdrawn_routes_len = EXTRACT_16BITS(p); + p += 2; + length -= 2; + if (withdrawn_routes_len) { /* * Without keeping state from the original NLRI message, * it's not possible to tell if this a v4 or v6 route, * so only try to decode it if we're not v6 enabled. */ + TCHECK2(p[0], withdrawn_routes_len); + if (length < withdrawn_routes_len) + goto trunc; #ifdef INET6 - printf("\n\t Withdrawn routes: %d bytes", len); + printf("\n\t Withdrawn routes: %d bytes", withdrawn_routes_len); + p += withdrawn_routes_len; + length -= withdrawn_routes_len; #else - char buf[MAXHOSTNAMELEN + 100]; - int wpfx; + if (withdrawn_routes_len < 2) + goto trunc; + length -= 2; + withdrawn_routes_len -= 2; - TCHECK2(p[2], len); - i = 2; printf("\n\t Withdrawn routes:"); - while(i < 2 + len) { - wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); + while(withdrawn_routes_len > 0) { + wpfx = decode_prefix4(p, withdrawn_routes_len, buf, sizeof(buf)); if (wpfx == -1) { printf("\n\t (illegal prefix length)"); break; } else if (wpfx == -2) goto trunc; + else if (wpfx == -3) + goto trunc; /* bytes left, but not enough */ else { - i += wpfx; printf("\n\t %s", buf); + p += wpfx; + length -= wpfx; + withdrawn_routes_len -= wpfx; } } #endif } - p += 2 + len; TCHECK2(p[0], 2); + if (length < 2) + goto trunc; len = EXTRACT_16BITS(p); + p += 2; + length -= 2; - if (len == 0 && length == BGP_UPDATE_MINSIZE) { + if (withdrawn_routes_len == 0 && len == 0 && length == 0) { + /* No withdrawn routes, no path attributes, no NLRI */ printf("\n\t End-of-Rib Marker (empty NLRI)"); return; } if (len) { /* do something more useful!*/ - i = 2; - while (i < 2 + len) { - int alen, aoff; - - TCHECK2(p[i], sizeof(bgpa)); - memcpy(&bgpa, &p[i], sizeof(bgpa)); - alen = bgp_attr_len(&bgpa); - aoff = bgp_attr_off(&bgpa); - - printf("\n\t %s (%u), length: %u", + while (len) { + int aflags, atype, alenlen, alen; + + TCHECK2(p[0], 2); + if (len < 2) + goto trunc; + if (length < 2) + goto trunc; + aflags = *p; + atype = *(p + 1); + p += 2; + len -= 2; + length -= 2; + alenlen = bgp_attr_lenlen(aflags, p); + TCHECK2(p[0], alenlen); + if (len < alenlen) + goto trunc; + if (length < alenlen) + goto trunc; + alen = bgp_attr_len(aflags, p); + p += alenlen; + len -= alenlen; + length -= alenlen; + + printf("\n\t %s (%u), length: %u", tok2strbuf(bgp_attr_values, "Unknown Attribute", - bgpa.bgpa_type, + atype, tokbuf, sizeof(tokbuf)), - bgpa.bgpa_type, + atype, alen); - if (bgpa.bgpa_flags) { + if (aflags) { printf(", Flags [%s%s%s%s", - bgpa.bgpa_flags & 0x80 ? "O" : "", - bgpa.bgpa_flags & 0x40 ? "T" : "", - bgpa.bgpa_flags & 0x20 ? "P" : "", - bgpa.bgpa_flags & 0x10 ? "E" : ""); - if (bgpa.bgpa_flags & 0xf) - printf("+%x", bgpa.bgpa_flags & 0xf); + aflags & 0x80 ? "O" : "", + aflags & 0x40 ? "T" : "", + aflags & 0x20 ? "P" : "", + aflags & 0x10 ? "E" : ""); + if (aflags & 0xf) + printf("+%x", aflags & 0xf); printf("]: "); } - if (!bgp_attr_print(&bgpa, &p[i + aoff], alen)) + if (len < alen) + goto trunc; + if (length < alen) goto trunc; - i += aoff + alen; + if (!bgp_attr_print(atype, p, alen)) + goto trunc; + p += alen; + len -= alen; + length -= alen; } } - p += 2 + len; - if (dat + length > p) { + if (length) { + /* + * XXX - what if they're using the "Advertisement of + * Multiple Paths in BGP" feature: + * + * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/ + * + * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06 + */ printf("\n\t Updated routes:"); - while (dat + length > p) { + while (length) { char buf[MAXHOSTNAMELEN + 100]; - i = decode_prefix4(p, buf, sizeof(buf)); + i = decode_prefix4(p, length, buf, sizeof(buf)); if (i == -1) { printf("\n\t (illegal prefix length)"); break; } else if (i == -2) goto trunc; + else if (i == -3) + goto trunc; /* bytes left, but not enough */ else { printf("\n\t %s", buf); p += i; + length -= i; } } } diff --git a/contrib/tcpdump/print-ether.c b/contrib/tcpdump/print-ether.c index 76505721af..e2f487c2a3 100644 --- a/contrib/tcpdump/print-ether.c +++ b/contrib/tcpdump/print-ether.c @@ -37,7 +37,6 @@ static const char rcsid[] _U_ = #include "extract.h" #include "addrtoname.h" #include "ethertype.h" - #include "ether.h" const struct tok ethertype_values[] = { @@ -84,6 +83,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_CFM_OLD, "CFM (old)" }, { ETHERTYPE_CFM, "CFM" }, { ETHERTYPE_LLDP, "LLDP" }, + { ETHERTYPE_TIPC, "TIPC"}, { 0, NULL} }; @@ -408,6 +408,10 @@ ethertype_print(netdissect_options *ndo, mpls_print(/*ndo,*/p, length); return (1); + case ETHERTYPE_TIPC: + tipc_print(ndo, p, length, caplen); + return (1); + case ETHERTYPE_LAT: case ETHERTYPE_SCA: case ETHERTYPE_MOPRC: diff --git a/contrib/tcpdump/print-forces.c b/contrib/tcpdump/print-forces.c index 033580e51b..438aa279ec 100644 --- a/contrib/tcpdump/print-forces.c +++ b/contrib/tcpdump/print-forces.c @@ -113,24 +113,24 @@ sdatailv_print(register const u_char * pptr, register u_int len, printf("Error: BAD SPARSEDATA-TLV!\n"); return -1; } - rlen = len - ILV_HDRL; + rlen = len; indent += 1; while (rlen != 0) { + char *ib = indent_pr(indent, 1); + register const u_char *tdp = (u_char *) ILV_DATA(ilv); TCHECK(*ilv); invilv = ilv_valid(ilv, rlen); if (invilv) { - printf("Error: BAD ILV!\n"); - return -1; - } - if (vflag >= 3) { - register const u_char *tdp = (u_char *) ILV_DATA(ilv); - char *ib = indent_pr(indent, 1); - printf("\n%s SPARSEDATA: type %x length %d\n", &ib[1], - EXTRACT_32BITS(&ilv->type), - EXTRACT_32BITS(&ilv->length)); printf("%s[", &ib[1]); hex_print_with_offset(ib, tdp, rlen, 0); printf("\n%s]\n", &ib[1]); + return -1; + } + if (vflag >= 3) { + int ilvl = EXTRACT_32BITS(&ilv->length); + printf("\n%s ILV: type %x length %d\n", &ib[1], + EXTRACT_32BITS(&ilv->type), ilvl); + hex_print_with_offset("\t\t[", tdp, ilvl-ILV_HDRL, 0); } ilv = GO_NXT_ILV(ilv, rlen); @@ -216,7 +216,6 @@ pdatacnt_print(register const u_char * pptr, register u_int len, u_int16_t IDcnt, u_int16_t op_msk, int indent) { u_int i; - int rc; u_int32_t id; char *ib = indent_pr(indent, 0); @@ -282,9 +281,10 @@ pdatacnt_print(register const u_char * pptr, register u_int len, chk_op_type(type, op_msk, ops->op_msk); - rc = ops->print((const u_char *)pdtlv, + if (ops->print((const u_char *)pdtlv, tll + pad + TLV_HDRL, op_msk, - indent + 2); + indent + 2) == -1) + return -1; len -= (TLV_HDRL + pad + tll); } else { printf("Invalid path data content type 0x%x len %d\n", @@ -404,7 +404,6 @@ recpdoptlv_print(register const u_char * pptr, register u_int len, { const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; int tll; - int rc = 0; int invtlv; u_int16_t type; register const u_char *dp; @@ -434,7 +433,8 @@ recpdoptlv_print(register const u_char * pptr, register u_int len, EXTRACT_16BITS(&pdtlv->length), EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL); - rc = pdata_print(dp, tll, op_msk, indent + 1); + if (pdata_print(dp, tll, op_msk, indent + 1) == -1) + return -1; pdtlv = GO_NXT_TLV(pdtlv, len); } @@ -1016,7 +1016,7 @@ void forces_print(register const u_char * pptr, register u_int len) if (vflag >= 1) { printf("\n\tForCES Version %d len %uB flags 0x%08x ", ForCES_V(fhdr), mlen, flg_raw); - printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIu64, + printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64, ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)), ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)), EXTRACT_64BITS(fhdr->fm_cor)); diff --git a/contrib/tcpdump/print-icmp6.c b/contrib/tcpdump/print-icmp6.c index ce1046ed2e..176c15c5a3 100644 --- a/contrib/tcpdump/print-icmp6.c +++ b/contrib/tcpdump/print-icmp6.c @@ -752,7 +752,7 @@ icmp6_opt_print(const u_char *bp, int resid) case ND_OPT_ADVINTERVAL: opa = (struct nd_opt_advinterval *)op; TCHECK(opa->nd_opt_adv_interval); - printf(" %us", EXTRACT_32BITS(&opa->nd_opt_adv_interval)); + printf(" %ums", EXTRACT_32BITS(&opa->nd_opt_adv_interval)); break; case ND_OPT_HOMEAGENT_INFO: oph = (struct nd_opt_homeagent_info *)op; diff --git a/contrib/tcpdump/print-igmp.c b/contrib/tcpdump/print-igmp.c index 6522bc3044..4087ee0980 100644 --- a/contrib/tcpdump/print-igmp.c +++ b/contrib/tcpdump/print-igmp.c @@ -227,7 +227,11 @@ print_igmpv3_query(register const u_char *bp, register u_int len) } if (mrc != 100) { (void)printf(" [max resp time "); - relts_print(mrt); + if (mrt < 600) { + (void)printf("%.1fs", mrt * 0.1); + } else { + relts_print(mrt / 10); + } (void)printf("]"); } TCHECK2(bp[4], 4); diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c index 1fa7aab0d6..494eb2958e 100644 --- a/contrib/tcpdump/print-ip.c +++ b/contrib/tcpdump/print-ip.c @@ -350,7 +350,7 @@ again: ipds->nh = enh & 0xff; goto again; } - + case IPPROTO_IPCOMP: { int enh; @@ -370,25 +370,25 @@ again: case IPPROTO_DCCP: dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len); break; - + case IPPROTO_TCP: /* pass on the MF bit plus the offset to detect fragments */ tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, ipds->off & (IP_MF|IP_OFFMASK)); break; - + case IPPROTO_UDP: /* pass on the MF bit plus the offset to detect fragments */ udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, ipds->off & (IP_MF|IP_OFFMASK)); break; - + case IPPROTO_ICMP: /* pass on the MF bit plus the offset to detect fragments */ icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, ipds->off & (IP_MF|IP_OFFMASK)); break; - + case IPPROTO_PIGP: /* * XXX - the current IANA protocol number assignments @@ -405,11 +405,11 @@ again: */ igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); break; - + case IPPROTO_EIGRP: eigrp_print(ipds->cp, ipds->len); break; - + case IPPROTO_ND: ND_PRINT((ndo, " nd %d", ipds->len)); break; @@ -434,7 +434,7 @@ again: return; } break; - + #ifdef INET6 case IPPROTO_IPV6: /* ip6-in-ip encapsulation */ @@ -482,7 +482,7 @@ again: break; default: - if ((proto = getprotobynumber(ipds->nh)) != NULL) + if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL) ND_PRINT((ndo, " %s", proto->p_name)); else ND_PRINT((ndo, " ip-proto-%d", ipds->nh)); @@ -490,7 +490,7 @@ again: break; } } - + void ip_print_inner(netdissect_options *ndo, const u_char *bp, @@ -597,7 +597,7 @@ ip_print(netdissect_options *ndo, } if (ipds->ip->ip_ttl >= 1) - (void)printf(", ttl %u", ipds->ip->ip_ttl); + (void)printf(", ttl %u", ipds->ip->ip_ttl); /* * for the firewall guys, print id, offset. @@ -661,11 +661,11 @@ ip_print(netdissect_options *ndo, if (ipds->off & 0x1fff) { (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src), ipaddr_string(&ipds->ip->ip_dst)); - if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL) + if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL) (void)printf(" %s", proto->p_name); else (void)printf(" ip-proto-%d", ipds->ip->ip_p); - } + } } } diff --git a/contrib/tcpdump/print-ip6opts.c b/contrib/tcpdump/print-ip6opts.c index 7a4bf5593a..2121b46039 100644 --- a/contrib/tcpdump/print-ip6opts.c +++ b/contrib/tcpdump/print-ip6opts.c @@ -141,6 +141,8 @@ ip6_opt_print(const u_char *bp, int len) int i; int optlen = 0; + if (len == 0) + return; for (i = 0; i < len; i += optlen) { if (bp[i] == IP6OPT_PAD1) optlen = 1; @@ -271,10 +273,11 @@ ip6_opt_print(const u_char *bp, int len) printf("(type %d: trunc)", bp[i]); goto trunc; } - printf("(opt_type 0x%02x: len=%d) ", bp[i], bp[i + 1]); + printf("(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1]); break; } } + printf(" "); #if 0 end: diff --git a/contrib/tcpdump/print-ldp.c b/contrib/tcpdump/print-ldp.c index 1243104855..262c9bda71 100644 --- a/contrib/tcpdump/print-ldp.c +++ b/contrib/tcpdump/print-ldp.c @@ -180,7 +180,7 @@ static const struct tok ldp_tlv_values[] = { #define LDP_FEC_WILDCARD 0x01 #define LDP_FEC_PREFIX 0x02 #define LDP_FEC_HOSTADDRESS 0x03 -/* From draft-martini-l2circuit-trans-mpls-13.txt */ +/* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */ #define LDP_FEC_MARTINI_VC 0x80 static const struct tok ldp_fec_values[] = { @@ -238,6 +238,9 @@ int ldp_tlv_print(register const u_char *); * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +#define TLV_TCHECK(minlen) \ + TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv; + int ldp_tlv_print(register const u_char *tptr) { @@ -273,6 +276,7 @@ ldp_tlv_print(register const u_char *tptr) { switch(tlv_type) { case LDP_TLV_COMMON_HELLO: + TLV_TCHECK(4); printf("\n\t Hold Time: %us, Flags: [%s Hello%s]", EXTRACT_16BITS(tptr), (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link", @@ -280,18 +284,22 @@ ldp_tlv_print(register const u_char *tptr) { break; case LDP_TLV_IPV4_TRANSPORT_ADDR: + TLV_TCHECK(4); printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr)); break; #ifdef INET6 case LDP_TLV_IPV6_TRANSPORT_ADDR: + TLV_TCHECK(16); printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr)); break; #endif case LDP_TLV_CONFIG_SEQ_NUMBER: + TLV_TCHECK(4); printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr)); break; case LDP_TLV_ADDRESS_LIST: + TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN); af = EXTRACT_16BITS(tptr); tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN; @@ -300,6 +308,7 @@ ldp_tlv_print(register const u_char *tptr) { switch (af) { case AFNUM_INET: while(tlv_tlen >= sizeof(struct in_addr)) { + TCHECK2(*tptr, sizeof(struct in_addr)); printf(" %s",ipaddr_string(tptr)); tlv_tlen-=sizeof(struct in_addr); tptr+=sizeof(struct in_addr); @@ -308,6 +317,7 @@ ldp_tlv_print(register const u_char *tptr) { #ifdef INET6 case AFNUM_INET6: while(tlv_tlen >= sizeof(struct in6_addr)) { + TCHECK2(*tptr, sizeof(struct in6_addr)); printf(" %s",ip6addr_string(tptr)); tlv_tlen-=sizeof(struct in6_addr); tptr+=sizeof(struct in6_addr); @@ -321,6 +331,7 @@ ldp_tlv_print(register const u_char *tptr) { break; case LDP_TLV_COMMON_SESSION: + TLV_TCHECK(8); printf("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]", EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2), (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited", @@ -329,50 +340,86 @@ ldp_tlv_print(register const u_char *tptr) { break; case LDP_TLV_FEC: + TLV_TCHECK(1); fec_type = *tptr; printf("\n\t %s FEC (0x%02x)", tok2str(ldp_fec_values, "Unknown", fec_type), fec_type); tptr+=1; + tlv_tlen-=1; switch(fec_type) { case LDP_FEC_WILDCARD: break; case LDP_FEC_PREFIX: + TLV_TCHECK(2); af = EXTRACT_16BITS(tptr); - tptr+=2; + tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; if (af == AFNUM_INET) { - i=decode_prefix4(tptr,buf,sizeof(buf)); - printf(": IPv4 prefix %s",buf); + i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf)); + if (i == -2) + goto trunc; + if (i == -3) + printf(": IPv4 prefix (goes past end of TLV)"); + else if (i == -1) + printf(": IPv4 prefix (invalid length)"); + else + printf(": IPv4 prefix %s",buf); } #ifdef INET6 else if (af == AFNUM_INET6) { - i=decode_prefix6(tptr,buf,sizeof(buf)); - printf(": IPv6 prefix %s",buf); + i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf)); + if (i == -2) + goto trunc; + if (i == -3) + printf(": IPv4 prefix (goes past end of TLV)"); + else if (i == -1) + printf(": IPv6 prefix (invalid length)"); + else + printf(": IPv6 prefix %s",buf); } #endif + else + printf(": Address family %u prefix", af); break; case LDP_FEC_HOSTADDRESS: break; case LDP_FEC_MARTINI_VC: - if (!TTEST2(*tptr, 11)) - goto trunc; + /* + * According to RFC 4908, the VC info Length field can be zero, + * in which case not only are there no interface parameters, + * there's no VC ID. + */ + TLV_TCHECK(7); vc_info_len = *(tptr+2); + if (vc_info_len == 0) { + printf(": %s, %scontrol word, group-ID %u, VC-info-length: %u", + tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), + EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", + EXTRACT_32BITS(tptr+3), + vc_info_len); + break; + } + + /* Make sure we have the VC ID as well */ + TLV_TCHECK(11); printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", EXTRACT_32BITS(tptr+3), EXTRACT_32BITS(tptr+7), vc_info_len); + if (vc_info_len < 4) + goto trunc; /* minimum 4, for the VC ID */ + vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */ - if (vc_info_len == 0) /* infinite loop protection */ - break; - + /* Skip past the fixed information and the VC ID */ tptr+=11; - if (!TTEST2(*tptr, vc_info_len)) - goto trunc; + tlv_tlen-=11; + TLV_TCHECK(vc_info_len); while (vc_info_len > 2) { vc_info_tlv_type = *tptr; @@ -421,10 +468,12 @@ ldp_tlv_print(register const u_char *tptr) { break; case LDP_TLV_GENERIC_LABEL: + TLV_TCHECK(4); printf("\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff); break; case LDP_TLV_STATUS: + TLV_TCHECK(8); ui = EXTRACT_32BITS(tptr); tptr+=4; printf("\n\t Status: 0x%02x, Flags: [%s and %s forward]", @@ -438,6 +487,7 @@ ldp_tlv_print(register const u_char *tptr) { break; case LDP_TLV_FT_SESSION: + TLV_TCHECK(8); ft_flags = EXTRACT_16BITS(tptr); printf("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]", ft_flags&0x8000 ? "" : "No ", @@ -456,6 +506,7 @@ ldp_tlv_print(register const u_char *tptr) { break; case LDP_TLV_MTU: + TLV_TCHECK(2); printf("\n\t MTU: %u", EXTRACT_16BITS(tptr)); break; @@ -486,6 +537,10 @@ ldp_tlv_print(register const u_char *tptr) { trunc: printf("\n\t\t packet exceeded snapshot"); return 0; + +badtlv: + printf("\n\t\t TLV contents go past end of TLV"); + return(tlv_len+4); /* Type & Length fields not included */ } void @@ -546,8 +601,7 @@ ldp_msg_print(register const u_char *pptr) { while(tlen>0) { /* did we capture enough for fully decoding the msg header ? */ - if (!TTEST2(*tptr, sizeof(struct ldp_msg_header))) - goto trunc; + TCHECK2(*tptr, sizeof(struct ldp_msg_header)); ldp_msg_header = (const struct ldp_msg_header *)tptr; msg_len=EXTRACT_16BITS(ldp_msg_header->length); @@ -570,8 +624,7 @@ ldp_msg_print(register const u_char *pptr) { msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */ /* did we capture enough for fully decoding the message ? */ - if (!TTEST2(*tptr, msg_len)) - goto trunc; + TCHECK2(*tptr, msg_len); hexdump=FALSE; switch(msg_type) { diff --git a/contrib/tcpdump/print-lldp.c b/contrib/tcpdump/print-lldp.c index 0ee2f955db..8735e58cee 100644 --- a/contrib/tcpdump/print-lldp.c +++ b/contrib/tcpdump/print-lldp.c @@ -385,9 +385,9 @@ static const struct tok lldp_tia_application_type_values[] = { { 0, NULL} }; -#define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 5) +#define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 5) #define LLDP_TIA_NETWORK_POLICY_T_BIT (1 << 6) -#define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 7) +#define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 7) static const struct tok lldp_tia_network_policy_bits_values[] = { { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"}, diff --git a/contrib/tcpdump/print-lwapp.c b/contrib/tcpdump/print-lwapp.c index 984ebaa304..154876f54a 100644 --- a/contrib/tcpdump/print-lwapp.c +++ b/contrib/tcpdump/print-lwapp.c @@ -174,7 +174,7 @@ lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) { const struct lwapp_transport_header *lwapp_trans_header; const struct lwapp_control_header *lwapp_control_header; const u_char *tptr; - int hexdump,tlen; + int tlen; int msg_tlen; tptr=pptr; @@ -247,7 +247,6 @@ lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) { /* did we capture enough for fully decoding the message */ if (!TTEST2(*tptr, msg_tlen)) goto trunc; - hexdump=FALSE; /* XXX - Decode sub messages for each message */ switch(lwapp_control_header->msg_type) { diff --git a/contrib/tcpdump/print-ospf6.c b/contrib/tcpdump/print-ospf6.c index 1100485670..fb62b39685 100644 --- a/contrib/tcpdump/print-ospf6.c +++ b/contrib/tcpdump/print-ospf6.c @@ -160,17 +160,25 @@ trunc: } static int -ospf6_print_lsaprefix(register const struct lsa6_prefix *lsapp) +ospf6_print_lsaprefix(const u_int8_t *tptr, u_int lsa_length) { + const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr; u_int wordlen; struct in6_addr prefix; - TCHECK(*lsapp); + if (lsa_length < sizeof (*lsapp) - 4) + goto trunc; + lsa_length -= sizeof (*lsapp) - 4; + TCHECK2(*lsapp, sizeof (*lsapp) - 4); wordlen = (lsapp->lsa_p_len + 31) / 32; if (wordlen * 4 > sizeof(struct in6_addr)) { printf(" bogus prefixlen /%d", lsapp->lsa_p_len); goto trunc; } + if (lsa_length < wordlen * 4) + goto trunc; + lsa_length -= wordlen * 4; + TCHECK2(lsapp->lsa_p_prefix, wordlen * 4); memset(&prefix, 0, sizeof(prefix)); memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4); printf("\n\t\t%s/%d", ip6addr_string(&prefix), @@ -194,7 +202,6 @@ trunc: static int ospf6_print_lsa(register const struct lsa6 *lsap) { - register const u_char *ls_end, *ls_opt; register const struct rlalink6 *rlp; #if 0 register const struct tos_metric *tosp; @@ -210,34 +217,45 @@ ospf6_print_lsa(register const struct lsa6 *lsap) register const u_int32_t *lp; #endif register u_int prefixes; - register int bytelen, length, lsa_length; + register int bytelen; + register u_int length, lsa_length; u_int32_t flags32; - u_int8_t *tptr; + const u_int8_t *tptr; if (ospf6_print_lshdr(&lsap->ls_hdr)) return (1); TCHECK(lsap->ls_hdr.ls_length); length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); + + /* + * The LSA length includes the length of the header; + * it must have a value that's at least that length. + * If it does, find the length of what follows the + * header. + */ + if (length < sizeof(struct lsa6_hdr)) + return (1); lsa_length = length - sizeof(struct lsa6_hdr); - ls_end = (u_char *)lsap + length; tptr = (u_int8_t *)lsap+sizeof(struct lsa6_hdr); switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { case LS_TYPE_ROUTER | LS_SCOPE_AREA: + if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options); TCHECK(lsap->lsa_un.un_rla.rla_options); printf("\n\t Options [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options))); - - TCHECK(lsap->lsa_un.un_rla.rla_flags); printf(", RLA-Flags [%s]", bittok2str(ospf6_rla_flag_values, "none", lsap->lsa_un.un_rla.rla_flags)); - - TCHECK(lsap->lsa_un.un_rla.rla_link); rlp = lsap->lsa_un.un_rla.rla_link; - while (rlp + 1 <= (struct rlalink6 *)ls_end) { + while (lsa_length != 0) { + if (lsa_length < sizeof (*rlp)) + return (1); + lsa_length -= sizeof (*rlp); TCHECK(*rlp); switch (rlp->link_type) { @@ -276,13 +294,20 @@ ospf6_print_lsa(register const struct lsa6 *lsap) break; case LS_TYPE_NETWORK | LS_SCOPE_AREA: + if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options); TCHECK(lsap->lsa_un.un_nla.nla_options); printf("\n\t Options [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options))); + printf("\n\t Connected Routers:"); ap = lsap->lsa_un.un_nla.nla_router; - while ((u_char *)ap < ls_end) { + while (lsa_length != 0) { + if (lsa_length < sizeof (*ap)) + return (1); + lsa_length -= sizeof (*ap); TCHECK(*ap); printf("\n\t\t%s", ipaddr_string(ap)); ++ap; @@ -290,18 +315,27 @@ ospf6_print_lsa(register const struct lsa6 *lsap) break; case LS_TYPE_INTER_AP | LS_SCOPE_AREA: + if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric); TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); printf(", metric %u", EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC); - lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix; - while (lsapp + sizeof(lsapp) <= (struct lsa6_prefix *)ls_end) { - bytelen = ospf6_print_lsaprefix(lsapp); - if (bytelen) + + tptr = (u_int8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; + while (lsa_length != 0) { + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); + if (bytelen < 0) goto trunc; - lsapp = (struct lsa6_prefix *)(((u_char *)lsapp) + bytelen); + lsa_length -= bytelen; + tptr += bytelen; } break; - case LS_SCOPE_AS | LS_TYPE_ASE: + + case LS_TYPE_ASE | LS_SCOPE_AS: + if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric); TCHECK(lsap->lsa_un.un_asla.asla_metric); flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); printf("\n\t Flags [%s]", @@ -309,48 +343,63 @@ ospf6_print_lsa(register const struct lsa6 *lsap) printf(" metric %u", EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & ASLA_MASK_METRIC); - lsapp = lsap->lsa_un.un_asla.asla_prefix; - bytelen = ospf6_print_lsaprefix(lsapp); + + tptr = (u_int8_t *)lsap->lsa_un.un_asla.asla_prefix; + lsapp = (struct lsa6_prefix *)tptr; + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); if (bytelen < 0) goto trunc; - if ((ls_opt = (u_char *)(((u_char *)lsapp) + bytelen)) < ls_end) { - struct in6_addr *fwdaddr6; + lsa_length -= bytelen; + tptr += bytelen; - if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { - fwdaddr6 = (struct in6_addr *)ls_opt; - TCHECK(*fwdaddr6); - printf(" forward %s", - ip6addr_string(fwdaddr6)); - - ls_opt += sizeof(struct in6_addr); - } - - if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { - TCHECK(*(u_int32_t *)ls_opt); - printf(" tag %s", - ipaddr_string((u_int32_t *)ls_opt)); + if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { + struct in6_addr *fwdaddr6; - ls_opt += sizeof(u_int32_t); - } + fwdaddr6 = (struct in6_addr *)tptr; + if (lsa_length < sizeof (*fwdaddr6)) + return (1); + lsa_length -= sizeof (*fwdaddr6); + TCHECK(*fwdaddr6); + printf(" forward %s", + ip6addr_string(fwdaddr6)); + tptr += sizeof(*fwdaddr6); + } - if (lsapp->lsa_p_metric) { - TCHECK(*(u_int32_t *)ls_opt); - printf(" RefLSID: %s", - ipaddr_string((u_int32_t *)ls_opt)); + if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { + if (lsa_length < sizeof (u_int32_t)) + return (1); + lsa_length -= sizeof (u_int32_t); + TCHECK(*(u_int32_t *)tptr); + printf(" tag %s", + ipaddr_string((u_int32_t *)tptr)); + tptr += sizeof(u_int32_t); + } - ls_opt += sizeof(u_int32_t); - } + if (lsapp->lsa_p_metric) { + if (lsa_length < sizeof (u_int32_t)) + return (1); + lsa_length -= sizeof (u_int32_t); + TCHECK(*(u_int32_t *)tptr); + printf(" RefLSID: %s", + ipaddr_string((u_int32_t *)tptr)); + tptr += sizeof(u_int32_t); } break; case LS_TYPE_LINK: /* Link LSA */ llsap = &lsap->lsa_un.un_llsa; - TCHECK(llsap->llsa_options); + if (lsa_length < sizeof (llsap->llsa_priandopt)) + return (1); + lsa_length -= sizeof (llsap->llsa_priandopt); + TCHECK(llsap->llsa_priandopt); printf("\n\t Options [%s]", bittok2str(ospf6_option_values, "none", EXTRACT_32BITS(&llsap->llsa_options))); - TCHECK(llsap->llsa_nprefix); + + if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) + return (1); + lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); printf("\n\t Priority %d, Link-local address %s, Prefixes %d:", llsap->llsa_priority, @@ -358,57 +407,63 @@ ospf6_print_lsa(register const struct lsa6 *lsap) prefixes); tptr = (u_int8_t *)llsap->llsa_prefix; - while (prefixes > 0) { - lsapp = (struct lsa6_prefix *)tptr; - if ((bytelen = ospf6_print_lsaprefix(lsapp)) == -1) { - goto trunc; - } - prefixes--; - tptr += bytelen; - } + while (prefixes > 0) { + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); + if (bytelen < 0) + goto trunc; + prefixes--; + lsa_length -= bytelen; + tptr += bytelen; + } break; case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: /* Intra-Area-Prefix LSA */ + if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid); TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); ospf6_print_ls_type( EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), &lsap->lsa_un.un_intra_ap.intra_ap_lsid); + + if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix); TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); printf("\n\t Prefixes %d:", prefixes); - tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; - - while (prefixes > 0) { - lsapp = (struct lsa6_prefix *)tptr; - if ((bytelen = ospf6_print_lsaprefix(lsapp)) == -1) { - goto trunc; - } - prefixes--; - tptr += bytelen; - } + tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; + while (prefixes > 0) { + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); + if (bytelen < 0) + goto trunc; + prefixes--; + lsa_length -= bytelen; + tptr += bytelen; + } break; case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: if (ospf_print_grace_lsa(tptr, lsa_length) == -1) { return 1; } - - break; + break; case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: - if (ospf_print_te_lsa(tptr, lsa_length) == -1) { - return 1; - } - break; + if (ospf_print_te_lsa(tptr, lsa_length) == -1) { + return 1; + } + break; default: - if(!print_unknown_data(tptr, - "\n\t ", - lsa_length)) { - return (1); - } + if(!print_unknown_data(tptr, + "\n\t ", + lsa_length)) { + return (1); + } + break; } return (0); diff --git a/contrib/tcpdump/print-pim.c b/contrib/tcpdump/print-pim.c index 0f558af135..e0cca125f6 100644 --- a/contrib/tcpdump/print-pim.c +++ b/contrib/tcpdump/print-pim.c @@ -667,7 +667,7 @@ pimv2_print(register const u_char *bp, register u_int len, u_int cksum) case PIMV2_HELLO_OPTION_LANPRUNEDELAY: if (olen != 4) { - (void)printf("ERROR: Option Lenght != 4 Bytes (%u)", olen); + (void)printf("ERROR: Option Length != 4 Bytes (%u)", olen); } else { char t_bit; u_int16_t lan_delay, override_interval; @@ -690,7 +690,7 @@ pimv2_print(register const u_char *bp, register u_int len, u_int cksum) printf("%u", EXTRACT_32BITS(bp)); break; default: - printf("ERROR: Option Lenght != 4 Bytes (%u)", olen); + printf("ERROR: Option Length != 4 Bytes (%u)", olen); break; } break; diff --git a/contrib/tcpdump/print-pppoe.c b/contrib/tcpdump/print-pppoe.c index 7abc787832..bcc976c4b7 100644 --- a/contrib/tcpdump/print-pppoe.c +++ b/contrib/tcpdump/print-pppoe.c @@ -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" }, diff --git a/contrib/tcpdump/print-rrcp.c b/contrib/tcpdump/print-rrcp.c index 64cb7dec31..c5b1fdd96a 100644 --- a/contrib/tcpdump/print-rrcp.c +++ b/contrib/tcpdump/print-rrcp.c @@ -102,11 +102,11 @@ rrcp_print(netdissect_options *ndo, ND_PRINT((ndo, "%s > %s, %s %s", etheraddr_string(ESRC(ep)), etheraddr_string(EDST(ep)), - tok2strbuf(proto_values,"RRCP-0x%02d",rrcp_proto,proto_str,sizeof(proto_str)), + tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)), ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); if (rrcp_proto==1){ ND_PRINT((ndo, ": %s", - tok2strbuf(opcode_values,"unknown opcode (0x%02d)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); + tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); } if (rrcp_opcode==1 || rrcp_opcode==2){ ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); diff --git a/contrib/tcpdump/print-syslog.c b/contrib/tcpdump/print-syslog.c old mode 100755 new mode 100644 diff --git a/contrib/tcpdump/print-tipc.c b/contrib/tcpdump/print-tipc.c new file mode 100644 index 0000000000..8f2f769145 --- /dev/null +++ b/contrib/tcpdump/print-tipc.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.66 2006-03-03 22:53:21 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "addrtoname.h" +#include "ether.h" +#include "ethertype.h" +#include "extract.h" /* must come after interface.h */ + +/* + * Transparent Inter-Process Communication (TIPC) protocol. + * + * http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html + * http://tipc.sourceforge.net/doc/tipc_message_formats.html + */ + +#define TIPC_USER_LOW_IMPORTANCE 0 +#define TIPC_USER_MEDIUM_IMPORTANCE 1 +#define TIPC_USER_HIGH_IMPORTANCE 2 +#define TIPC_USER_CRITICAL_IMPORTANCE 3 +#define TIPC_USER_BCAST_PROTOCOL 5 +#define TIPC_USER_MSG_BUNDLER 6 +#define TIPC_USER_LINK_PROTOCOL 7 +#define TIPC_USER_CONN_MANAGER 8 +#define TIPC_USER_CHANGEOVER_PROTOCOL 10 +#define TIPC_USER_NAME_DISTRIBUTOR 11 +#define TIPC_USER_MSG_FRAGMENTER 12 +#define TIPC_USER_LINK_CONFIG 13 + +#define TIPC_CONN_MSG 0 +#define TIPC_DIRECT_MSG 1 +#define TIPC_NAMED_MSG 2 +#define TIPC_MCAST_MSG 3 + +#define TIPC_ZONE(addr) (((addr) >> 24) & 0xFF) +#define TIPC_CLUSTER(addr) (((addr) >> 12) & 0xFFF) +#define TIPC_NODE(addr) (((addr) >> 0) & 0xFFF) + +struct tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; +}; + +#define TIPC_VER(w0) (((w0) >> 29) & 0x07) +#define TIPC_USER(w0) (((w0) >> 25) & 0x0F) +#define TIPC_HSIZE(w0) (((w0) >> 21) & 0x0F) +#define TIPC_MSIZE(w0) (((w0) >> 0) & 0xFFFF) +#define TIPC_MTYPE(w1) (((w1) >> 29) & 0x07) +#define TIPC_BROADCAST_ACK(w1) (((w1) >> 0) & 0xFFFF) +#define TIPC_LINK_ACK(w2) (((w2) >> 16) & 0xFFFF) +#define TIPC_LINK_SEQ(w2) (((w2) >> 0) & 0xFFFF) + +static const struct tok tipcuser_values[] = { + { TIPC_USER_LOW_IMPORTANCE, "Low Importance Data payload" }, + { TIPC_USER_MEDIUM_IMPORTANCE, "Medium Importance Data payload" }, + { TIPC_USER_HIGH_IMPORTANCE, "High Importance Data payload" }, + { TIPC_USER_CRITICAL_IMPORTANCE, "Critical Importance Data payload" }, + { TIPC_USER_BCAST_PROTOCOL, "Broadcast Link Protocol internal" }, + { TIPC_USER_MSG_BUNDLER, "Message Bundler Protocol internal" }, + { TIPC_USER_LINK_PROTOCOL, "Link State Protocol internal" }, + { TIPC_USER_CONN_MANAGER, "Connection Manager internal" }, + { TIPC_USER_CHANGEOVER_PROTOCOL, "Link Changeover Protocol internal" }, + { TIPC_USER_NAME_DISTRIBUTOR, "Name Table Update Protocol internal" }, + { TIPC_USER_MSG_FRAGMENTER, "Message Fragmentation Protocol internal" }, + { TIPC_USER_LINK_CONFIG, "Neighbor Detection Protocol internal" }, + { 0, NULL } +}; + +static const struct tok tipcmtype_values[] = { + { TIPC_CONN_MSG, "CONN_MSG" }, + { TIPC_DIRECT_MSG, "MCAST_MSG" }, + { TIPC_NAMED_MSG, "NAMED_MSG" }, + { TIPC_MCAST_MSG, "DIRECT_MSG" }, + { 0, NULL } +}; + +static const struct tok tipc_linkconf_mtype_values[] = { + { 0, "Link request" }, + { 1, "Link response" }, + { 0, NULL } +}; + +struct payload_tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; + u_int32_t w2; + u_int32_t prev_node; + u_int32_t orig_port; + u_int32_t dest_port; + u_int32_t orig_node; + u_int32_t dest_node; + u_int32_t name_type; + u_int32_t w9; + u_int32_t wA; +}; + +struct internal_tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; + u_int32_t w2; + u_int32_t prev_node; + u_int32_t w4; + u_int32_t w5; + u_int32_t orig_node; + u_int32_t dest_node; + u_int32_t trans_seq; + u_int32_t w9; +}; + +#define TIPC_SEQ_GAP(w1) (((w1) >> 16) & 0x1FFF) +#define TIPC_BC_GAP_AFTER(w2) (((w2) >> 16) & 0xFFFF) +#define TIPC_BC_GAP_TO(w2) (((w2) >> 0) & 0xFFFF) +#define TIPC_LAST_SENT_FRAG(w4) (((w4) >> 16) & 0xFFFF) +#define TIPC_NEXT_SENT_FRAG(w4) (((w4) >> 0) & 0xFFFF) +#define TIPC_SESS_NO(w5) (((w5) >> 16) & 0xFFFF) +#define TIPC_MSG_CNT(w9) (((w9) >> 16) & 0xFFFF) +#define TIPC_LINK_TOL(w9) (((w9) >> 0) & 0xFFFF) + +struct link_conf_tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; + u_int32_t dest_domain; + u_int32_t prev_node; + u_int32_t ntwrk_id; + u_int32_t w5; + u_int8_t media_address[16]; +}; + +#define TIPC_NODE_SIG(w1) (((w1) >> 0) & 0xFFFF) +#define TIPC_MEDIA_ID(w5) (((w5) >> 0) & 0xFF) + +static void +print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap) +{ + u_int32_t w0, w1, w2; + u_int user; + u_int hsize; + u_int msize; + u_int mtype; + u_int broadcast_ack; + u_int link_ack; + u_int link_seq; + u_int prev_node; + u_int orig_port; + u_int dest_port; + u_int orig_node; + u_int dest_node; + + ND_TCHECK(ap->dest_port); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + hsize = TIPC_HSIZE(w0); + msize = TIPC_MSIZE(w0); + w1 = EXTRACT_32BITS(&ap->w1); + mtype = TIPC_MTYPE(w1); + prev_node = EXTRACT_32BITS(&ap->prev_node); + orig_port = EXTRACT_32BITS(&ap->orig_port); + dest_port = EXTRACT_32BITS(&ap->dest_port); + if (hsize <= 6) { + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + TIPC_VER(w0), + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + orig_port, dest_port, + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipcmtype_values, "Unknown", mtype))); + } else { + ND_TCHECK(ap->dest_node); + orig_node = EXTRACT_32BITS(&ap->orig_node); + dest_node = EXTRACT_32BITS(&ap->dest_node); + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + TIPC_VER(w0), + TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node), + orig_port, + TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node), + dest_port, + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipcmtype_values, "Unknown", mtype))); + + if (ndo->ndo_vflag) { + broadcast_ack = TIPC_BROADCAST_ACK(w1); + w2 = EXTRACT_32BITS(&ap->w2); + link_ack = TIPC_LINK_ACK(w2); + link_seq = TIPC_LINK_SEQ(w2); + ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u", + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + broadcast_ack, link_ack, link_seq)); + } + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +static void +print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap) +{ + u_int32_t w0, w1, w2, w4, w5, w9; + u_int user; + u_int hsize; + u_int msize; + u_int mtype; + u_int seq_gap; + u_int broadcast_ack; + u_int bc_gap_after; + u_int bc_gap_to; + u_int prev_node; + u_int last_sent_frag; + u_int next_sent_frag; + u_int sess_no; + u_int orig_node; + u_int dest_node; + u_int trans_seq; + u_int msg_cnt; + u_int link_tol; + + ND_TCHECK(ap->dest_node); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + hsize = TIPC_HSIZE(w0); + msize = TIPC_MSIZE(w0); + w1 = EXTRACT_32BITS(&ap->w1); + mtype = TIPC_MTYPE(w1); + orig_node = EXTRACT_32BITS(&ap->orig_node); + dest_node = EXTRACT_32BITS(&ap->dest_node); + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)", + TIPC_VER(w0), + TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node), + TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node), + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipcmtype_values, "Unknown", mtype), w1)); + + if (ndo->ndo_vflag) { + ND_TCHECK(*ap); + seq_gap = TIPC_SEQ_GAP(w1); + broadcast_ack = TIPC_BROADCAST_ACK(w1); + w2 = EXTRACT_32BITS(&ap->w2); + bc_gap_after = TIPC_BC_GAP_AFTER(w2); + bc_gap_to = TIPC_BC_GAP_TO(w2); + prev_node = EXTRACT_32BITS(&ap->prev_node); + w4 = EXTRACT_32BITS(&ap->w4); + last_sent_frag = TIPC_LAST_SENT_FRAG(w4); + next_sent_frag = TIPC_NEXT_SENT_FRAG(w4); + w5 = EXTRACT_32BITS(&ap->w5); + sess_no = TIPC_SESS_NO(w5); + trans_seq = EXTRACT_32BITS(&ap->trans_seq); + w9 = EXTRACT_32BITS(&ap->w9); + msg_cnt = TIPC_MSG_CNT(w9); + link_tol = TIPC_LINK_TOL(w9); + ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u, Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u", + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to, + last_sent_frag, next_sent_frag, trans_seq, msg_cnt, + link_tol)); + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +static void +print_link_conf(netdissect_options *ndo, const struct link_conf_tipc_pkthdr *ap) +{ + u_int32_t w0, w1, w5; + u_int user; + u_int hsize; + u_int msize; + u_int mtype; + u_int node_sig; + u_int prev_node; + u_int dest_domain; + u_int ntwrk_id; + u_int media_id; + + ND_TCHECK(ap->prev_node); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + hsize = TIPC_HSIZE(w0); + msize = TIPC_MSIZE(w0); + w1 = EXTRACT_32BITS(&ap->w1); + mtype = TIPC_MTYPE(w1); + prev_node = EXTRACT_32BITS(&ap->prev_node); + dest_domain = EXTRACT_32BITS(&ap->dest_domain); + prev_node = EXTRACT_32BITS(&ap->prev_node); + + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + TIPC_VER(w0), + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + TIPC_ZONE(dest_domain), TIPC_CLUSTER(dest_domain), TIPC_NODE(dest_domain), + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipc_linkconf_mtype_values, "Unknown", mtype))); + if (ndo->ndo_vflag) { + ND_TCHECK(ap->w5); + node_sig = TIPC_NODE_SIG(w1); + ntwrk_id = EXTRACT_32BITS(&ap->ntwrk_id); + w5 = EXTRACT_32BITS(&ap->w5); + media_id = TIPC_MEDIA_ID(w5); + ND_PRINT((ndo, "\n\tNodeSignature %u, network_id %u, media_id %u", + node_sig, ntwrk_id, media_id)); + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +void +tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_, + u_int caplen _U_) +{ + const struct tipc_pkthdr *ap; + u_int32_t w0; + u_int user; + + ap = (struct tipc_pkthdr *)bp; + ND_TCHECK(ap->w0); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + + switch (user) + { + case TIPC_USER_LOW_IMPORTANCE: + case TIPC_USER_MEDIUM_IMPORTANCE: + case TIPC_USER_HIGH_IMPORTANCE: + case TIPC_USER_CRITICAL_IMPORTANCE: + case TIPC_USER_NAME_DISTRIBUTOR: + case TIPC_USER_CONN_MANAGER: + print_payload(ndo, (struct payload_tipc_pkthdr *)bp); + break; + + case TIPC_USER_LINK_CONFIG: + print_link_conf(ndo, (struct link_conf_tipc_pkthdr *)bp); + break; + + case TIPC_USER_BCAST_PROTOCOL: + case TIPC_USER_MSG_BUNDLER: + case TIPC_USER_LINK_PROTOCOL: + case TIPC_USER_CHANGEOVER_PROTOCOL: + case TIPC_USER_MSG_FRAGMENTER: + print_internal(ndo, (struct internal_tipc_pkthdr *)bp); + break; + + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +/* + * Local Variables: + * c-style: bsd + * End: + */ + diff --git a/contrib/tcpdump/tcpdump.1.in b/contrib/tcpdump/tcpdump.1.in index aabda77149..a9387f102a 100644 --- a/contrib/tcpdump/tcpdump.1.in +++ b/contrib/tcpdump/tcpdump.1.in @@ -200,7 +200,8 @@ Print the AS number in BGP packets in ASDOT notation rather than ASPLAIN notation. .TP .B \-B -Set the operating system capture buffer size to \fIbuffer_size\fP. +Set the operating system capture buffer size to \fIbuffer_size\fP, in +units of KiB (1024 bytes). .TP .B \-c Exit after receiving \fIcount\fP packets. @@ -392,9 +393,37 @@ Make stdout line buffered. Useful if you want to see the data while capturing it. E.g., -.br -``tcpdump\ \ \-l\ \ |\ \ tee dat'' or -``tcpdump\ \ \-l \ \ > dat\ \ &\ \ tail\ \ \-f\ \ dat''. +.IP +.RS +.RS +.nf +\fBtcpdump \-l | tee dat\fP +.fi +.RE +.RE +.IP +or +.IP +.RS +.RS +.nf +\fBtcpdump \-l > dat & tail \-f dat\fP +.fi +.RE +.RE +.IP +Note that on Windows,``line buffered'' means ``unbuffered'', so that +WinDump will write each character individually if +.B \-l +is specified. +.IP +.B \-U +is similar to +.B \-l +in its behavior, but it will cause output to be ``packet-buffered'', so +that the output is written to stdout at the end of each packet rather +than at the end of each line; this is buffered on all platforms, +including Windows. .TP .B \-L List the known data link types for the interface, in the specified mode, @@ -511,11 +540,20 @@ on each dump line. Print undecoded NFS handles. .TP .B \-U -Make output saved via the +If the +.B \-w +option is not specified, make the printed packet output +``packet-buffered''; i.e., as the description of the contents of each +packet is printed, it will be written to the standard output, rather +than, when not writing to a terminal, being written only when the output +buffer fills. +.IP +If the .B \-w -option ``packet-buffered''; i.e., as each packet is saved, it will be -written to the output file, rather than being written only when the -output buffer fills. +option is specified, make the saved raw packet output +``packet-buffered''; i.e., as each packet is saved, it will be written +to the output file, rather than being written only when the output +buffer fills. .IP The .B \-U @@ -557,6 +595,13 @@ Write the raw packets to \fIfile\fR rather than parsing and printing them out. They can later be printed with the \-r option. Standard output is used if \fIfile\fR is ``-''. +.IP +This output will be buffered if written to a file or pipe, so a program +reading from the file or pipe may not see packets for an arbitrary +amount of time after they are received. Use the +.B \-U +flag to cause packets to be written as soon as they are received. +.IP See .BR pcap-savefile (@MAN_FILE_FORMATS@) for a description of the file format. diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index ac35b2b349..587ed32170 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -87,6 +87,12 @@ extern int SIZE_BUF; #define NAME_MAX 255 #endif +#ifdef SIGINFO +#define SIGNAL_REQ_INFO SIGINFO +#elif SIGUSR1 +#define SIGNAL_REQ_INFO SIGUSR1 +#endif + netdissect_options Gndo; netdissect_options *gndo = &Gndo; @@ -119,7 +125,7 @@ static void ndo_error(netdissect_options *ndo, const char *fmt, ...) __attribute__ ((noreturn, format (printf, 2, 3))); static void ndo_warning(netdissect_options *ndo, const char *fmt, ...); -#ifdef SIGINFO +#ifdef SIGNAL_REQ_INFO RETSIGTYPE requestinfo(int); #endif @@ -1349,13 +1355,13 @@ main(int argc, char **argv) pcap_userdata = (u_char *)&printinfo; } -#ifdef SIGINFO +#ifdef SIGNAL_REQ_INFO /* * We can't get statistics when reading from a file rather * than capturing from a device. */ if (RFileName == NULL) - (void)setsignal(SIGINFO, requestinfo); + (void)setsignal(SIGNAL_REQ_INFO, requestinfo); #endif if (vflag > 0 && WFileName) { @@ -1844,7 +1850,7 @@ default_print(const u_char *bp, u_int length) ndo_default_print(gndo, bp, length); } -#ifdef SIGINFO +#ifdef SIGNAL_REQ_INFO RETSIGTYPE requestinfo(int signo _U_) { if (infodelay)