bgp route refresh/MP capability option.

Greg Hankins <gregh@twoguys.org>

svn path=/trunk/; revision=2780
This commit is contained in:
Jun-ichiro itojun Hagino 2000-12-25 05:28:40 +00:00
parent 9314e65702
commit b56e34d396
2 changed files with 247 additions and 26 deletions

View File

@ -2,14 +2,16 @@
* Routines for BGP packet dissection.
* Copyright 1999, Jun-ichiro itojun Hagino <itojun@itojun.org>
*
* $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);
}

View File

@ -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 <gerald@zing.org>
@ -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