X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/756d0a1356a49efbd1a9f461f478913cb8163b23..383670e8f3f5b51d1017d8c1a678aa7eaf1f2b4d:/print-bgp.c diff --git a/print-bgp.c b/print-bgp.c index 36903d22..a2095372 100644 --- a/print-bgp.c +++ b/print-bgp.c @@ -557,7 +557,8 @@ static const struct tok bgp_add_path_recvsend[] = { { 0, NULL }, }; -static char astostr[20]; +/* allocate space for the largest possible string */ +static char astostr[sizeof("xxxxx.xxxxx")]; /* * as_printf @@ -589,7 +590,6 @@ decode_prefix4(netdissect_options *ndo, nd_ipv4 addr; u_int plen, plenbytes; - ND_TCHECK_1(pptr); ITEMCHECK(1); plen = GET_U_1(pptr); if (32 < plen) @@ -598,20 +598,16 @@ decode_prefix4(netdissect_options *ndo, memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; - ND_TCHECK_LEN(pptr + 1, plenbytes); ITEMCHECK(plenbytes); - memcpy(&addr, pptr + 1, plenbytes); + GET_CPY_BYTES(&addr, pptr + 1, plenbytes); if (plen % 8) { ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "%s/%u", ipaddr_string(ndo, (const u_char *)&addr), plen); return 1 + plenbytes; -trunc: - return -2; - badtlv: - return -3; + return -2; } static int @@ -646,9 +642,8 @@ decode_labeled_prefix4(netdissect_options *ndo, memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; - ND_TCHECK_LEN(pptr + 4, plenbytes); ITEMCHECK(plenbytes); - memcpy(&addr, pptr + 4, plenbytes); + GET_CPY_BYTES(&addr, pptr + 4, plenbytes); if (plen % 8) { ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } @@ -671,7 +666,7 @@ badtlv: /* * bgp_vpn_ip_print * - * print an ipv4 or ipv6 address into a buffer dependend on address length. + * print an ipv4 or ipv6 address into a buffer dependent on address length. */ static char * bgp_vpn_ip_print(netdissect_options *ndo, @@ -684,12 +679,10 @@ bgp_vpn_ip_print(netdissect_options *ndo, switch(addr_length) { case (sizeof(nd_ipv4) << 3): /* 32 */ - ND_TCHECK_LEN(pptr, sizeof(nd_ipv4)); - snprintf(pos, sizeof(addr), "%s", ipaddr_string(ndo, pptr)); + snprintf(pos, sizeof(addr), "%s", GET_IPADDR_STRING(pptr)); break; case (sizeof(nd_ipv6) << 3): /* 128 */ - ND_TCHECK_LEN(pptr, sizeof(nd_ipv6)); - snprintf(pos, sizeof(addr), "%s", ip6addr_string(ndo, pptr)); + snprintf(pos, sizeof(addr), "%s", GET_IP6ADDR_STRING(pptr)); break; default: snprintf(pos, sizeof(addr), "bogus address length %u", addr_length); @@ -697,7 +690,6 @@ bgp_vpn_ip_print(netdissect_options *ndo, } pos += strlen(pos); -trunc: *(pos) = '\0'; return (addr); } @@ -730,7 +722,6 @@ bgp_vpn_sg_print(netdissect_options *ndo, total_length = 0; /* Source address length, encoded in bits */ - ND_TCHECK_1(pptr); addr_length = GET_U_1(pptr); pptr++; @@ -745,7 +736,6 @@ bgp_vpn_sg_print(netdissect_options *ndo, } /* Group address length, encoded in bits */ - ND_TCHECK_1(pptr); addr_length = GET_U_1(pptr); pptr++; @@ -769,7 +759,7 @@ bgp_vpn_rd_print(netdissect_options *ndo, const u_char *pptr) { /* allocate space for the largest possible string */ - static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; + static char rd[sizeof("xxxxx.xxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; char *pos = rd; /* ok lets load the RD format */ @@ -829,7 +819,7 @@ bgp_extended_community_print(netdissect_options *ndo, ND_PRINT("%u:%u (= %s)", GET_BE_U_2(pptr + 2), GET_BE_U_4(pptr + 4), - ipaddr_string(ndo, pptr+4)); + GET_IPADDR_STRING(pptr+4)); break; case BGP_EXT_COM_RT_1: @@ -837,7 +827,7 @@ bgp_extended_community_print(netdissect_options *ndo, case BGP_EXT_COM_L2VPN_RT_1: case BGP_EXT_COM_VRF_RT_IMP: ND_PRINT("%s:%u", - ipaddr_string(ndo, pptr+2), + GET_IPADDR_STRING(pptr+2), GET_BE_U_2(pptr + 6)); break; @@ -860,13 +850,13 @@ bgp_extended_community_print(netdissect_options *ndo, case BGP_EXT_COM_VPN_ORIGIN4: case BGP_EXT_COM_OSPF_RID: case BGP_EXT_COM_OSPF_RID2: - ND_PRINT("%s", ipaddr_string(ndo, pptr+2)); + ND_PRINT("%s", GET_IPADDR_STRING(pptr+2)); break; case BGP_EXT_COM_OSPF_RTYPE: case BGP_EXT_COM_OSPF_RTYPE2: ND_PRINT("area:%s, router-type:%s, metric-type:%s%s", - ipaddr_string(ndo, pptr+2), + GET_IPADDR_STRING(pptr+2), tok2str(bgp_extd_comm_ospf_rtype_values, "unknown (0x%02x)", GET_U_1((pptr + 6))), @@ -905,16 +895,103 @@ bgp_extended_community_print(netdissect_options *ndo, } } +/* + * RFC4684 (Section 4)/RFC2858 (Section 4). + * RTC membership prefix is structured as follows + * [prefix-len] [origin-as] [route-target] + * The route-target is encoded as RT ext-comms. + * Prefix-len may be 0, 32..96 + * + * Note that pptr is not packet data - it is + * a buffer owned by our caller - therefore GET_* + * macros can not be used. + */ +static char * +bgp_rt_prefix_print(netdissect_options *ndo, + const u_char *pptr, + u_int plen) +{ + /* allocate space for the largest possible string */ + char rtc_prefix_in_hex[20] = ""; + u_int rtc_prefix_in_hex_len = 0; + static char output[61]; /* max response string */ + uint16_t ec_type = 0; + u_int octet_count; + u_int i; + + if (plen == 0) { + snprintf(output, sizeof(output), "route-target: 0:0/0"); + return (output); + } + + /* hex representation of the prefix */ + octet_count = (plen+7)/8; + for (i=0; i> (plen % 8)) & 0xff); + } + ND_PRINT("\n\t origin AS: %s, %s", + asbuf, + bgp_rt_prefix_print(ndo, (u_char *)&route_target, plen)); -trunc: - return -2; + return 5 + num_octets; } static int @@ -962,7 +1045,6 @@ decode_labeled_vpn_prefix4(netdissect_options *ndo, nd_ipv4 addr; u_int plen; - ND_TCHECK_1(pptr); plen = GET_U_1(pptr); /* get prefix length */ if ((24+64) > plen) @@ -974,8 +1056,7 @@ decode_labeled_vpn_prefix4(netdissect_options *ndo, return -1; memset(&addr, 0, sizeof(addr)); - ND_TCHECK_LEN(pptr + 12, (plen + 7) / 8); - memcpy(&addr, pptr + 12, (plen + 7) / 8); + GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8); if (plen % 8) { ((u_char *)&addr)[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); @@ -989,9 +1070,6 @@ decode_labeled_vpn_prefix4(netdissect_options *ndo, ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 12 + (plen + 7) / 8; - -trunc: - return -2; } /* @@ -1013,8 +1091,6 @@ decode_mdt_vpn_nlri(netdissect_options *ndo, const u_char *rd; const u_char *vpn_ip; - ND_TCHECK_1(pptr); - /* if the NLRI is not predefined length, quit.*/ if (GET_U_1(pptr) != MDT_VPN_NLRI_LEN * 8) return -1; @@ -1026,15 +1102,12 @@ decode_mdt_vpn_nlri(netdissect_options *ndo, pptr += 8; /* IPv4 address */ - ND_TCHECK_LEN(pptr, sizeof(nd_ipv4)); vpn_ip = pptr; pptr += sizeof(nd_ipv4); /* MDT Group Address */ - ND_TCHECK_LEN(pptr, sizeof(nd_ipv4)); - snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s", - bgp_vpn_rd_print(ndo, rd), ipaddr_string(ndo, vpn_ip), ipaddr_string(ndo, pptr)); + bgp_vpn_rd_print(ndo, rd), GET_IPADDR_STRING(vpn_ip), GET_IPADDR_STRING(pptr)); return MDT_VPN_NLRI_LEN + 1; @@ -1069,7 +1142,6 @@ decode_multicast_vpn(netdissect_options *ndo, u_int addr_length, sg_length; u_int offset; - ND_TCHECK_2(pptr); route_type = GET_U_1(pptr); pptr++; route_length = GET_U_1(pptr); @@ -1178,7 +1250,6 @@ decode_labeled_vpn_l2(netdissect_options *ndo, u_int plen, tlen, tlv_type, tlv_len, ttlv_len; int stringlen; - ND_TCHECK_2(pptr); plen = GET_BE_U_2(pptr); tlen = plen; pptr += 2; @@ -1192,7 +1263,7 @@ decode_labeled_vpn_l2(netdissect_options *ndo, buf[0] = '\0'; stringlen = snprintf(buf, buflen, "RD: %s, BGPNH: %s", bgp_vpn_rd_print(ndo, pptr), - ipaddr_string(ndo, pptr+8)); + GET_IPADDR_STRING(pptr+8)); UPDATE_BUF_BUFLEN(buf, buflen, stringlen); pptr += 12; tlen -= 12; @@ -1221,7 +1292,6 @@ decode_labeled_vpn_l2(netdissect_options *ndo, } return plen + 2; } - ND_TCHECK_3(pptr); tlv_type = GET_U_1(pptr); pptr++; tlv_len = GET_BE_U_2(pptr); /* length, in *bits* */ @@ -1291,7 +1361,6 @@ decode_prefix6(netdissect_options *ndo, nd_ipv6 addr; u_int plen, plenbytes; - ND_TCHECK_1(pd); ITEMCHECK(1); plen = GET_U_1(pd); if (128 < plen) @@ -1300,9 +1369,8 @@ decode_prefix6(netdissect_options *ndo, memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; - ND_TCHECK_LEN(pd + 1, plenbytes); ITEMCHECK(plenbytes); - memcpy(&addr, pd + 1, plenbytes); + GET_CPY_BYTES(&addr, pd + 1, plenbytes); if (plen % 8) { addr[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); @@ -1310,11 +1378,8 @@ decode_prefix6(netdissect_options *ndo, snprintf(buf, buflen, "%s/%u", ip6addr_string(ndo, (const u_char *)&addr), plen); return 1 + plenbytes; -trunc: - return -2; - badtlv: - return -3; + return -2; } static int @@ -1340,8 +1405,7 @@ decode_labeled_prefix6(netdissect_options *ndo, memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; - ND_TCHECK_LEN(pptr + 4, plenbytes); - memcpy(&addr, pptr + 4, plenbytes); + GET_CPY_BYTES(&addr, pptr + 4, plenbytes); if (plen % 8) { addr[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); @@ -1369,7 +1433,6 @@ decode_labeled_vpn_prefix6(netdissect_options *ndo, nd_ipv6 addr; u_int plen; - ND_TCHECK_1(pptr); plen = GET_U_1(pptr); /* get prefix length */ if ((24+64) > plen) @@ -1381,8 +1444,7 @@ decode_labeled_vpn_prefix6(netdissect_options *ndo, return -1; memset(&addr, 0, sizeof(addr)); - ND_TCHECK_LEN(pptr + 12, (plen + 7) / 8); - memcpy(&addr, pptr + 12, (plen + 7) / 8); + GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8); if (plen % 8) { addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); @@ -1396,9 +1458,6 @@ decode_labeled_vpn_prefix6(netdissect_options *ndo, ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 12 + (plen + 7) / 8; - -trunc: - return -2; } static int @@ -1408,27 +1467,23 @@ decode_clnp_prefix(netdissect_options *ndo, uint8_t addr[19]; u_int plen; - ND_TCHECK_1(pptr); plen = GET_U_1(pptr); /* get prefix length */ if (152 < plen) return -1; memset(&addr, 0, sizeof(addr)); - ND_TCHECK_LEN(pptr + 4, (plen + 7) / 8); - memcpy(&addr, pptr + 4, (plen + 7) / 8); + GET_CPY_BYTES(&addr, pptr + 4, (plen + 7) / 8); if (plen % 8) { addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } + /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */ snprintf(buf, buflen, "%s/%u", isonsap_string(ndo, addr,(plen + 7) / 8), plen); return 1 + (plen + 7) / 8; - -trunc: - return -2; } static int @@ -1438,7 +1493,6 @@ decode_labeled_vpn_clnp_prefix(netdissect_options *ndo, uint8_t addr[19]; u_int plen; - ND_TCHECK_1(pptr); plen = GET_U_1(pptr); /* get prefix length */ if ((24+64) > plen) @@ -1450,12 +1504,12 @@ decode_labeled_vpn_clnp_prefix(netdissect_options *ndo, return -1; memset(&addr, 0, sizeof(addr)); - ND_TCHECK_LEN(pptr + 12, (plen + 7) / 8); - memcpy(&addr, pptr + 12, (plen + 7) / 8); + GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8); if (plen % 8) { addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ + /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */ snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s", bgp_vpn_rd_print(ndo, pptr+4), isonsap_string(ndo, addr,(plen + 7) / 8), @@ -1464,9 +1518,6 @@ decode_labeled_vpn_clnp_prefix(netdissect_options *ndo, ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 12 + (plen + 7) / 8; - -trunc: - return -2; } /* @@ -1496,15 +1547,12 @@ bgp_attr_get_as_size(netdissect_options *ndo, * each. */ while (tptr < pptr + len) { - ND_TCHECK_1(tptr); - /* * If we do not find a valid segment type, our guess might be wrong. */ if (GET_U_1(tptr) < BGP_AS_SEG_TYPE_MIN || GET_U_1(tptr) > BGP_AS_SEG_TYPE_MAX) { goto trunc; } - ND_TCHECK_1(tptr + 1); tptr += 2 + GET_U_1(tptr + 1) * 2; } @@ -1676,8 +1724,6 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, if (advance == -1) ND_PRINT("\n\t (illegal prefix length)"); else if (advance == -2) - goto trunc; - else if (advance == -3) break; /* bytes left, but not enough */ else ND_PRINT("\n\t %s", buf); @@ -1703,15 +1749,11 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, buflen); if (advance == -1) ND_PRINT("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; else ND_PRINT("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): advance = decode_rt_routing_info(ndo, tptr); - if (advance == -2) - goto trunc; break; case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): @@ -1744,8 +1786,6 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, if (advance == -1) ND_PRINT("\n\t (illegal prefix length)"); else if (advance == -2) - goto trunc; - else if (advance == -3) break; /* bytes left, but not enough */ else ND_PRINT("\n\t %s", buf); @@ -1771,8 +1811,6 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, buflen); if (advance == -1) ND_PRINT("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; else ND_PRINT("\n\t %s", buf); break; @@ -1794,8 +1832,6 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, advance = decode_clnp_prefix(ndo, tptr, buf, buflen); if (advance == -1) ND_PRINT("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; else ND_PRINT("\n\t %s", buf); break; @@ -1805,8 +1841,6 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, buflen); if (advance == -1) ND_PRINT("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; else ND_PRINT("\n\t %s", buf); break; @@ -1848,7 +1882,6 @@ bgp_attr_print(netdissect_options *ndo, if (len != 1) ND_PRINT("invalid len"); else { - ND_TCHECK_1(tptr); ND_PRINT("%s", tok2str(bgp_origin_values, "Unknown Origin Typecode", GET_U_1(tptr))); @@ -1880,10 +1913,8 @@ bgp_attr_print(netdissect_options *ndo, as_size = bgp_attr_get_as_size(ndo, atype, pptr, len); while (tptr < pptr + len) { - ND_TCHECK_1(tptr); ND_PRINT("%s", tok2str(bgp_as_path_segment_open_values, "?", GET_U_1(tptr))); - ND_TCHECK_1(tptr + 1); for (i = 0; i < GET_U_1(tptr + 1) * as_size; i += as_size) { ND_TCHECK_LEN(tptr + 2 + i, as_size); ND_PRINT("%s ", @@ -1892,10 +1923,8 @@ bgp_attr_print(netdissect_options *ndo, GET_BE_U_2(tptr + i + 2) : GET_BE_U_4(tptr + i + 2))); } - ND_TCHECK_1(tptr); ND_PRINT("%s", tok2str(bgp_as_path_segment_close_values, "?", GET_U_1(tptr))); - ND_TCHECK_1(tptr + 1); tptr += 2 + GET_U_1(tptr + 1) * as_size; } break; @@ -1903,8 +1932,7 @@ bgp_attr_print(netdissect_options *ndo, if (len != 4) ND_PRINT("invalid len"); else { - ND_TCHECK_4(tptr); - ND_PRINT("%s", ipaddr_string(ndo, tptr)); + ND_PRINT("%s", GET_IPADDR_STRING(tptr)); } break; case BGPTYPE_MULTI_EXIT_DISC: @@ -1912,7 +1940,6 @@ bgp_attr_print(netdissect_options *ndo, if (len != 4) ND_PRINT("invalid len"); else { - ND_TCHECK_4(tptr); ND_PRINT("%u", GET_BE_U_4(tptr)); } break; @@ -1934,11 +1961,11 @@ bgp_attr_print(netdissect_options *ndo, if (len == 6) { ND_PRINT(" AS #%s, origin %s", as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(tptr)), - ipaddr_string(ndo, tptr + 2)); + GET_IPADDR_STRING(tptr + 2)); } else { ND_PRINT(" AS #%s, origin %s", as_printf(ndo, astostr, sizeof(astostr), - GET_BE_U_4(tptr)), ipaddr_string(ndo, tptr + 4)); + GET_BE_U_4(tptr)), GET_IPADDR_STRING(tptr + 4)); } break; case BGPTYPE_AGGREGATOR4: @@ -1946,10 +1973,9 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT("invalid len"); break; } - ND_TCHECK_8(tptr); ND_PRINT(" AS #%s, origin %s", as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr)), - ipaddr_string(ndo, tptr + 4)); + GET_IPADDR_STRING(tptr + 4)); break; case BGPTYPE_COMMUNITIES: if (len % 4) { @@ -1988,8 +2014,7 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT("invalid len"); break; } - ND_TCHECK_4(tptr); - ND_PRINT("%s",ipaddr_string(ndo, tptr)); + ND_PRINT("%s",GET_IPADDR_STRING(tptr)); break; case BGPTYPE_CLUSTER_LIST: if (len % 4) { @@ -1997,11 +2022,10 @@ bgp_attr_print(netdissect_options *ndo, break; } while (tlen != 0) { - ND_TCHECK_4(tptr); if (tlen < 4) goto trunc; ND_PRINT("%s%s", - ipaddr_string(ndo, tptr), + GET_IPADDR_STRING(tptr), (tlen>4) ? ", " : ""); tlen -=4; tptr +=4; @@ -2017,17 +2041,23 @@ bgp_attr_print(netdissect_options *ndo, if (ret < 0) break; - tptr +=3; + tptr += 3; + tlen -= 3; ND_TCHECK_1(tptr); + if (tlen < 1) + goto trunc; nhlen = GET_U_1(tptr); - tlen = nhlen; tptr++; + tlen--; - if (tlen) { + if (nhlen) { u_int nnh = 0; + uint8_t tnhlen = nhlen; + if (tlen < tnhlen) + goto trunc; ND_PRINT("\n\t nexthop: "); - while (tlen != 0) { + while (tnhlen != 0) { if (nnh++ > 0) { ND_PRINT(", " ); } @@ -2039,104 +2069,115 @@ bgp_attr_print(netdissect_options *ndo, case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): case (AFNUM_INET<<8 | SAFNUM_MDT): - if (tlen < sizeof(nd_ipv4)) { + if (tnhlen < sizeof(nd_ipv4)) { ND_PRINT("invalid len"); - tlen = 0; + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); - ND_PRINT("%s",ipaddr_string(ndo, tptr)); - tlen -= sizeof(nd_ipv4); + ND_PRINT("%s",GET_IPADDR_STRING(tptr)); tptr += sizeof(nd_ipv4); + tnhlen -= sizeof(nd_ipv4); + tlen -= sizeof(nd_ipv4); } break; case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < sizeof(nd_ipv4)+BGP_VPN_RD_LEN) { + if (tnhlen < sizeof(nd_ipv4)+BGP_VPN_RD_LEN) { ND_PRINT("invalid len"); - tlen = 0; + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, - sizeof(nd_ipv4) + BGP_VPN_RD_LEN); ND_PRINT("RD: %s, %s", bgp_vpn_rd_print(ndo, tptr), - ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN)); - tlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN); + GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN)); tptr += (sizeof(nd_ipv4)+BGP_VPN_RD_LEN); + tlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN); + tnhlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN); } break; case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): - if (tlen < sizeof(nd_ipv6)) { + if (tnhlen < sizeof(nd_ipv6)) { ND_PRINT("invalid len"); - tlen = 0; + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv6)); - ND_PRINT("%s", ip6addr_string(ndo, tptr)); - tlen -= sizeof(nd_ipv6); + ND_PRINT("%s", GET_IP6ADDR_STRING(tptr)); tptr += sizeof(nd_ipv6); + tlen -= sizeof(nd_ipv6); + tnhlen -= sizeof(nd_ipv6); } break; case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < sizeof(nd_ipv6)+BGP_VPN_RD_LEN) { + if (tnhlen < sizeof(nd_ipv6)+BGP_VPN_RD_LEN) { ND_PRINT("invalid len"); - tlen = 0; + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, - sizeof(nd_ipv6) + BGP_VPN_RD_LEN); ND_PRINT("RD: %s, %s", bgp_vpn_rd_print(ndo, tptr), - ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN)); - tlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN); + GET_IP6ADDR_STRING(tptr+BGP_VPN_RD_LEN)); tptr += (sizeof(nd_ipv6)+BGP_VPN_RD_LEN); + tlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN); + tnhlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN); } break; case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < sizeof(nd_ipv4)) { + if (tnhlen < sizeof(nd_ipv4)) { ND_PRINT("invalid len"); - tlen = 0; + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); - ND_PRINT("%s", ipaddr_string(ndo, tptr)); - tlen -= (sizeof(nd_ipv4)); + ND_PRINT("%s", GET_IPADDR_STRING(tptr)); tptr += (sizeof(nd_ipv4)); + tlen -= (sizeof(nd_ipv4)); + tnhlen -= (sizeof(nd_ipv4)); } break; case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - ND_TCHECK_LEN(tptr, tlen); - ND_PRINT("%s", isonsap_string(ndo, tptr, tlen)); - tptr += tlen; - tlen = 0; + ND_PRINT("%s", GET_ISONSAP_STRING(tptr, tnhlen)); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; break; case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): - if (tlen < BGP_VPN_RD_LEN+1) { + if (tnhlen < BGP_VPN_RD_LEN+1) { ND_PRINT("invalid len"); - tlen = 0; + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, tlen); + ND_TCHECK_LEN(tptr, tnhlen); ND_PRINT("RD: %s, %s", bgp_vpn_rd_print(ndo, tptr), - isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)); + GET_ISONSAP_STRING(tptr+BGP_VPN_RD_LEN,tnhlen-BGP_VPN_RD_LEN)); /* rfc986 mapped IPv4 address ? */ if (GET_BE_U_4(tptr + BGP_VPN_RD_LEN) == 0x47000601) - ND_PRINT(" = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4)); + ND_PRINT(" = %s", GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN+4)); /* rfc1888 mapped IPv6 address ? */ else if (GET_BE_U_3(tptr + BGP_VPN_RD_LEN) == 0x350000) - ND_PRINT(" = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3)); - tptr += tlen; - tlen = 0; + ND_PRINT(" = %s", GET_IP6ADDR_STRING(tptr+BGP_VPN_RD_LEN+3)); + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; } break; default: @@ -2145,26 +2186,38 @@ bgp_attr_print(netdissect_options *ndo, * an unsupported AFI/SAFI. */ ND_PRINT("ERROR: no AFI %u/SAFI %u nexthop decoder", af, safi); - tptr += tlen; - tlen = 0; + tptr += tnhlen; + tlen -= tnhlen; + tnhlen = 0; goto done; break; } } } ND_PRINT(", nh-length: %u", nhlen); - tptr += tlen; - ND_TCHECK_1(tptr); + /* As per RFC 2858; this is reserved in RFC 4760 */ + if (tlen < 1) + goto trunc; snpa = GET_U_1(tptr); tptr++; + tlen--; if (snpa) { ND_PRINT("\n\t %u SNPA", snpa); for (/*nothing*/; snpa != 0; snpa--) { - ND_TCHECK_1(tptr); - ND_PRINT("\n\t %u bytes", GET_U_1(tptr)); - tptr += GET_U_1(tptr) + 1; + uint8_t snpalen; + if (tlen < 1) + goto trunc; + snpalen = GET_U_1(tptr); + ND_PRINT("\n\t %u bytes", snpalen); + tptr++; + tlen--; + if (tlen < snpalen) + goto trunc; + ND_TCHECK_LEN(tptr, snpalen); + tptr += snpalen; + tlen -= snpalen; } } else { ND_PRINT(", no SNPA"); @@ -2249,7 +2302,6 @@ bgp_attr_print(netdissect_options *ndo, goto trunc; flags = GET_U_1(tptr); tunnel_type = GET_U_1(tptr + 1); - tlen = len; ND_PRINT("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), @@ -2263,34 +2315,29 @@ bgp_attr_print(netdissect_options *ndo, switch (tunnel_type) { case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ case BGP_PMSI_TUNNEL_PIM_BIDIR: - ND_TCHECK_8(tptr); ND_PRINT("\n\t Sender %s, P-Group %s", - ipaddr_string(ndo, tptr), - ipaddr_string(ndo, tptr+4)); + GET_IPADDR_STRING(tptr), + GET_IPADDR_STRING(tptr+4)); break; case BGP_PMSI_TUNNEL_PIM_SSM: - ND_TCHECK_8(tptr); ND_PRINT("\n\t Root-Node %s, P-Group %s", - ipaddr_string(ndo, tptr), - ipaddr_string(ndo, tptr+4)); + GET_IPADDR_STRING(tptr), + GET_IPADDR_STRING(tptr+4)); break; case BGP_PMSI_TUNNEL_INGRESS: - ND_TCHECK_4(tptr); ND_PRINT("\n\t Tunnel-Endpoint %s", - ipaddr_string(ndo, tptr)); + GET_IPADDR_STRING(tptr)); break; case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ case BGP_PMSI_TUNNEL_LDP_MP2MP: - ND_TCHECK_8(tptr); ND_PRINT("\n\t Root-Node %s, LSP-ID 0x%08x", - ipaddr_string(ndo, tptr), + GET_IPADDR_STRING(tptr), GET_BE_U_4(tptr + 4)); break; case BGP_PMSI_TUNNEL_RSVP_P2MP: - ND_TCHECK_8(tptr); ND_PRINT("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", - ipaddr_string(ndo, tptr), + GET_IPADDR_STRING(tptr), GET_BE_U_4(tptr + 4)); break; default: @@ -2305,12 +2352,7 @@ bgp_attr_print(netdissect_options *ndo, uint8_t type; uint16_t length; - tlen = len; - while (tlen >= 3) { - - ND_TCHECK_3(tptr); - type = GET_U_1(tptr); length = GET_BE_U_2(tptr + 1); tptr += 3; @@ -2431,7 +2473,6 @@ bgp_attr_print(netdissect_options *ndo, } ND_PRINT("\n\t "); while (len != 0) { - ND_TCHECK_LEN(tptr, 12); ND_PRINT("%u:%u:%u%s", GET_BE_U_4(tptr), GET_BE_U_4(tptr + 4), @@ -2613,7 +2654,7 @@ bgp_open_print(netdissect_options *ndo, as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(bgp_open_header->bgpo_myas))); ND_PRINT("Holdtime %us, ", GET_BE_U_2(bgp_open_header->bgpo_holdtime)); - ND_PRINT("ID %s", ipaddr_string(ndo, bgp_open_header->bgpo_id)); + ND_PRINT("ID %s", GET_IPADDR_STRING(bgp_open_header->bgpo_id)); optslen = GET_U_1(bgp_open_header->bgpo_optlen); ND_PRINT("\n\t Optional parameters, length: %u", optslen); @@ -2716,8 +2757,6 @@ bgp_update_print(netdissect_options *ndo, ND_PRINT("\n\t (illegal prefix length)"); break; } else if (wpfx == -2) - goto trunc; - else if (wpfx == -3) goto trunc; /* bytes left, but not enough */ else { ND_PRINT("\n\t %s", buf); @@ -2833,8 +2872,6 @@ bgp_update_print(netdissect_options *ndo, ND_PRINT("\n\t (illegal prefix length)"); break; } else if (i == -2) - goto trunc; - else if (i == -3) goto trunc; /* bytes left, but not enough */ else { ND_PRINT("\n\t %s", buf); @@ -2917,7 +2954,6 @@ bgp_notification_print(netdissect_options *ndo, */ if(bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) { tptr = dat + BGP_NOTIFICATION_SIZE; - ND_TCHECK_7(tptr); ND_PRINT(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", tok2str(af_values, "Unknown", GET_BE_U_2(tptr)), GET_BE_U_2(tptr), @@ -2933,7 +2969,6 @@ bgp_notification_print(netdissect_options *ndo, bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) && length >= BGP_NOTIFICATION_SIZE + 1) { tptr = dat + BGP_NOTIFICATION_SIZE; - ND_TCHECK_1(tptr); shutdown_comm_length = GET_U_1(tptr); remainder_offset = 0; /* garbage, hexdump it all */ @@ -2949,7 +2984,7 @@ bgp_notification_print(netdissect_options *ndo, else { ND_TCHECK_LEN(tptr + 1, shutdown_comm_length); ND_PRINT(", Shutdown Communication (length: %u): \"", shutdown_comm_length); - (void)nd_printn(ndo, tptr+1, shutdown_comm_length, NULL); + nd_printjn(ndo, tptr+1, shutdown_comm_length); ND_PRINT("\""); remainder_offset += shutdown_comm_length + 1; }