aboutsummaryrefslogtreecommitdiffstats
path: root/print-bgp.c
diff options
context:
space:
mode:
Diffstat (limited to 'print-bgp.c')
-rw-r--r--print-bgp.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/print-bgp.c b/print-bgp.c
index c82f1cc7df10..7db3c6bb0f93 100644
--- a/print-bgp.c
+++ b/print-bgp.c
@@ -47,6 +47,8 @@
#include "af.h"
#include "l2vpn.h"
+static const char tstr[] = "[|BGP]";
+
struct bgp {
uint8_t bgp_marker[16];
uint16_t bgp_len;
@@ -1013,7 +1015,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 { \
@@ -1359,7 +1361,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;
@@ -1482,7 +1484,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:
@@ -1698,10 +1700,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;
@@ -2280,8 +2284,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;
@@ -2342,6 +2354,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)),
@@ -2351,12 +2365,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)),
@@ -2420,7 +2437,7 @@ bgp_capabilities_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2483,7 +2500,7 @@ bgp_open_print(netdissect_options *ndo,
}
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2583,7 +2600,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;
@@ -2620,7 +2637,7 @@ bgp_update_print(netdissect_options *ndo,
}
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2701,7 +2718,7 @@ bgp_notification_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2735,7 +2752,7 @@ bgp_route_refresh_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static int
@@ -2775,7 +2792,7 @@ bgp_header_print(netdissect_options *ndo,
}
return 1;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
return 0;
}
@@ -2824,7 +2841,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) {
@@ -2850,7 +2867,7 @@ bgp_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, " [|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
/*