X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/1621dd41599c95a8d8f475cd3f8882c6767c4c3a..refs/heads/tcpdump-3.9:/print-bgp.c diff --git a/print-bgp.c b/print-bgp.c index e4c08f27..50bdb2ca 100644 --- a/print-bgp.c +++ b/print-bgp.c @@ -36,7 +36,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.91.2.9 2006-02-02 12:36:46 hannes Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.91.2.12 2007-07-14 22:26:35 guy Exp $"; #endif #include @@ -50,6 +50,7 @@ static const char rcsid[] _U_ = #include "extract.h" #include "bgp.h" #include "l2vpn.h" +#include "af.h" struct bgp { u_int8_t bgp_marker[16]; @@ -339,48 +340,6 @@ static struct tok bgp_safi_values[] = { #define BGP_COMMUNITY_NO_ADVERT 0xffffff02 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 -/* RFC1700 address family numbers */ -#define AFNUM_INET 1 -#define AFNUM_INET6 2 -#define AFNUM_NSAP 3 -#define AFNUM_HDLC 4 -#define AFNUM_BBN1822 5 -#define AFNUM_802 6 -#define AFNUM_E163 7 -#define AFNUM_E164 8 -#define AFNUM_F69 9 -#define AFNUM_X121 10 -#define AFNUM_IPX 11 -#define AFNUM_ATALK 12 -#define AFNUM_DECNET 13 -#define AFNUM_BANYAN 14 -#define AFNUM_E164NSAP 15 -#define AFNUM_VPLS 25 -/* draft-kompella-ppvpn-l2vpn */ -#define AFNUM_L2VPN 196 /* still to be approved by IANA */ - -static struct tok bgp_afi_values[] = { - { 0, "Reserved"}, - { AFNUM_INET, "IPv4"}, - { AFNUM_INET6, "IPv6"}, - { AFNUM_NSAP, "NSAP"}, - { AFNUM_HDLC, "HDLC"}, - { AFNUM_BBN1822, "BBN 1822"}, - { AFNUM_802, "802"}, - { AFNUM_E163, "E.163"}, - { AFNUM_E164, "E.164"}, - { AFNUM_F69, "F.69"}, - { AFNUM_X121, "X.121"}, - { AFNUM_IPX, "Novell IPX"}, - { AFNUM_ATALK, "Appletalk"}, - { AFNUM_DECNET, "Decnet IV"}, - { AFNUM_BANYAN, "Banyan Vines"}, - { AFNUM_E164NSAP, "E.164 with NSAP subaddress"}, - { AFNUM_L2VPN, "Layer-2 VPN"}, - { AFNUM_VPLS, "VPLS"}, - { 0, NULL}, -}; - /* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */ #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */ #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */ @@ -650,6 +609,26 @@ trunc: return -2; } +/* + * As I remember, some versions of systems have an snprintf() that + * returns -1 if the buffer would have overflowed. If the return + * value is negative, set buflen to 0, to indicate that we've filled + * the buffer up. + * + * If the return value is greater than buflen, that means that + * the buffer would have overflowed; again, set buflen to 0 in + * that case. + */ +#define UPDATE_BUF_BUFLEN(buf, buflen, strlen) \ + if (strlen<0) \ + buflen=0; \ + else if ((u_int)strlen>buflen) \ + buflen=0; \ + else { \ + buflen-=strlen; \ + buf+=strlen; \ + } + static int decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) { @@ -660,11 +639,13 @@ decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) tlen=plen; pptr+=2; TCHECK2(pptr[0],15); + buf[0]='\0'; strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", bgp_vpn_rd_print(pptr), EXTRACT_16BITS(pptr+8), EXTRACT_16BITS(pptr+10), EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ + UPDATE_BUF_BUFLEN(buf, buflen, strlen); pptr+=15; tlen-=15; @@ -680,23 +661,32 @@ decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) switch(tlv_type) { case 1: - strlen+=snprintf(buf+strlen,buflen-strlen, "\n\t\tcircuit status vector (%u) length: %u: 0x", - tlv_type, - tlv_len); + if (buflen!=0) { + strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ while (ttlv_len>0) { TCHECK(pptr[0]); - strlen+=snprintf(buf+strlen,buflen-strlen, "%02x",*pptr++); + if (buflen!=0) { + strlen=snprintf(buf,buflen, "%02x",*pptr++); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } ttlv_len--; } break; default: - snprintf(buf+strlen,buflen-strlen, "\n\t\tunknown TLV #%u, length: %u", - tlv_type, - tlv_len); + if (buflen!=0) { + strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } break; } - tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it tright */ + tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */ } return plen+2; @@ -1020,7 +1010,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) safi = tptr[2]; printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", - tok2strbuf(bgp_afi_values, "Unknown AFI", af, + tok2strbuf(af_values, "Unknown AFI", af, tokbuf, sizeof(tokbuf)), af, (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ @@ -1356,7 +1346,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) safi = tptr[2]; printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", - tok2strbuf(bgp_afi_values, "Unknown AFI", af, + tok2strbuf(af_values, "Unknown AFI", af, tokbuf, sizeof(tokbuf)), af, (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ @@ -1548,7 +1538,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) *(tptr+6), tokbuf, sizeof(tokbuf)), (*(tptr+7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", - (*(tptr+6) == (BGP_OSPF_RTYPE_EXT ||BGP_OSPF_RTYPE_NSSA )) ? "E1" : ""); + ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : ""); break; case BGP_EXT_COM_L2INFO: printf(": %s Control Flags [0x%02x]:MTU %u", @@ -1685,7 +1675,7 @@ bgp_open_print(const u_char *dat, int length) switch(cap_type) { case BGP_CAPCODE_MP: printf("\n\t\tAFI %s (%u), SAFI %s (%u)", - tok2strbuf(bgp_afi_values, "Unknown", + tok2strbuf(af_values, "Unknown", EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), tokbuf, sizeof(tokbuf)), EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), @@ -1702,7 +1692,7 @@ bgp_open_print(const u_char *dat, int length) cap_offset=4; while(tcap_len>=4) { printf("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", - tok2strbuf(bgp_afi_values,"Unknown", + tok2strbuf(af_values,"Unknown", EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), tokbuf, sizeof(tokbuf)), EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), @@ -1916,7 +1906,7 @@ bgp_notification_print(const u_char *dat, int length) tptr = dat + BGP_NOTIFICATION_SIZE; TCHECK2(*tptr, 7); printf(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", - tok2strbuf(bgp_afi_values, "Unknown", + tok2strbuf(af_values, "Unknown", EXTRACT_16BITS(tptr), tokbuf, sizeof(tokbuf)), EXTRACT_16BITS(tptr), tok2strbuf(bgp_safi_values, "Unknown", *(tptr+2), @@ -1950,7 +1940,7 @@ bgp_route_refresh_print(const u_char *pptr, int len) { bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr; printf("\n\t AFI %s (%u), SAFI %s (%u)", - tok2strbuf(bgp_afi_values,"Unknown", + tok2strbuf(af_values,"Unknown", /* this stinks but the compiler pads the structure * weird */ EXTRACT_16BITS(&bgp_route_refresh_header->afi),