From: itojun Date: Mon, 25 Dec 2000 05:28:40 +0000 (+0000) Subject: bgp route refresh/MP capability option. X-Git-Url: http://git.samba.org/samba.git/?p=obnox%2Fwireshark%2Fwip.git;a=commitdiff_plain;h=3b6c37add8dcbea20dc1fc716c323e5059a51481 bgp route refresh/MP capability option. Greg Hankins git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@2780 f5534014-38df-0310-8fa8-9805f1628bb7 --- diff --git a/packet-bgp.c b/packet-bgp.c index b94ee9953d..bfbc4ed06e 100644 --- a/packet-bgp.c +++ b/packet-bgp.c @@ -2,14 +2,16 @@ * Routines for BGP packet dissection. * Copyright 1999, Jun-ichiro itojun Hagino * - * $Id: packet-bgp.c,v 1.28 2000/11/19 08:53:55 guy Exp $ + * $Id: packet-bgp.c,v 1.29 2000/12/25 05:28:40 itojun Exp $ * * Supports: * RFC1771 A Border Gateway Protocol 4 (BGP-4) * RFC1965 Autonomous System Confederations for BGP - * RFC1966 BGP Route Reflection An alternative to full mesh IBGP * RFC1997 BGP Communities Attribute - * RFC2283 Multiprotocol Extensions for BGP-4 + * RFC2796 BGP Route Reflection An alternative to full mesh IBGP + * RFC2842 Capabilities Advertisement with BGP-4 + * RFC2858 Multiprotocol Extensions for BGP-4 + * RFC2918 Route Refresh Capability for BGP-4 * * TODO: * Destination Preference Attribute for BGP (work in progress) @@ -64,13 +66,12 @@ #include "packet-bgp.h" #include "packet-ipv6.h" -#define TCP_PORT_BGP 179 - static const value_string bgptypevals[] = { { BGP_OPEN, "OPEN Message" }, { BGP_UPDATE, "UPDATE Message" }, { BGP_NOTIFICATION, "NOTIFICATION Message" }, { BGP_KEEPALIVE, "KEEPALIVE Message" }, + { BGP_ROUTE_REFRESH, "ROUTE-REFRESH Message" }, { 0, NULL }, }; @@ -197,9 +198,12 @@ static gint ett_bgp_nlri = -1; static gint ett_bgp_open = -1; static gint ett_bgp_update = -1; static gint ett_bgp_notification = -1; +static gint ett_bgp_route_refresh = -1; /* ROUTE-REFRESH message tree */ static gint ett_bgp_as_paths = -1; static gint ett_bgp_communities = -1; -static gint ett_bgp_cluster_list = -1; +static gint ett_bgp_cluster_list = -1; /* cluster list tree */ +static gint ett_bgp_options = -1; /* optional parameters tree */ +static gint ett_bgp_option = -1; /* an optional parameter tree */ /* * Decode an IPv4 prefix. @@ -261,8 +265,20 @@ decode_prefix6(const u_char *pd, char *buf, int buflen) static void dissect_bgp_open(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { - struct bgp_open bgpo; /* BGP OPEN message */ - int hlen; /* message length */ + struct bgp_open bgpo; /* BGP OPEN message */ + int hlen; /* message length */ + u_int i; /* tmp */ + int ptype; /* parameter type */ + int plen; /* parameter length */ + int ctype; /* capability type */ + int clen; /* capability length */ + int ostart; /* options start */ + const u_char *oend; /* options end */ + const u_char *p; /* packet offset pointer */ + proto_item *ti; /* tree item */ + proto_tree *subtree; /* subtree for options */ + proto_tree *subtree2; /* subtree for an option */ + proto_tree *subtree3; /* subtree for an option */ /* snarf OPEN message */ memcpy(&bgpo, &pd[offset], sizeof(bgpo)); @@ -285,12 +301,159 @@ dissect_bgp_open(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) "Optional parameters length: %u %s", bgpo.bgpo_optlen, (bgpo.bgpo_optlen == 1) ? "byte" : "bytes"); - if (hlen > sizeof(struct bgp_open)) { - int openoff; - openoff = ((char *)&bgpo.bgpo_optlen - (char *)&bgpo) + 1; - proto_tree_add_text(tree, NullTVB, - offset + openoff, hlen - openoff, - "Optional parameters"); + /* optional parameters */ + if (bgpo.bgpo_optlen > 0) { + /* add a subtree and setup some offsets */ + ostart = offset + sizeof(bgpo) - 3; + ti = proto_tree_add_text(tree, NullTVB, ostart, bgpo.bgpo_optlen, + "Optional parameters"); + subtree = proto_item_add_subtree(ti, ett_bgp_options); + p = &pd[ostart]; + oend = p + bgpo.bgpo_optlen; + + /* step through all of the optional parameters */ + while (p < oend) { + + /* grab the type and length */ + ptype = *p++; + plen = *p++; + + /* check the type */ + switch (ptype) { + case BGP_OPTION_AUTHENTICATION: + proto_tree_add_text(subtree, NullTVB, p - pd - 2, 2 + plen, + "Authentication information (%u %s)", plen, + (plen == 1) ? "byte" : "bytes"); + break; + case BGP_OPTION_CAPABILITY: + /* grab the capability code */ + ctype = *p++; + clen = *p++; + + /* check the capability type */ + switch (ctype) { + case BGP_CAPABILITY_RESERVED: + ti = proto_tree_add_text(subtree, NullTVB, p - pd - 4, + 2 + plen, "Reserved capability (%u %s)", 2 + plen, + (plen == 1) ? "byte" : "bytes"); + subtree2 = proto_item_add_subtree(ti, ett_bgp_option); + proto_tree_add_text(subtree2, NullTVB, p - pd - 4, + 1, "Parameter type: Capabilities (2)"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 3, + 1, "Parameter length: %u %s", plen, + (plen == 1) ? "byte" : "bytes"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 2, + 1, "Capability code: Reserved (0)"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 1, + 1, "Capability length: %u %s", clen, + (clen == 1) ? "byte" : "bytes"); + if (clen != 0) { + proto_tree_add_text(subtree2, NullTVB, p - pd, + clen, "Capability value: Unknown"); + } + p += clen; + break; + case BGP_CAPABILITY_MULTIPROTOCOL: + ti = proto_tree_add_text(subtree, NullTVB, p - pd - 4, + 2 + plen, + "Multiprotocol extensions capability (%u %s)", + 2 + plen, (plen == 1) ? "byte" : "bytes"); + subtree2 = proto_item_add_subtree(ti, ett_bgp_option); + proto_tree_add_text(subtree2, NullTVB, p - pd - 4, + 1, "Parameter type: Capabilities (2)"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 3, + 1, "Parameter length: %u %s", plen, + (plen == 1) ? "byte" : "bytes"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 2, + 1, "Capability code: Multiprotocol extensions (%d)", + ctype); + if (clen != 4) { + proto_tree_add_text(subtree2, NullTVB, p - pd - 1, + 1, "Capability length: Invalid"); + proto_tree_add_text(subtree2, NullTVB, p - pd, + clen, "Capability value: Unknown"); + } + else { + proto_tree_add_text(subtree2, NullTVB, p - pd - 1, + 1, "Capability length: %u %s", clen, + (clen == 1) ? "byte" : "bytes"); + ti = proto_tree_add_text(subtree2, NullTVB, p - pd, + clen, "Capability value"); + subtree3 = proto_item_add_subtree(ti, + ett_bgp_option); + /* AFI */ + i = pntohs(p); + proto_tree_add_text(subtree3, NullTVB, p - pd, + 2, "Address family identifier: %s (%u)", + val_to_str(i, afnumber, "Unknown"), i); + p += 2; + /* Reserved */ + proto_tree_add_text(subtree3, NullTVB, p - pd, + 1, "Reserved: 1 byte"); + p++; + /* SAFI */ + i = *p; + proto_tree_add_text(subtree3, NullTVB, p - pd, + 1, "Subsequent address family identifier: %s (%u)", + val_to_str(i, bgpattr_nlri_safi, + i >= 128 ? "Vendor specific" : "Unknown"), i); + p++; + } + break; + case BGP_CAPABILITY_ROUTE_REFRESH: + ti = proto_tree_add_text(subtree, NullTVB, p - pd - 4, + 2 + plen, "Route refresh capability (%u %s)", 2 + plen, + (plen == 1) ? "byte" : "bytes"); + subtree2 = proto_item_add_subtree(ti, ett_bgp_option); + proto_tree_add_text(subtree2, NullTVB, p - pd - 4, + 1, "Parameter type: Capabilities (2)"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 3, + 1, "Parameter length: %u %s", plen, + (plen == 1) ? "byte" : "bytes"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 2, + 1, "Capability code: Route refresh (%d)", ctype); + if (clen != 0) { + proto_tree_add_text(subtree2, NullTVB, p - pd, + clen, "Capability value: Invalid"); + } + else { + proto_tree_add_text(subtree2, NullTVB, p - pd - 1, + 1, "Capability length: %u %s", clen, + (clen == 1) ? "byte" : "bytes"); + } + p += clen; + break; + /* unknown capability */ + default: + ti = proto_tree_add_text(subtree, NullTVB, p - pd - 4, + 2 + plen, "Unknown capability (%u %s)", 2 + plen, + (plen == 1) ? "byte" : "bytes"); + subtree2 = proto_item_add_subtree(ti, ett_bgp_option); + proto_tree_add_text(subtree2, NullTVB, p - pd - 4, + 1, "Parameter type: Capabilities (2)"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 3, + 1, "Parameter length: %u %s", plen, + (plen == 1) ? "byte" : "bytes"); + proto_tree_add_text(subtree2, NullTVB, p - pd - 2, + 1, "Capability code: %s (%d)", + ctype >= 128 ? "Private use" : "Unknown", ctype); + proto_tree_add_text(subtree2, NullTVB, p - pd - 1, + 1, "Capability length: %u %s", clen, + (clen == 1) ? "byte" : "bytes"); + if (clen != 0) { + proto_tree_add_text(subtree2, NullTVB, p - pd, + clen, "Capability value: Unknown"); + } + p += clen; + break; + } + break; + default: + proto_tree_add_text(subtree, NullTVB, p - pd - 2, 2 + plen, + "Unknown optional parameter"); + break; + } + } } } @@ -1118,6 +1281,36 @@ dissect_bgp_notification(const u_char *pd, int offset, frame_data *fd, } } +/* + * Dissect a BGP ROUTE-REFRESH message. + */ +static void +dissect_bgp_route_refresh(const u_char *pd, int offset, frame_data *fd, + proto_tree *tree) +{ + const u_char *p; /* string pointer */ + u_int i; /* tmp */ + + /* AFI */ + p = &pd[offset + BGP_HEADER_SIZE]; + i = pntohs(p); + proto_tree_add_text(tree, NullTVB, offset + BGP_HEADER_SIZE, 2, + "Address family identifier: %s (%u)", + val_to_str(i, afnumber, "Unknown"), i); + p += 2; + /* Reserved */ + proto_tree_add_text(tree, NullTVB, offset + BGP_HEADER_SIZE + 2, 1, + "Reserved: 1 byte"); + p++; + /* SAFI */ + i = *p; + proto_tree_add_text(tree, NullTVB, offset + BGP_HEADER_SIZE + 3, 1, + "Subsequent address family identifier: %s (%u)", + val_to_str(i, bgpattr_nlri_safi, + i >= 128 ? "Vendor specific" : "Unknown"), + i); +} + /* * Dissect a BGP packet. */ @@ -1203,8 +1396,8 @@ dissect_bgp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) hlen = ntohs(bgp.bgp_len); typ = val_to_str(bgp.bgp_type, bgptypevals, "Unknown Message"); if (END_OF_FRAME < hlen) { - ti = proto_tree_add_text(bgp_tree, NullTVB, offset + i, END_OF_FRAME, - "%s (truncated)", typ); + ti = proto_tree_add_text(bgp_tree, NullTVB, offset + i, + END_OF_FRAME, "%s (truncated)", typ); } else { ti = proto_tree_add_text(bgp_tree, NullTVB, offset + i, hlen, "%s", typ); @@ -1223,6 +1416,9 @@ dissect_bgp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) case BGP_KEEPALIVE: bgp1_tree = proto_item_add_subtree(ti, ett_bgp); break; + case BGP_ROUTE_REFRESH: + bgp1_tree = proto_item_add_subtree(ti, ett_bgp_route_refresh); + break; default: bgp1_tree = proto_item_add_subtree(ti, ett_bgp); break; @@ -1265,6 +1461,9 @@ dissect_bgp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) case BGP_KEEPALIVE: /* no data in KEEPALIVE messages */ break; + case BGP_ROUTE_REFRESH: + dissect_bgp_route_refresh(pd, offset + i, fd, bgp1_tree); + break; default: break; } @@ -1299,9 +1498,12 @@ proto_register_bgp(void) &ett_bgp_open, &ett_bgp_update, &ett_bgp_notification, + &ett_bgp_route_refresh, &ett_bgp_as_paths, &ett_bgp_communities, &ett_bgp_cluster_list, + &ett_bgp_options, + &ett_bgp_option, }; proto_bgp = proto_register_protocol("Border Gateway Protocol", "bgp"); @@ -1312,5 +1514,5 @@ proto_register_bgp(void) void proto_reg_handoff_bgp(void) { - old_dissector_add("tcp.port", TCP_PORT_BGP, dissect_bgp); + old_dissector_add("tcp.port", BGP_TCP_PORT, dissect_bgp); } diff --git a/packet-bgp.h b/packet-bgp.h index 3902c5ffbd..94a6f86ae7 100644 --- a/packet-bgp.h +++ b/packet-bgp.h @@ -1,7 +1,7 @@ /* packet-bgp.c * Definitions for BGP packet disassembly structures and routine * - * $Id: packet-bgp.h,v 1.9 2000/04/11 14:21:37 itojun Exp $ + * $Id: packet-bgp.h,v 1.10 2000/12/25 05:28:40 itojun Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -33,12 +33,14 @@ #define BGP_MIN_UPDATE_MSG_SIZE 23 #define BGP_MIN_NOTIFICATION_MSG_SIZE 21 #define BGP_MIN_KEEPALVE_MSG_SIZE BGP_HEADER_SIZE +#define BGP_TCP_PORT 179 /* BGP message types */ #define BGP_OPEN 1 #define BGP_UPDATE 2 #define BGP_NOTIFICATION 3 #define BGP_KEEPALIVE 4 +#define BGP_ROUTE_REFRESH 5 /* BGP header */ struct bgp { @@ -70,6 +72,16 @@ struct bgp_notification { /* data should follow */ }; +/* BGP ROUTE-REFRESH message */ +struct bgp_route_refresh { + guint8 bgpr_marker[BGP_MARKER_SIZE]; + guint16 bgpr_len; + guint8 bgpr_type; + guint16 bgpr_afi; + guint8 bgpr_reserved; + guint8 bgpr_safi; +}; + /* path attribute */ struct bgp_attr { guint8 bgpa_flags; @@ -85,10 +97,17 @@ struct bgp_attr { /* AS_PATH segment types */ #define AS_SET 1 /* RFC1771 */ #define AS_SEQUENCE 2 /* RFC1771 */ -/* This is wrong according to the RFC... in the Zebra code they say that - cisco reversed it. Packet traces seem to agree. */ -#define AS_CONFED_SET 4 /* RFC1965 */ -#define AS_CONFED_SEQUENCE 3 /* RFC1965 */ +#define AS_CONFED_SET 4 /* RFC1965 has the wrong values, corrected in */ +#define AS_CONFED_SEQUENCE 3 /* draft-ietf-idr-bgp-confed-rfc1965bis-01.txt */ + +/* OPEN message Optional Parameter types */ +#define BGP_OPTION_AUTHENTICATION 1 /* RFC1771 */ +#define BGP_OPTION_CAPABILITY 2 /* RFC2842 */ + +/* BGP capability code */ +#define BGP_CAPABILITY_RESERVED 0 /* RFC2434 */ +#define BGP_CAPABILITY_MULTIPROTOCOL 1 /* RFC2858 */ +#define BGP_CAPABILITY_ROUTE_REFRESH 2 /* RFC2918 */ /* well-known communities, from RFC1997 */ #define BGP_COMM_NO_EXPORT 0xFFFFFF01 @@ -106,13 +125,13 @@ struct bgp_attr { #define BGPTYPE_ATOMIC_AGGREGATE 6 /* RFC1771 */ #define BGPTYPE_AGGREGATOR 7 /* RFC1771 */ #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ -#define BGPTYPE_ORIGINATOR_ID 9 /* RFC1966 */ -#define BGPTYPE_CLUSTER_LIST 10 /* RFC1966 */ +#define BGPTYPE_ORIGINATOR_ID 9 /* RFC2796 */ +#define BGPTYPE_CLUSTER_LIST 10 /* RFC2796 */ #define BGPTYPE_DPA 11 /* work in progress */ #define BGPTYPE_ADVERTISER 12 /* RFC1863 */ #define BGPTYPE_RCID_PATH 13 /* RFC1863 */ -#define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */ -#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */ +#define BGPTYPE_MP_REACH_NLRI 14 /* RFC2858 */ +#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2858 */ /* RFC1700 address family numbers */ #define AFNUM_INET 1