diff options
Diffstat (limited to 'freebsd/contrib/tcpdump/print-bgp.c')
-rw-r--r-- | freebsd/contrib/tcpdump/print-bgp.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/freebsd/contrib/tcpdump/print-bgp.c b/freebsd/contrib/tcpdump/print-bgp.c index 3d1e2f4d..148b7a0c 100644 --- a/freebsd/contrib/tcpdump/print-bgp.c +++ b/freebsd/contrib/tcpdump/print-bgp.c @@ -53,6 +53,8 @@ #include "af.h" #include "l2vpn.h" +static const char tstr[] = "[|BGP]"; + struct bgp { uint8_t bgp_marker[16]; uint16_t bgp_len; @@ -1019,7 +1021,7 @@ trunc: */ #define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \ if (stringlen<0) \ - buflen=0; \ + buflen=0; \ else if ((u_int)stringlen>buflen) \ buflen=0; \ else { \ @@ -1365,7 +1367,7 @@ trunc: static int bgp_attr_print(netdissect_options *ndo, - u_int atype, const u_char *pptr, u_int len) + u_int atype, const u_char *pptr, u_int len, const unsigned attr_set_level) { int i; uint16_t af; @@ -1488,7 +1490,7 @@ bgp_attr_print(netdissect_options *ndo, } ND_TCHECK2(tptr[0], 8); ND_PRINT((ndo, " AS #%s, origin %s", - as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), + as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), ipaddr_string(ndo, tptr + 4))); break; case BGPTYPE_COMMUNITIES: @@ -1704,10 +1706,12 @@ bgp_attr_print(netdissect_options *ndo, bgp_vpn_rd_print(ndo, tptr), isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN))); /* rfc986 mapped IPv4 address ? */ - if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) + if (tlen == BGP_VPN_RD_LEN + 4 + sizeof(struct in_addr) + && EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) ND_PRINT((ndo, " = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4))); /* rfc1888 mapped IPv6 address ? */ - else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) + else if (tlen == BGP_VPN_RD_LEN + 3 + sizeof(struct in6_addr) + && EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) ND_PRINT((ndo, " = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3))); tptr += tlen; tlen = 0; @@ -2286,8 +2290,16 @@ bgp_attr_print(netdissect_options *ndo, ND_PRINT((ndo, "+%x", aflags & 0xf)); ND_PRINT((ndo, "]: ")); } - /* FIXME check for recursion */ - if (!bgp_attr_print(ndo, atype, tptr, alen)) + /* The protocol encoding per se allows ATTR_SET to be nested as many times + * as the message can accommodate. This printer used to be able to recurse + * into ATTR_SET contents until the stack exhaustion, but now there is a + * limit on that (if live protocol exchange goes that many levels deep, + * something is probably wrong anyway). Feel free to refine this value if + * you can find the spec with respective normative text. + */ + if (attr_set_level == 10) + ND_PRINT((ndo, "(too many nested levels, not recursing)")); + else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1)) return 0; tptr += alen; len -= alen; @@ -2348,6 +2360,8 @@ bgp_capabilities_print(netdissect_options *ndo, ND_TCHECK2(opt[i+2], cap_len); switch (cap_type) { case BGP_CAPCODE_MP: + /* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */ + ND_TCHECK_8BITS(opt + i + 5); ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)", tok2str(af_values, "Unknown", EXTRACT_16BITS(opt+i+2)), @@ -2357,12 +2371,15 @@ bgp_capabilities_print(netdissect_options *ndo, opt[i+5])); break; case BGP_CAPCODE_RESTART: + /* Restart Flags (4 bits), Restart Time in seconds (12 bits) */ + ND_TCHECK_16BITS(opt + i + 2); ND_PRINT((ndo, "\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) { + ND_TCHECK_8BITS(opt + i + cap_offset + 3); ND_PRINT((ndo, "\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", tok2str(af_values,"Unknown", EXTRACT_16BITS(opt+i+cap_offset)), @@ -2426,7 +2443,7 @@ bgp_capabilities_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "[|BGP]")); + ND_PRINT((ndo, "%s", tstr)); } static void @@ -2489,7 +2506,7 @@ bgp_open_print(netdissect_options *ndo, } return; trunc: - ND_PRINT((ndo, "[|BGP]")); + ND_PRINT((ndo, "%s", tstr)); } static void @@ -2589,7 +2606,7 @@ bgp_update_print(netdissect_options *ndo, goto trunc; if (length < alen) goto trunc; - if (!bgp_attr_print(ndo, atype, p, alen)) + if (!bgp_attr_print(ndo, atype, p, alen, 0)) goto trunc; p += alen; len -= alen; @@ -2626,7 +2643,7 @@ bgp_update_print(netdissect_options *ndo, } return; trunc: - ND_PRINT((ndo, "[|BGP]")); + ND_PRINT((ndo, "%s", tstr)); } static void @@ -2707,7 +2724,7 @@ bgp_notification_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "[|BGP]")); + ND_PRINT((ndo, "%s", tstr)); } static void @@ -2741,7 +2758,7 @@ bgp_route_refresh_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, "[|BGP]")); + ND_PRINT((ndo, "%s", tstr)); } static int @@ -2781,7 +2798,7 @@ bgp_header_print(netdissect_options *ndo, } return 1; trunc: - ND_PRINT((ndo, "[|BGP]")); + ND_PRINT((ndo, "%s", tstr)); return 0; } @@ -2830,7 +2847,7 @@ bgp_print(netdissect_options *ndo, memcpy(&bgp, p, BGP_SIZE); if (start != p) - ND_PRINT((ndo, " [|BGP]")); + ND_PRINT((ndo, " %s", tstr)); hlen = ntohs(bgp.bgp_len); if (hlen < BGP_SIZE) { @@ -2856,7 +2873,7 @@ bgp_print(netdissect_options *ndo, return; trunc: - ND_PRINT((ndo, " [|BGP]")); + ND_PRINT((ndo, "%s", tstr)); } /* |