X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/cbe18055349fa44ac8348c56834c32586e0a81ab..d2777156522f139a858bd6b5b51e364826bc95a7:/print-bgp.c diff --git a/print-bgp.c b/print-bgp.c index 0abb7001..e13fdd91 100644 --- a/print-bgp.c +++ b/print-bgp.c @@ -263,12 +263,10 @@ static const struct tok bgp_notify_major_values[] = { { 0, NULL} }; -/* draft-ietf-idr-cease-subcode-02 */ +/* RFC 4486 */ #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1 -/* draft-ietf-idr-shutdown-07 */ #define BGP_NOTIFY_MINOR_CEASE_SHUT 2 #define BGP_NOTIFY_MINOR_CEASE_RESET 4 -#define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN 128 static const struct tok bgp_notify_minor_cease_values[] = { { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"}, { BGP_NOTIFY_MINOR_CEASE_SHUT, "Administrative Shutdown"}, @@ -557,8 +555,7 @@ static const struct tok bgp_add_path_recvsend[] = { { 0, NULL }, }; -/* allocate space for the largest possible string */ -static char astostr[sizeof("xxxxx.xxxxx")]; +#define AS_STR_SIZE sizeof("xxxxx.xxxxx") /* * as_printf @@ -598,20 +595,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 +639,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 +663,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,7 +676,6 @@ 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", GET_IPADDR_STRING(pptr)); break; case (sizeof(nd_ipv6) << 3): /* 128 */ @@ -696,7 +687,6 @@ bgp_vpn_ip_print(netdissect_options *ndo, } pos += strlen(pos); -trunc: *(pos) = '\0'; return (addr); } @@ -768,6 +758,8 @@ bgp_vpn_rd_print(netdissect_options *ndo, /* allocate space for the largest possible string */ static char rd[sizeof("xxxxx.xxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; char *pos = rd; + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; /* ok lets load the RD format */ switch (GET_BE_U_2(pptr)) { @@ -817,6 +809,8 @@ bgp_extended_community_print(netdissect_options *ndo, float f; uint32_t i; } bw; + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; switch (GET_BE_U_2(pptr)) { @@ -846,7 +840,7 @@ bgp_extended_community_print(netdissect_options *ndo, break; case BGP_EXT_COM_LINKBAND: - bw.i = GET_BE_U_4(pptr + 2); + bw.i = GET_BE_U_4(pptr + 4); ND_PRINT("bandwidth: %.3f Mbps", bw.f*8/1000000); break; @@ -919,9 +913,11 @@ bgp_rt_prefix_print(netdissect_options *ndo, u_int plen) { /* allocate space for the largest possible string */ - char rtc_prefix_in_hex[20] = ""; + char rtc_prefix_in_hex[sizeof("0000 0000 0000 0000")] = ""; u_int rtc_prefix_in_hex_len = 0; static char output[61]; /* max response string */ + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; uint16_t ec_type = 0; u_int octet_count; u_int i; @@ -953,7 +949,7 @@ bgp_rt_prefix_print(netdissect_options *ndo, /* * get the ext-comm type * Note: pptr references a static 8 octet buffer with unused bits set to 0, - * hense EXTRACT_*() macros are safe. + * hence EXTRACT_*() macros are safe. */ ec_type = EXTRACT_BE_U_2(pptr); switch (ec_type) { @@ -995,7 +991,8 @@ decode_rt_routing_info(netdissect_options *ndo, { uint8_t route_target[8]; u_int plen; - char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */ + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; u_int num_octets; /* NLRI "prefix length" from RFC 2858 Section 4. */ @@ -1017,7 +1014,7 @@ decode_rt_routing_info(netdissect_options *ndo, } /* With at least "origin AS", possibly with "route target". */ - as_printf(ndo, asbuf, sizeof(asbuf), GET_BE_U_4(pptr + 1)); + as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 1)); plen -= 32; /* adjust prefix length */ @@ -1032,20 +1029,17 @@ decode_rt_routing_info(netdissect_options *ndo, */ memset(&route_target, 0, sizeof(route_target)); num_octets = (plen + 7) / 8; - ND_TCHECK_LEN(pptr + 5, num_octets); - memcpy(&route_target, pptr + 5, num_octets); + GET_CPY_BYTES(&route_target, pptr + 5, num_octets); /* If mask-len is not on octet boundary, ensure all extra bits are 0 */ if (plen % 8) { ((u_char *)&route_target)[num_octets - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } ND_PRINT("\n\t origin AS: %s, %s", - asbuf, + astostr, bgp_rt_prefix_print(ndo, (u_char *)&route_target, plen)); return 5 + num_octets; -trunc: - return -2; } static int @@ -1066,8 +1060,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); @@ -1081,9 +1074,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; } /* @@ -1116,13 +1106,10 @@ 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), GET_IPADDR_STRING(vpn_ip), GET_IPADDR_STRING(pptr)); @@ -1155,6 +1142,8 @@ static int decode_multicast_vpn(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen) { + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; uint8_t route_type, route_length; u_int addr_length, sg_length; u_int offset; @@ -1386,9 +1375,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); @@ -1396,11 +1384,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 @@ -1426,8 +1411,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); @@ -1466,8 +1450,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); @@ -1481,9 +1464,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 @@ -1499,8 +1479,7 @@ decode_clnp_prefix(netdissect_options *ndo, 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); @@ -1511,9 +1490,6 @@ decode_clnp_prefix(netdissect_options *ndo, plen); return 1 + (plen + 7) / 8; - -trunc: - return -2; } static int @@ -1534,8 +1510,7 @@ 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); } @@ -1549,9 +1524,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; } /* @@ -1758,8 +1730,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); @@ -1785,15 +1755,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): @@ -1826,8 +1792,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); @@ -1853,8 +1817,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; @@ -1876,8 +1838,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; @@ -1887,8 +1847,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; @@ -1911,6 +1869,8 @@ bgp_attr_print(netdissect_options *ndo, uint8_t atype, const u_char *pptr, u_int len, const unsigned attr_set_level) { + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; u_int i; uint16_t af; uint8_t safi, snpa, nhlen; @@ -1980,7 +1940,6 @@ bgp_attr_print(netdissect_options *ndo, if (len != 4) ND_PRINT("invalid len"); else { - ND_TCHECK_4(tptr); ND_PRINT("%s", GET_IPADDR_STRING(tptr)); } break; @@ -2063,7 +2022,6 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT("invalid len"); break; } - ND_TCHECK_4(tptr); ND_PRINT("%s",GET_IPADDR_STRING(tptr)); break; case BGPTYPE_CLUSTER_LIST: @@ -2072,7 +2030,6 @@ bgp_attr_print(netdissect_options *ndo, break; } while (tlen != 0) { - ND_TCHECK_4(tptr); if (tlen < 4) goto trunc; ND_PRINT("%s%s", @@ -2126,7 +2083,6 @@ bgp_attr_print(netdissect_options *ndo, tlen -= tnhlen; tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); ND_PRINT("%s",GET_IPADDR_STRING(tptr)); tptr += sizeof(nd_ipv4); tnhlen -= sizeof(nd_ipv4); @@ -2142,8 +2098,6 @@ bgp_attr_print(netdissect_options *ndo, 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), GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN)); @@ -2195,7 +2149,6 @@ bgp_attr_print(netdissect_options *ndo, tlen -= tnhlen; tnhlen = 0; } else { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); ND_PRINT("%s", GET_IPADDR_STRING(tptr)); tptr += (sizeof(nd_ipv4)); tlen -= (sizeof(nd_ipv4)); @@ -2205,7 +2158,6 @@ bgp_attr_print(netdissect_options *ndo, case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - ND_TCHECK_LEN(tptr, tnhlen); ND_PRINT("%s", GET_ISONSAP_STRING(tptr, tnhlen)); tptr += tnhlen; tlen -= tnhlen; @@ -2382,7 +2334,6 @@ bgp_attr_print(netdissect_options *ndo, GET_IPADDR_STRING(tptr+4)); break; case BGP_PMSI_TUNNEL_INGRESS: - ND_TCHECK_4(tptr); ND_PRINT("\n\t Tunnel-Endpoint %s", GET_IPADDR_STRING(tptr)); break; @@ -2426,7 +2377,6 @@ bgp_attr_print(netdissect_options *ndo, /* * Check if we can read the TLV data. */ - ND_TCHECK_LEN(tptr + 3, length); if (tlen < length) goto trunc; @@ -2565,6 +2515,8 @@ static void bgp_capabilities_print(netdissect_options *ndo, const u_char *opt, u_int caps_len) { + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; u_int cap_type, cap_len, tcap_len, cap_offset; u_int i = 0; @@ -2693,6 +2645,8 @@ static void bgp_open_print(netdissect_options *ndo, const u_char *dat, u_int length) { + /* allocate space for the largest possible string */ + char astostr[AS_STR_SIZE]; const struct bgp_open *bgp_open_header; u_int optslen; const struct bgp_opt *bgpopt; @@ -2814,8 +2768,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); @@ -2849,6 +2801,9 @@ bgp_update_print(netdissect_options *ndo, } if (len) { + /* Make sure the path attributes don't go past the end of the packet */ + if (length < len) + goto trunc; /* do something more useful!*/ while (len) { uint8_t aflags, atype, alenlen; @@ -2931,8 +2886,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); @@ -2956,8 +2909,6 @@ bgp_notification_print(netdissect_options *ndo, const struct bgp_notification *bgp_notification_header; const u_char *tptr; uint8_t bgpn_major, bgpn_minor; - uint8_t shutdown_comm_length; - uint8_t remainder_offset; ND_TCHECK_LEN(dat, BGP_NOTIFICATION_SIZE); if (length= BGP_NOTIFICATION_SIZE + 7) { @@ -3023,18 +2974,17 @@ bgp_notification_print(netdissect_options *ndo, GET_BE_U_4(tptr + 3)); } /* - * draft-ietf-idr-shutdown describes a method to send a communication + * RFC 9003 describes a method to send a communication * intended for human consumption regarding the Administrative Shutdown */ if ((bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT || bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) && length >= BGP_NOTIFICATION_SIZE + 1) { tptr = dat + BGP_NOTIFICATION_SIZE; - shutdown_comm_length = GET_U_1(tptr); - remainder_offset = 0; + uint8_t shutdown_comm_length = GET_U_1(tptr); + uint8_t remainder_offset = 0; /* garbage, hexdump it all */ - if (shutdown_comm_length > BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN || - shutdown_comm_length > length - (BGP_NOTIFICATION_SIZE + 1)) { + if (shutdown_comm_length > length - (BGP_NOTIFICATION_SIZE + 1)) { ND_PRINT(", invalid Shutdown Communication length"); } else if (shutdown_comm_length == 0) { @@ -3043,7 +2993,6 @@ bgp_notification_print(netdissect_options *ndo, } /* a proper shutdown communication */ 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_PRINT("\"");