X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/5ef0bcb5edd748de9d9af13c40da0395dfdd94e8..6d3b0e4599c5aa922bba42e53b038b51d9024a62:/print-bgp.c diff --git a/print-bgp.c b/print-bgp.c index ab3e2835..ba927e4b 100644 --- a/print-bgp.c +++ b/print-bgp.c @@ -80,13 +80,15 @@ struct bgp_open { nd_uint16_t bgpo_holdtime; nd_uint32_t bgpo_id; nd_uint8_t bgpo_optlen; + nd_uint8_t bgpo_opttype; /* RFC9072 */ + nd_uint16_t bgpo_optlen_extended; /* RFC9072 */ /* options should follow */ }; #define BGP_OPEN_SIZE 29 /* unaligned */ struct bgp_opt { - nd_uint8_t bgpopt_type; - nd_uint8_t bgpopt_len; + nd_uint8_t bgpopt_type; + nd_uint16_t bgpopt_len; /* Can be one or two bytes, depending on RFC9072 */ /* variable length */ }; #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ @@ -106,10 +108,22 @@ struct bgp_route_refresh { nd_uint16_t len; nd_uint8_t type; /* No padding after this; afi is, in fact, not aligned */ nd_uint16_t afi; - nd_uint8_t res; + nd_uint8_t subtype; nd_uint8_t safi; }; #define BGP_ROUTE_REFRESH_SIZE 23 +#define BGP_ROUTE_REFRESH_SUBTYPE_NORMAL 0 +#define BGP_ROUTE_REFRESH_SUBTYPE_BORR 1 +#define BGP_ROUTE_REFRESH_SUBTYPE_EORR 2 +#define BGP_ROUTE_REFRESH_SUBTYPE_RESERVED 255 + +static const struct tok bgp_route_refresh_subtype_values[] = { + {BGP_ROUTE_REFRESH_SUBTYPE_NORMAL, "Normal route refresh request"}, + {BGP_ROUTE_REFRESH_SUBTYPE_BORR, + "Demarcation of the beginning of a route refresh"}, + {BGP_ROUTE_REFRESH_SUBTYPE_EORR, + "Demarcation of the ending of a route refresh"}, + {0, NULL}}; #define bgp_attr_lenlen(flags, p) \ (((flags) & 0x10) ? 2U : 1U) @@ -126,9 +140,6 @@ struct bgp_route_refresh { #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ #define BGPTYPE_ORIGINATOR_ID 9 /* RFC4456 */ #define BGPTYPE_CLUSTER_LIST 10 /* RFC4456 */ -#define BGPTYPE_DPA 11 /* deprecated, draft-ietf-idr-bgp-dpa */ -#define BGPTYPE_ADVERTISERS 12 /* deprecated RFC1863 */ -#define BGPTYPE_RCID_PATH 13 /* deprecated RFC1863 */ #define BGPTYPE_MP_REACH_NLRI 14 /* RFC4760 */ #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC4760 */ #define BGPTYPE_EXTD_COMMUNITIES 16 /* RFC4360 */ @@ -159,9 +170,6 @@ static const struct tok bgp_attr_values[] = { { BGPTYPE_COMMUNITIES, "Community"}, { BGPTYPE_ORIGINATOR_ID, "Originator ID"}, { BGPTYPE_CLUSTER_LIST, "Cluster List"}, - { BGPTYPE_DPA, "DPA"}, - { BGPTYPE_ADVERTISERS, "Advertisers"}, - { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"}, { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"}, { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"}, { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"}, @@ -216,13 +224,14 @@ static const struct tok bgp_opt_values[] = { #define BGP_CAPCODE_ORF 3 /* RFC5291 */ #define BGP_CAPCODE_MR 4 /* RFC3107 */ #define BGP_CAPCODE_EXT_NH 5 /* RFC5549 */ +#define BGP_CAPCODE_EXT_MSG 6 /* RFC8654 */ #define BGP_CAPCODE_ML 8 /* RFC8277 */ #define BGP_CAPCODE_RESTART 64 /* RFC4724 */ #define BGP_CAPCODE_AS_NEW 65 /* RFC6793 */ #define BGP_CAPCODE_DYN_CAP 67 /* draft-ietf-idr-dynamic-cap */ #define BGP_CAPCODE_MULTISESS 68 /* draft-ietf-idr-bgp-multisession */ #define BGP_CAPCODE_ADD_PATH 69 /* RFC7911 */ -#define BGP_CAPCODE_ENH_RR 70 /* draft-keyur-bgp-enhanced-route-refresh */ +#define BGP_CAPCODE_ENH_RR 70 /* RFC7313 */ #define BGP_CAPCODE_LLGR 71 /* draft-uttaro-idr-bgp-persistence-05 */ #define BGP_CAPCODE_RR_CISCO 128 @@ -232,6 +241,7 @@ static const struct tok bgp_capcode_values[] = { { BGP_CAPCODE_ORF, "Cooperative Route Filtering"}, { BGP_CAPCODE_MR, "Multiple Routes to a Destination"}, { BGP_CAPCODE_EXT_NH, "Extended Next Hop Encoding"}, + { BGP_CAPCODE_EXT_MSG, "BGP Extended Message"}, { BGP_CAPCODE_ML, "Multiple Labels"}, { BGP_CAPCODE_RESTART, "Graceful Restart"}, { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"}, @@ -263,12 +273,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"}, @@ -453,6 +461,9 @@ static const struct tok bgp_safi_values[] = { #define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805 +/* Optional Parameters */ +#define BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH 255 /* Non-Ext OP Type */ + static const struct tok bgp_extd_comm_flag_values[] = { { 0x8000, "vendor-specific"}, { 0x4000, "non-transitive"}, @@ -557,8 +568,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 +608,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 +652,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 +676,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, @@ -766,6 +771,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)) { @@ -815,6 +822,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)) { @@ -844,7 +853,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; @@ -917,9 +926,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; @@ -993,7 +1004,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. */ @@ -1015,7 +1027,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 */ @@ -1030,20 +1042,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 @@ -1064,8 +1073,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); @@ -1079,9 +1087,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; } /* @@ -1150,6 +1155,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; @@ -1381,9 +1388,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); @@ -1391,11 +1397,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 @@ -1421,8 +1424,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); @@ -1461,8 +1463,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); @@ -1476,9 +1477,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 @@ -1494,8 +1492,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); @@ -1506,9 +1503,6 @@ decode_clnp_prefix(netdissect_options *ndo, plen); return 1 + (plen + 7) / 8; - -trunc: - return -2; } static int @@ -1529,8 +1523,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); } @@ -1544,9 +1537,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; } /* @@ -1753,8 +1743,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); @@ -1780,15 +1768,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): @@ -1821,8 +1805,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); @@ -1848,8 +1830,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; @@ -1871,8 +1851,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; @@ -1882,8 +1860,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; @@ -1906,6 +1882,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; @@ -2412,7 +2390,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; @@ -2551,6 +2528,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; @@ -2620,6 +2599,8 @@ bgp_capabilities_print(netdissect_options *ndo, case BGP_CAPCODE_RR: case BGP_CAPCODE_LLGR: case BGP_CAPCODE_RR_CISCO: + case BGP_CAPCODE_EXT_MSG: + case BGP_CAPCODE_ENH_RR: break; case BGP_CAPCODE_AS_NEW: /* @@ -2679,11 +2660,17 @@ 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; + uint8_t opsttype; const struct bgp_opt *bgpopt; const u_char *opt; u_int i; + uint8_t extended_opt_params = 0; + u_int open_size = BGP_OPEN_SIZE; + u_int opt_size = BGP_OPT_SIZE; ND_TCHECK_LEN(dat, BGP_OPEN_SIZE); if (length < BGP_OPEN_SIZE) @@ -2699,22 +2686,32 @@ bgp_open_print(netdissect_options *ndo, GET_BE_U_2(bgp_open_header->bgpo_holdtime)); 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); + opsttype = GET_U_1(bgp_open_header->bgpo_opttype); + if (opsttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH) { + optslen = GET_BE_U_2(bgp_open_header->bgpo_optlen_extended); + extended_opt_params = 1; + open_size += 3; + opt_size += 1; + } + ND_PRINT("\n\t Optional parameters%s, length: %u", + extended_opt_params ? " (Extended)" : "", optslen); - opt = dat + BGP_OPEN_SIZE; - length -= BGP_OPEN_SIZE; + opt = dat + open_size; + length -= open_size; i = 0; while (i < optslen) { - uint8_t opt_type, opt_len; + uint8_t opt_type; + uint16_t opt_len; - ND_TCHECK_LEN(opt + i, BGP_OPT_SIZE); - if (length < BGP_OPT_SIZE + i) + ND_TCHECK_LEN(opt + i, opt_size); + if (length < opt_size + i) goto trunc; bgpopt = (const struct bgp_opt *)(opt + i); opt_type = GET_U_1(bgpopt->bgpopt_type); - opt_len = GET_U_1(bgpopt->bgpopt_len); - if (BGP_OPT_SIZE + i + opt_len > optslen) { + opt_len = extended_opt_params ? GET_BE_U_2(bgpopt->bgpopt_len) + : GET_U_1(bgpopt->bgpopt_len); + if (opt_size + i + opt_len > optslen) { ND_PRINT("\n\t Option %u, length: %u, goes past the end of the options", opt_type, opt_len); break; @@ -2729,7 +2726,7 @@ bgp_open_print(netdissect_options *ndo, switch(opt_type) { case BGP_OPT_CAP: - bgp_capabilities_print(ndo, opt + BGP_OPT_SIZE + i, + bgp_capabilities_print(ndo, opt + opt_size + i, opt_len); break; @@ -2739,7 +2736,7 @@ bgp_open_print(netdissect_options *ndo, opt_type); break; } - i += BGP_OPT_SIZE + opt_len; + i += opt_size + opt_len; } return; trunc: @@ -2800,8 +2797,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); @@ -2835,6 +2830,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; @@ -2917,8 +2915,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); @@ -2942,8 +2938,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) { @@ -3009,18 +3003,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) { @@ -3029,9 +3022,8 @@ 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_printjn(ndo, tptr+1, shutdown_comm_length); ND_PRINT("\""); remainder_offset += shutdown_comm_length + 1; } @@ -3065,13 +3057,16 @@ bgp_route_refresh_print(netdissect_options *ndo, bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr; - ND_PRINT("\n\t AFI %s (%u), SAFI %s (%u)", - tok2str(af_values,"Unknown", - GET_BE_U_2(bgp_route_refresh_header->afi)), - GET_BE_U_2(bgp_route_refresh_header->afi), - tok2str(bgp_safi_values,"Unknown", - GET_U_1(bgp_route_refresh_header->safi)), - GET_U_1(bgp_route_refresh_header->safi)); + ND_PRINT("\n\t AFI %s (%u), SAFI %s (%u), Subtype %s (%u)", + tok2str(af_values, "Unknown", + GET_BE_U_2(bgp_route_refresh_header->afi)), + GET_BE_U_2(bgp_route_refresh_header->afi), + tok2str(bgp_safi_values, "Unknown", + GET_U_1(bgp_route_refresh_header->safi)), + GET_U_1(bgp_route_refresh_header->safi), + tok2str(bgp_route_refresh_subtype_values, "Unknown", + GET_U_1(bgp_route_refresh_header->subtype)), + GET_U_1(bgp_route_refresh_header->subtype)); if (ndo->ndo_vflag > 1) { ND_TCHECK_LEN(pptr, len);