X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/000d739130b4d6120a0eb340772c94831321e4c4..a8d38a6e871d65bb56d9068c09a10eefc33f4c0b:/print-bgp.c diff --git a/print-bgp.c b/print-bgp.c index f361a824..9f6a3697 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.93 2005-04-20 20:22:11 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.113 2007-06-21 06:06:29 hannes Exp $"; #endif #include @@ -49,6 +49,7 @@ static const char rcsid[] _U_ = #include "addrtoname.h" #include "extract.h" #include "bgp.h" +#include "af.h" #include "l2vpn.h" struct bgp { @@ -144,6 +145,7 @@ struct bgp_attr { #define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */ #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */ #define BGPTYPE_EXTD_COMMUNITIES 16 /* draft-ietf-idr-bgp-ext-communities */ +#define BGPTYPE_PMSI_TUNNEL 22 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ #define BGPTYPE_ATTR_SET 128 /* draft-marques-ppvpn-ibgp */ #define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */ @@ -165,6 +167,7 @@ static struct tok bgp_attr_values[] = { { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"}, { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"}, { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"}, + { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"}, { BGPTYPE_ATTR_SET, "Attribute Set"}, { 255, "Reserved for development"}, { 0, NULL} @@ -266,6 +269,7 @@ static struct tok bgp_notify_minor_open_values[] = { { 4, "Unsupported Optional Parameter"}, { 5, "Authentication Failure"}, { 6, "Unacceptable Hold Time"}, + { 7, "Capability Message Error"}, { 0, NULL} }; @@ -299,6 +303,31 @@ static struct tok bgp_origin_values[] = { { 0, NULL} }; +#define BGP_PMSI_TUNNEL_RSVP_P2MP 1 +#define BGP_PMSI_TUNNEL_LDP_P2MP 2 +#define BGP_PMSI_TUNNEL_PIM_SSM 3 +#define BGP_PMSI_TUNNEL_PIM_SM 4 +#define BGP_PMSI_TUNNEL_PIM_BIDIR 5 +#define BGP_PMSI_TUNNEL_INGRESS 6 +#define BGP_PMSI_TUNNEL_LDP_MP2MP 7 + +static struct tok bgp_pmsi_tunnel_values[] = { + { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"}, + { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"}, + { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"}, + { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"}, + { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"}, + { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"}, + { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"}, + { 0, NULL} +}; + +static struct tok bgp_pmsi_flag_values[] = { + { 0x01, "Leaf Information required"}, + { 0, NULL} +}; + + /* Subsequent address family identifier, RFC2283 section 7 */ #define SAFNUM_RES 0 #define SAFNUM_UNICAST 1 @@ -306,6 +335,8 @@ static struct tok bgp_origin_values[] = { #define SAFNUM_UNIMULTICAST 3 /* labeled BGP RFC3107 */ #define SAFNUM_LABUNICAST 4 +/* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ +#define SAFNUM_MULTICAST_VPN 5 #define SAFNUM_TUNNEL 64 /* XXX */ #define SAFNUM_VPLS 65 /* XXX */ #define SAFNUM_MDT 66 /* XXX */ @@ -330,7 +361,8 @@ static struct tok bgp_safi_values[] = { { SAFNUM_VPNUNICAST, "labeled VPN Unicast"}, { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"}, { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"}, - { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"}, /* draft-marques-ppvpn-rt-constrain-01.txt */ + { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"}, + { SAFNUM_MULTICAST_VPN, "Multicast VPN"}, { 0, NULL } }; @@ -339,46 +371,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 -/* 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"}, - { 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) */ @@ -388,8 +380,6 @@ static struct tok bgp_afi_values[] = { #define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */ #define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */ /* rfc2547 bgp-mpls-vpns */ -#define BGP_EXT_COM_CISCO_MCAST 0x0009 /* cisco proprietary */ - #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */ #define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatability */ #define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatability */ @@ -403,6 +393,17 @@ static struct tok bgp_afi_values[] = { #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ +#define BGP_EXT_COM_SOURCE_AS 0x0009 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ +#define BGP_EXT_COM_VRF_RT_IMP 0x010a /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ + +/* 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"}, @@ -417,7 +418,6 @@ static struct tok bgp_extd_comm_subtype_values[] = { { BGP_EXT_COM_RO_1, "origin"}, { BGP_EXT_COM_RO_2, "origin"}, { BGP_EXT_COM_LINKBAND, "link-BW"}, - { BGP_EXT_COM_CISCO_MCAST, "mdt-group"}, { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"}, { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"}, { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"}, @@ -427,6 +427,14 @@ 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)" }, + { BGP_EXT_COM_SOURCE_AS, "source-AS" }, + { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"}, { 0, NULL}, }; @@ -491,6 +499,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) @@ -516,6 +527,97 @@ trunc: return -2; } +/* + * bgp_vpn_ip_print + * + * print an ipv4 or ipv6 address into a buffer dependend on address length. + */ +static char * +bgp_vpn_ip_print (const u_char *pptr, u_int addr_length) { + + /* worst case string is s fully formatted v6 address */ + static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")]; + char *pos = addr; + + switch(addr_length) { + case (sizeof(struct in_addr) << 3): /* 32 */ + TCHECK2(pptr[0], sizeof(struct in_addr)); + snprintf(pos, sizeof(addr), "%s", ipaddr_string(pptr)); + break; + case (sizeof(struct in6_addr) << 3): /* 128 */ + TCHECK2(pptr[0], sizeof(struct in6_addr)); + snprintf(pos, sizeof(addr), "%s", ip6addr_string(pptr)); + break; + default: + snprintf(pos, sizeof(addr), "bogus address length %u", addr_length); + break; + } + pos += strlen(pos); + +trunc: + *(pos) = '\0'; + return (addr); +} + +/* + * bgp_vpn_sg_print + * + * print an multicast s,g entry into a buffer. + * the s,g entry is encoded like this. + * + * +-----------------------------------+ + * | Multicast Source Length (1 octet) | + * +-----------------------------------+ + * | Multicast Source (Variable) | + * +-----------------------------------+ + * | Multicast Group Length (1 octet) | + * +-----------------------------------+ + * | Multicast Group (Variable) | + * +-----------------------------------+ + * + * return the number of bytes read from the wire. + */ +static int +bgp_vpn_sg_print (const u_char *pptr, char *buf, u_int buflen) { + + u_int8_t addr_length; + u_int total_length, offset; + + total_length = 0; + + /* Source address length, encoded in bits */ + TCHECK2(pptr[0], 1); + addr_length = *pptr++; + + /* Source address */ + TCHECK2(pptr[0], (addr_length >> 3)); + total_length += (addr_length >> 3) + 1; + offset = strlen(buf); + if (addr_length) { + snprintf(buf + offset, buflen - offset, ", Source %s", + bgp_vpn_ip_print(pptr, addr_length)); + pptr += (addr_length >> 3); + } + + /* Group address length, encoded in bits */ + TCHECK2(pptr[0], 1); + addr_length = *pptr++; + + /* Group address */ + TCHECK2(pptr[0], (addr_length >> 3)); + total_length += (addr_length >> 3) + 1; + offset = strlen(buf); + if (addr_length) { + snprintf(buf + offset, buflen - offset, ", Group %s", + bgp_vpn_ip_print(pptr, addr_length)); + pptr += (addr_length >> 3); + } + +trunc: + return (total_length); +} + + /* RDs and RTs share the same semantics * we use bgp_vpn_rd_print for * printing route targets inside a NLRI */ @@ -565,9 +667,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 +704,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) @@ -622,6 +733,108 @@ trunc: return -2; } +#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7 + +static struct tok bgp_multicast_vpn_route_type_values[] = { + { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"}, +}; + +static int +decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen) +{ + u_int8_t route_type, route_length, addr_length, sg_length; + u_int offset; + + TCHECK2(pptr[0], 2); + route_type = *pptr++; + route_length = *pptr++; + + snprintf(buf, buflen, "Route-Type: %s (%u), length: %u", + tok2str(bgp_multicast_vpn_route_type_values, + "Unknown", route_type), + route_type, route_length); + + switch(route_type) { + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s", + bgp_vpn_rd_print(pptr), + bgp_vpn_ip_print(pptr + BGP_VPN_RD_LEN, + (route_length - BGP_VPN_RD_LEN) << 3)); + break; + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI: + TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u", + bgp_vpn_rd_print(pptr), + EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)); + break; + + case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s", + bgp_vpn_rd_print(pptr)); + pptr += BGP_VPN_RD_LEN; + + sg_length = bgp_vpn_sg_print(pptr, buf, buflen); + addr_length = route_length - sg_length; + + TCHECK2(pptr[0], addr_length); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", Originator %s", + bgp_vpn_ip_print(pptr, addr_length << 3)); + break; + + case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s", + bgp_vpn_rd_print(pptr)); + pptr += BGP_VPN_RD_LEN; + + bgp_vpn_sg_print(pptr, buf, buflen); + break; + + case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */ + case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u", + bgp_vpn_rd_print(pptr), + EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)); + pptr += BGP_VPN_RD_LEN; + + bgp_vpn_sg_print(pptr, buf, buflen); + break; + + /* + * no per route-type printing yet. + */ + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF: + default: + break; + } + + return route_length + 2; + +trunc: + return -2; +} + static int decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) { @@ -710,6 +923,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 +961,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) @@ -772,14 +992,13 @@ trunc: #endif static int -decode_labeled_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) +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 */ - plen-=24; /* adjust prefixlen - labellength */ if (152 < plen) return -1; @@ -791,14 +1010,11 @@ decode_labeled_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) 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, "%s/%d, label:%u %s", - isonsap_string(addr,(plen + 7) / 8 - 1), - plen, - EXTRACT_24BITS(pptr+1)>>4, - ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + snprintf(buf, buflen, "%s/%d", + isonsap_string(addr,(plen + 7) / 8), + plen); - return 4 + (plen + 7) / 8; + return 1 + (plen + 7) / 8; trunc: return -2; @@ -813,6 +1029,9 @@ decode_labeled_vpn_clnp_prefix(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 (152 < plen) @@ -828,7 +1047,7 @@ decode_labeled_vpn_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) /* 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 - 1), + isonsap_string(addr,(plen + 7) / 8), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); @@ -844,7 +1063,7 @@ 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; @@ -986,7 +1205,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 */ @@ -1003,12 +1222,12 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): #ifdef 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): @@ -1022,8 +1241,10 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) 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); @@ -1034,7 +1255,8 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) tptr +=3; TCHECK(tptr[0]); - tlen = tptr[0]; + nhlen = tptr[0]; + tlen = nhlen; tptr++; if (tlen) { @@ -1046,6 +1268,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) 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_MULTICAST_VPN): if (tlen < (int)sizeof(struct in_addr)) { printf("invalid len"); tlen = 0; @@ -1076,7 +1299,6 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) 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; @@ -1103,6 +1325,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) } break; #endif + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): @@ -1160,6 +1383,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) } } } + printf(", nh-length: %u", nhlen); tptr += tlen; TCHECK(tptr[0]); @@ -1219,6 +1443,16 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) else printf("\n\t %s", buf); break; + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): + advance = decode_multicast_vpn(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<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): @@ -1251,16 +1485,8 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) 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_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): @@ -1275,7 +1501,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - advance = decode_labeled_clnp_prefix(tptr, buf, sizeof(buf)); + advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) @@ -1303,8 +1529,9 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) tptr = pptr + len; break; } + if (advance < 0) + break; tptr += advance; - break; } done: break; @@ -1315,7 +1542,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 */ @@ -1394,6 +1621,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) printf("\n\t %s", buf); break; #endif + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): @@ -1408,7 +1636,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): - advance = decode_labeled_clnp_prefix(tptr, buf, sizeof(buf)); + advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) @@ -1427,6 +1655,16 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) else printf("\n\t %s", buf); break; + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): + advance = decode_multicast_vpn(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); @@ -1436,8 +1674,9 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) tptr = pptr + len; break; } + if (advance < 0) + break; tptr += advance; - break; } break; case BGPTYPE_EXTD_COMMUNITIES: @@ -1468,6 +1707,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) break; case BGP_EXT_COM_RT_1: case BGP_EXT_COM_RO_1: + case BGP_EXT_COM_VRF_RT_IMP: printf(": %s:%u", getname(tptr+2), EXTRACT_16BITS(tptr+6)); @@ -1483,11 +1723,6 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) printf(": bandwidth: %.3f Mbps", bw.f*8/1000000); break; - case BGP_EXT_COM_CISCO_MCAST: - printf(": AS %u, group %s", - EXTRACT_16BITS(tptr+2), - getname(tptr+4)); - break; case BGP_EXT_COM_VPN_ORIGIN: case BGP_EXT_COM_VPN_ORIGIN2: case BGP_EXT_COM_VPN_ORIGIN3: @@ -1505,7 +1740,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", @@ -1516,7 +1751,11 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) *(tptr+3), EXTRACT_16BITS(tptr+4)); break; + case BGP_EXT_COM_SOURCE_AS: + printf(": AS %u", EXTRACT_16BITS(tptr+2)); + break; default: + TCHECK2(*tptr,8); print_unknown_data(tptr,"\n\t ",8); break; } @@ -1525,6 +1764,64 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) } break; + case BGPTYPE_PMSI_TUNNEL: + { + u_int8_t tunnel_type, flags; + + tunnel_type = *(tptr+1); + flags = *tptr; + tlen = len; + + TCHECK2(tptr[0], 5); + printf("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", + tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), + tunnel_type, + bittok2str(bgp_pmsi_flag_values, "none", flags), + EXTRACT_24BITS(tptr+2)>>4); + + tptr +=5; + tlen -= 5; + + switch (tunnel_type) { + case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ + case BGP_PMSI_TUNNEL_PIM_BIDIR: + TCHECK2(tptr[0], 8); + printf("\n\t Sender %s, P-Group %s", + ipaddr_string(tptr), + ipaddr_string(tptr+4)); + break; + + case BGP_PMSI_TUNNEL_PIM_SSM: + TCHECK2(tptr[0], 8); + printf("\n\t Root-Node %s, P-Group %s", + ipaddr_string(tptr), + ipaddr_string(tptr+4)); + break; + case BGP_PMSI_TUNNEL_INGRESS: + TCHECK2(tptr[0], 4); + printf("\n\t Tunnel-Endpoint %s", + ipaddr_string(tptr)); + break; + case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ + case BGP_PMSI_TUNNEL_LDP_MP2MP: + TCHECK2(tptr[0], 8); + printf("\n\t Root-Node %s, LSP-ID 0x%08x", + ipaddr_string(tptr), + EXTRACT_32BITS(tptr+4)); + break; + case BGP_PMSI_TUNNEL_RSVP_P2MP: + TCHECK2(tptr[0], 8); + printf("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", + ipaddr_string(tptr), + EXTRACT_32BITS(tptr+4)); + break; + default: + if (vflag <= 1) { + print_unknown_data(tptr,"\n\t ",tlen); + } + } + break; + } case BGPTYPE_ATTR_SET: TCHECK2(tptr[0], 4); printf("\n\t Origin AS: %u", EXTRACT_32BITS(tptr)); @@ -1574,8 +1871,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: @@ -1639,7 +1938,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), @@ -1656,7 +1955,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), @@ -1673,14 +1972,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: @@ -1789,13 +2091,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); @@ -1866,7 +2169,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), @@ -1891,10 +2194,16 @@ bgp_route_refresh_print(const u_char *pptr, int len) { char tokbuf[TOKBUFSIZE]; char tokbuf2[TOKBUFSIZE]; + TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE); + + /* some little sanity checking */ + if (lenafi), @@ -1905,10 +2214,14 @@ bgp_route_refresh_print(const u_char *pptr, int len) { tokbuf2, sizeof(tokbuf2)), bgp_route_refresh_header->safi); - if (vflag > 1) + if (vflag > 1) { + TCHECK2(*pptr, len); print_unknown_data(pptr,"\n\t ", len); + } return; +trunc: + printf("[|BGP]"); } static int @@ -1941,9 +2254,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; @@ -1977,7 +2291,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) {