X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/65ff785f67debbda8cdc721b2352b2aad2206c33..a8d38a6e871d65bb56d9068c09a10eefc33f4c0b:/print-bgp.c?ds=inline diff --git a/print-bgp.c b/print-bgp.c index 6bcc4659..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.88 2004-06-22 15:04:51 hannes 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) @@ -771,12 +991,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; @@ -918,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 */ @@ -926,152 +1213,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): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): #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_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): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): + 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): + 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 +1402,138 @@ 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; + 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: - 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; #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: @@ -1241,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 */ @@ -1255,132 +1556,127 @@ 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; + 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); + 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: @@ -1411,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)); @@ -1426,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: @@ -1448,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", @@ -1459,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; } @@ -1468,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)); @@ -1517,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: @@ -1530,7 +1886,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 +1893,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)); @@ -1584,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), @@ -1601,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), @@ -1618,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: @@ -1646,7 +2003,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 +2010,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 +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); @@ -1759,14 +2115,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 (lengthafi), @@ -1854,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 @@ -1890,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; @@ -1926,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) {