X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/65ff785f67debbda8cdc721b2352b2aad2206c33..ffa1470e5c7ff0e50028d085a481dc797b0b51ed:/print-bgp.c diff --git a/print-bgp.c b/print-bgp.c index 6bcc4659..e4c08f27 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.88 2004-06-22 15:04:51 hannes Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.91.2.9 2006-02-02 12:36:46 hannes Exp $"; #endif #include @@ -355,6 +355,7 @@ static struct tok bgp_safi_values[] = { #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 */ @@ -376,6 +377,7 @@ static struct tok bgp_afi_values[] = { { AFNUM_BANYAN, "Banyan Vines"}, { AFNUM_E164NSAP, "E.164 with NSAP subaddress"}, { AFNUM_L2VPN, "Layer-2 VPN"}, + { AFNUM_VPLS, "VPLS"}, { 0, NULL}, }; @@ -403,6 +405,14 @@ static struct tok bgp_afi_values[] = { #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ +/* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */ +#define BGP_EXT_COM_EIGRP_GEN 0x8800 +#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801 +#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802 +#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803 +#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804 +#define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805 + static struct tok bgp_extd_comm_flag_values[] = { { 0x8000, "vendor-specific"}, { 0x4000, "non-transitive"}, @@ -427,6 +437,12 @@ static struct tok bgp_extd_comm_subtype_values[] = { { BGP_EXT_COM_OSPF_RID, "ospf-router-id"}, { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"}, { BGP_EXT_COM_L2INFO, "layer2-info"}, + { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" }, + { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" }, + { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" }, + { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" }, + { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" }, + { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" }, { 0, NULL}, }; @@ -491,6 +507,9 @@ decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen) stacked labels in a a single BGP message */ + if (24 > plen) + return -1; + plen-=24; /* adjust prefixlen - labellength */ if (32 < plen) @@ -565,9 +584,15 @@ decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen) TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ + if (0 == plen) + return 1; /* default route target */ + + if (32 > plen) + return -1; + plen-=32; /* adjust prefix length */ - if (0 < plen) + if (64 < plen) return -1; memset(&route_target, 0, sizeof(route_target)); @@ -596,6 +621,9 @@ decode_labeled_vpn_prefix4(const u_char *pptr, char *buf, u_int buflen) TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ + if ((24+64) > plen) + return -1; + plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ if (32 < plen) @@ -710,6 +738,10 @@ decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen) TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ + + if (24 > plen) + return -1; + plen-=24; /* adjust prefixlen - labellength */ if (128 < plen) @@ -744,6 +776,9 @@ decode_labeled_vpn_prefix6(const u_char *pptr, char *buf, u_int buflen) TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ + if ((24+64) > plen) + return -1; + plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ if (128 < plen) @@ -771,12 +806,79 @@ trunc: } #endif +static int +decode_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) +{ + u_int8_t addr[19]; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if (152 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[4], (plen + 7) / 8); + memcpy(&addr, &pptr[4], (plen + 7) / 8); + if (plen % 8) { + addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, buflen, "%s/%d", + isonsap_string(addr,(plen + 7) / 8), + plen); + + return 1 + (plen + 7) / 8; + +trunc: + return -2; +} + +static int +decode_labeled_vpn_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) +{ + u_int8_t addr[19]; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if ((24+64) > plen) + return -1; + + plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ + + if (152 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[12], (plen + 7) / 8); + memcpy(&addr, &pptr[12], (plen + 7) / 8); + if (plen % 8) { + addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", + bgp_vpn_rd_print(pptr+4), + isonsap_string(addr,(plen + 7) / 8), + plen, + EXTRACT_24BITS(pptr+1)>>4, + ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 12 + (plen + 7) / 8; + +trunc: + return -2; +} + static int bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) { int i; u_int16_t af; - u_int8_t safi, snpa; + u_int8_t safi, snpa, nhlen; union { /* copy buffer for bandwidth values */ float f; u_int32_t i; @@ -926,152 +1028,177 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) tokbuf, sizeof(tokbuf)), safi); - if (af == AFNUM_INET || af==AFNUM_L2VPN) - ; + switch(af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): #ifdef INET6 - else if (af == AFNUM_INET6) - ; + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_RT_ROUTING_INFO): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): #endif - else { - printf("\n\t no AFI %u decoder",af); + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + break; + default: + TCHECK2(tptr[0], tlen); + printf("\n\t no AFI %u / SAFI %u decoder",af,safi); if (vflag <= 1) print_unknown_data(tptr,"\n\t ",tlen); + goto done; break; } tptr +=3; TCHECK(tptr[0]); - tlen = tptr[0]; + nhlen = tptr[0]; + tlen = nhlen; tptr++; if (tlen) { - printf("\n\t nexthop: "); - while (tlen > 0) { - switch (af) { - case AFNUM_INET: - switch(safi) { - case SAFNUM_UNICAST: - case SAFNUM_MULTICAST: - case SAFNUM_UNIMULTICAST: - case SAFNUM_LABUNICAST: - case SAFNUM_RT_ROUTING_INFO: - if (tlen < (int)sizeof(struct in_addr)) { - printf("invalid len"); - tlen = 0; - } else { - TCHECK2(tptr[0], sizeof(struct in_addr)); - printf("%s",getname(tptr)); - tlen -= sizeof(struct in_addr); - tptr += sizeof(struct in_addr); - } - break; - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) { - printf("invalid len"); - tlen = 0; - } else { - TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); - printf("RD: %s, %s", - bgp_vpn_rd_print(tptr), - getname(tptr+BGP_VPN_RD_LEN)); - tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN); - tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN); - } - break; - default: - TCHECK2(tptr[0], tlen); - printf("no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr,"\n\t ",tlen); - tptr += tlen; - tlen = 0; - break; - } - break; + printf("\n\t nexthop: "); + while (tlen > 0) { + switch(af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + if (tlen < (int)sizeof(struct in_addr)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in_addr)); + printf("%s",getname(tptr)); + tlen -= sizeof(struct in_addr); + tptr += sizeof(struct in_addr); + } + break; + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); + printf("RD: %s, %s", + bgp_vpn_rd_print(tptr), + getname(tptr+BGP_VPN_RD_LEN)); + tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN); + tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN); + } + break; #ifdef INET6 - case AFNUM_INET6: - switch(safi) { - case SAFNUM_UNICAST: - case SAFNUM_MULTICAST: - case SAFNUM_UNIMULTICAST: - case SAFNUM_LABUNICAST: - case SAFNUM_RT_ROUTING_INFO: - if (tlen < (int)sizeof(struct in6_addr)) { - printf("invalid len"); - tlen = 0; - } else { - TCHECK2(tptr[0], sizeof(struct in6_addr)); - printf("%s", getname6(tptr)); - tlen -= sizeof(struct in6_addr); - tptr += sizeof(struct in6_addr); - } - break; - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) { - printf("invalid len"); - tlen = 0; - } else { - TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); - printf("RD: %s, %s", - bgp_vpn_rd_print(tptr), - getname6(tptr+BGP_VPN_RD_LEN)); - tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); - tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); - } - break; - default: - TCHECK2(tptr[0], tlen); - printf("no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr,"\n\t ",tlen); - tptr += tlen; - tlen = 0; - break; - } - break; + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_RT_ROUTING_INFO): + if (tlen < (int)sizeof(struct in6_addr)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in6_addr)); + printf("%s", getname6(tptr)); + tlen -= sizeof(struct in6_addr); + tptr += sizeof(struct in6_addr); + } + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); + printf("RD: %s, %s", + bgp_vpn_rd_print(tptr), + getname6(tptr+BGP_VPN_RD_LEN)); + tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); + tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); + } + break; #endif - case AFNUM_L2VPN: - switch(safi) { - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - if (tlen < (int)sizeof(struct in_addr)) { - printf("invalid len"); - tlen = 0; - } else { - TCHECK2(tptr[0], sizeof(struct in_addr)); - printf("%s", getname(tptr)); - tlen -= (sizeof(struct in_addr)); - tptr += (sizeof(struct in_addr)); - } - break; - default: - TCHECK2(tptr[0], tlen); - printf("no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr,"\n\t ",tlen); - tptr += tlen; - tlen = 0; - break; - } - break; - - default: - TCHECK2(tptr[0], tlen); - printf("no AFI %u decoder",af); - if (vflag <= 1) - print_unknown_data(tptr,"\n\t ",tlen); - tptr += tlen; - tlen = 0; - break; - } - } + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < (int)sizeof(struct in_addr)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in_addr)); + printf("%s", getname(tptr)); + tlen -= (sizeof(struct in_addr)); + tptr += (sizeof(struct in_addr)); + } + break; + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + TCHECK2(tptr[0], tlen); + printf("%s",isonsap_string(tptr,tlen)); + tptr += tlen; + tlen = 0; + break; + + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < BGP_VPN_RD_LEN+1) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], tlen); + printf("RD: %s, %s", + bgp_vpn_rd_print(tptr), + isonsap_string(tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)); + /* rfc986 mapped IPv4 address ? */ + if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) + printf(" = %s", getname(tptr+BGP_VPN_RD_LEN+4)); +#ifdef INET6 + /* rfc1888 mapped IPv6 address ? */ + else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) + printf(" = %s", getname6(tptr+BGP_VPN_RD_LEN+3)); +#endif + tptr += tlen; + tlen = 0; + } + break; + default: + TCHECK2(tptr[0], tlen); + printf("no AFI %u/SAFI %u decoder",af,safi); + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlen); + tptr += tlen; + tlen = 0; + goto done; + break; + } + } } + printf(", nh-length: %u", nhlen); tptr += tlen; TCHECK(tptr[0]); @@ -1090,149 +1217,137 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) } while (len - (tptr - pptr) > 0) { - switch (af) { - case AFNUM_INET: - switch (safi) { - case SAFNUM_UNICAST: - case SAFNUM_MULTICAST: - case SAFNUM_UNIMULTICAST: - advance = decode_prefix4(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_LABUNICAST: - advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_RT_ROUTING_INFO: - advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - default: - TCHECK2(*(tptr-3),tlen); - printf("\n\t no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr-3,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - break; + switch (af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; #ifdef INET6 - case AFNUM_INET6: - switch (safi) { - case SAFNUM_UNICAST: - case SAFNUM_MULTICAST: - case SAFNUM_UNIMULTICAST: - advance = decode_prefix6(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_LABUNICAST: - advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_RT_ROUTING_INFO: - advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - default: - TCHECK2(*(tptr-3),tlen); - printf("\n\t no SAFI %u decoder ",safi); - if (vflag <= 1) - print_unknown_data(tptr-3,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - break; + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_RT_ROUTING_INFO): + advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; #endif - case AFNUM_L2VPN: - switch(safi) { - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - default: - TCHECK2(*tptr,tlen); - printf("no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - break; - - - default: - TCHECK2(*(tptr-3),tlen); - printf("\n\t no AFI %u decoder ",af); - if (vflag <= 1) - print_unknown_data(tptr-3,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - tptr += advance; + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + default: + TCHECK2(*tptr,tlen); + printf("\n\t no AFI %u / SAFI %u decoder",af,safi); + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlen); + advance = 0; + tptr = pptr + len; + break; + } + if (advance < 0) + break; + tptr += advance; } + done: break; case BGPTYPE_MP_UNREACH_NLRI: @@ -1255,132 +1370,117 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) tptr += 3; while (len - (tptr - pptr) > 0) { - switch (af) { - case AFNUM_INET: - switch (safi) { - case SAFNUM_UNICAST: - case SAFNUM_MULTICAST: - case SAFNUM_UNIMULTICAST: - advance = decode_prefix4(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_LABUNICAST: - advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - default: - TCHECK2(*(tptr-3),tlen); - printf("\n\t no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr-3,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - break; - + switch (af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; #ifdef INET6 - case AFNUM_INET6: - switch (safi) { - case SAFNUM_UNICAST: - case SAFNUM_MULTICAST: - case SAFNUM_UNIMULTICAST: - advance = decode_prefix6(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_LABUNICAST: - advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal prefix length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - default: - TCHECK2(*(tptr-3),tlen); - printf("\n\t no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr-3,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - break; + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; #endif - - case AFNUM_L2VPN: - switch(safi) { - case SAFNUM_VPNUNICAST: - case SAFNUM_VPNMULTICAST: - case SAFNUM_VPNUNIMULTICAST: - advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); - if (advance == -1) - printf("\n\t (illegal length)"); - else if (advance == -2) - goto trunc; - else - printf("\n\t %s", buf); - break; - default: - TCHECK2(*(tptr-3),tlen); - printf("no SAFI %u decoder",safi); - if (vflag <= 1) - print_unknown_data(tptr-3,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - break; - - default: - TCHECK2(*(tptr-3),tlen); - printf("\n\t no AFI %u decoder",af); - if (vflag <= 1) - print_unknown_data(tptr-3,"\n\t ",tlen); - advance = 0; - tptr = pptr + len; - break; - } - - tptr += advance; + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + default: + TCHECK2(*(tptr-3),tlen); + printf("no AFI %u / SAFI %u decoder",af,safi); + if (vflag <= 1) + print_unknown_data(tptr-3,"\n\t ",tlen); + advance = 0; + tptr = pptr + len; + break; + } + if (advance < 0) + break; + tptr += advance; } break; case BGPTYPE_EXTD_COMMUNITIES: @@ -1460,6 +1560,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) EXTRACT_16BITS(tptr+4)); break; default: + TCHECK2(*tptr,8); print_unknown_data(tptr,"\n\t ",8); break; } @@ -1517,8 +1618,10 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) print_unknown_data(pptr,"\n\t ",len); break; } - if (vflag > 1 && len) /* omit zero length attributes*/ + if (vflag > 1 && len) { /* omit zero length attributes*/ + TCHECK2(*pptr,len); print_unknown_data(pptr,"\n\t ",len); + } return 1; trunc: @@ -1530,7 +1633,6 @@ bgp_open_print(const u_char *dat, int length) { struct bgp_open bgpo; struct bgp_opt bgpopt; - int hlen; const u_char *opt; int i,cap_type,cap_len,tcap_len,cap_offset; char tokbuf[TOKBUFSIZE]; @@ -1538,7 +1640,6 @@ bgp_open_print(const u_char *dat, int length) TCHECK2(dat[0], BGP_OPEN_SIZE); memcpy(&bgpo, dat, BGP_OPEN_SIZE); - hlen = ntohs(bgpo.bgpo_len); printf("\n\t Version %d, ", bgpo.bgpo_version); printf("my AS %u, ", ntohs(bgpo.bgpo_myas)); @@ -1618,14 +1719,17 @@ bgp_open_print(const u_char *dat, int length) case BGP_CAPCODE_RR_CISCO: break; default: + TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); printf("\n\t\tno decoder for Capability %u", cap_type); if (vflag <= 1) print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); break; } - if (vflag > 1) + if (vflag > 1) { + TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); + } break; case BGP_OPT_AUTH: default: @@ -1646,7 +1750,6 @@ bgp_update_print(const u_char *dat, int length) { struct bgp bgp; struct bgp_attr bgpa; - int hlen; const u_char *p; int len; int i; @@ -1654,7 +1757,6 @@ bgp_update_print(const u_char *dat, int length) TCHECK2(dat[0], BGP_SIZE); memcpy(&bgp, dat, BGP_SIZE); - hlen = ntohs(bgp.bgp_len); p = dat + BGP_SIZE; /*XXX*/ /* Unfeasible routes */ @@ -1736,13 +1838,14 @@ bgp_update_print(const u_char *dat, int length) p += 2 + len; if (dat + length > p) { - printf("\n\t Updated routes:"); + printf("\n\t Updated routes:"); while (dat + length > p) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); - if (i == -1) + if (i == -1) { printf("\n\t (illegal prefix length)"); - else if (i == -2) + break; + } else if (i == -2) goto trunc; else { printf("\n\t %s", buf); @@ -1759,14 +1862,12 @@ static void bgp_notification_print(const u_char *dat, int length) { struct bgp_notification bgpn; - int hlen; const u_char *tptr; char tokbuf[TOKBUFSIZE]; char tokbuf2[TOKBUFSIZE]; TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); - hlen = ntohs(bgpn.bgpn_len); /* some little sanity checking */ if (lengthsafi); - if (vflag > 1) + if (vflag > 1) { + TCHECK2(*pptr, len); print_unknown_data(pptr,"\n\t ", len); + } return; +trunc: + printf("[|BGP]"); } static int @@ -1890,9 +2001,10 @@ bgp_header_print(const u_char *dat, int length) bgp_route_refresh_print(dat, length); break; default: - /* we have no decoder for the BGP message */ - printf("\n\t no Message %u decoder",bgp.bgp_type); - print_unknown_data(dat,"\n\t ",length); + /* we have no decoder for the BGP message */ + TCHECK2(*dat, length); + printf("\n\t no Message %u decoder",bgp.bgp_type); + print_unknown_data(dat,"\n\t ",length); break; } return 1; @@ -1926,7 +2038,7 @@ bgp_print(const u_char *dat, int length) p = dat; start = p; - while (p < snapend) { + while (p < ep) { if (!TTEST2(p[0], 1)) break; if (p[0] != 0xff) {