MP-BGP message support, from Thierry Stagiaire.
svn path=/trunk/; revision=3534
This commit is contained in:
parent
58304dd1f7
commit
04734ec83d
4
AUTHORS
4
AUTHORS
|
@ -678,6 +678,10 @@ B. Johannessen <bob@havoq.com> {
|
|||
Gnutella support
|
||||
}
|
||||
|
||||
Thierry Stagiaire <thierry.pelle@rd.francetelecom.fr> {
|
||||
MP-BGP message support
|
||||
}
|
||||
|
||||
Alain Magloire <alainm@rcsm.ece.mcgill.ca> was kind enough to
|
||||
give his permission to use his version of snprintf.c.
|
||||
|
||||
|
|
|
@ -1123,6 +1123,7 @@ B<http://www.ethereal.com>.
|
|||
Mark Burton <markb@ordern.com>
|
||||
Javier Achirica <achirica@ttd.net>
|
||||
B. Johannessen <bob@havoq.com>
|
||||
Thierry Stagiaire <thierry.pelle@rd.francetelecom.fr>
|
||||
|
||||
Alain Magloire <alainm@rcsm.ece.mcgill.ca> was kind enough to give his
|
||||
permission to use his version of snprintf.c.
|
||||
|
|
421
packet-bgp.c
421
packet-bgp.c
|
@ -2,7 +2,7 @@
|
|||
* Routines for BGP packet dissection.
|
||||
* Copyright 1999, Jun-ichiro itojun Hagino <itojun@itojun.org>
|
||||
*
|
||||
* $Id: packet-bgp.c,v 1.37 2001/05/30 07:48:23 guy Exp $
|
||||
* $Id: packet-bgp.c,v 1.38 2001/06/10 02:08:09 guy Exp $
|
||||
*
|
||||
* Supports:
|
||||
* RFC1771 A Border Gateway Protocol 4 (BGP-4)
|
||||
|
@ -12,6 +12,7 @@
|
|||
* RFC2842 Capabilities Advertisement with BGP-4
|
||||
* RFC2858 Multiprotocol Extensions for BGP-4
|
||||
* RFC2918 Route Refresh Capability for BGP-4
|
||||
* Draft Ramahandra on Extended Communities Extentions
|
||||
*
|
||||
* TODO:
|
||||
* Destination Preference Attribute for BGP (work in progress)
|
||||
|
@ -153,18 +154,22 @@ static const value_string bgpattr_type[] = {
|
|||
{ BGPTYPE_CLUSTER_LIST, "CLUSTER_LIST" },
|
||||
{ BGPTYPE_MP_REACH_NLRI, "MP_REACH_NLRI" },
|
||||
{ BGPTYPE_MP_UNREACH_NLRI, "MP_UNREACH_NLRI" },
|
||||
{ BGPTYPE_EXTENDED_COMMUNITY, "EXTENDED_COMMUNITIES" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* Subsequent address family identifier, RFC2283 section 7 */
|
||||
static const value_string bgpattr_nlri_safi[] = {
|
||||
{ 0, "Reserved" },
|
||||
{ 1, "Unicast" },
|
||||
{ 2, "Multicast" },
|
||||
{ 3, "Unicast+Multicast" },
|
||||
/* Beware : See also MAX_SIZE_OF_EXT_COM_NAMES */
|
||||
static const value_string bgpext_com_type[] = {
|
||||
{ BGP_EXT_COM_RT_0, "Route Target" },
|
||||
{ BGP_EXT_COM_RT_1, "Route Target" },
|
||||
{ BGP_EXT_COM_RO_0, "Route Origin" },
|
||||
{ BGP_EXT_COM_RO_1, "Route Origin" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* MUST be resized if a longer named extended community is added */
|
||||
#define MAX_SIZE_OF_EXT_COM_NAMES 20
|
||||
|
||||
static const value_string afnumber[] = {
|
||||
{ 0, "Reserved" },
|
||||
{ AFNUM_INET, "IPv4" },
|
||||
|
@ -186,6 +191,19 @@ static const value_string afnumber[] = {
|
|||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* Subsequent address family identifier, RFC2858 */
|
||||
static const value_string bgpattr_nlri_safi[] = {
|
||||
{ 0, "Reserved" },
|
||||
{ SAFNUM_UNICAST, "Unicast" },
|
||||
{ SAFNUM_MULCAST, "Multicast" },
|
||||
{ SAFNUM_UNIMULC, "Unicast+Multicast" },
|
||||
{ SAFNUM_LBVPNIP, "Labeled VPN-IPv4" }, /* draft-rosen-rfc2547bis-03 */
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* Maximal size of an IP address string */
|
||||
#define MAX_SIZE_OF_IP_ADDR_STRING 16
|
||||
|
||||
static int proto_bgp = -1;
|
||||
static int hf_bgp_type = -1;
|
||||
|
||||
|
@ -196,6 +214,7 @@ static gint ett_bgp_attr = -1;
|
|||
static gint ett_bgp_attr_flags = -1;
|
||||
static gint ett_bgp_mp_reach_nlri = -1;
|
||||
static gint ett_bgp_mp_unreach_nlri = -1;
|
||||
static gint ett_bgp_mp_snpa = -1;
|
||||
static gint ett_bgp_nlri = -1;
|
||||
static gint ett_bgp_open = -1;
|
||||
static gint ett_bgp_update = -1;
|
||||
|
@ -206,7 +225,7 @@ static gint ett_bgp_communities = -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 */
|
||||
|
||||
static gint ett_bgp_extended_communities = -1 ; /* extended communities list tree */
|
||||
/*
|
||||
* Decode an IPv4 prefix.
|
||||
*/
|
||||
|
@ -261,6 +280,198 @@ decode_prefix6(tvbuff_t *tvb, gint offset, char *buf, int buflen)
|
|||
return(1 + length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode an MPLS label stack
|
||||
*/
|
||||
static int
|
||||
decode_MPLS_stack(tvbuff_t *tvb, gint offset, char *buf, int buflen)
|
||||
{
|
||||
guint32 label_entry; /* an MPLS label enrty (label + COS field + stack bit */
|
||||
gint index; /* index for the label stack */
|
||||
|
||||
index = offset ;
|
||||
label_entry = 0x000000 ;
|
||||
|
||||
buf[0] = '\0' ;
|
||||
|
||||
while ((label_entry && 0x000001) == 0) {
|
||||
|
||||
label_entry = tvb_get_ntoh24(tvb, index) ;
|
||||
snprintf(buf, buflen,"%s%u%s", buf, (label_entry >> 4), ((label_entry && 0x000001) == 0) ? "," : " (bottom)");
|
||||
index += 3 ;
|
||||
}
|
||||
|
||||
return((index - offset) / 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a multiprotocol address
|
||||
*/
|
||||
|
||||
static int
|
||||
mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf, int buflen)
|
||||
{
|
||||
int length; /* length of the address in byte */
|
||||
guint8 ip4addr[4],ip4addr2[4]; /* IPv4 address */
|
||||
guint16 rd_type; /* Route Distinguisher type */
|
||||
struct e_in6_addr ip6addr; /* IPv6 address */
|
||||
|
||||
length = 0 ;
|
||||
switch (afi) {
|
||||
case AFNUM_INET:
|
||||
switch (safi) {
|
||||
case SAFNUM_UNICAST:
|
||||
case SAFNUM_MULCAST:
|
||||
case SAFNUM_UNIMULC:
|
||||
length = 4 ;
|
||||
tvb_memcpy(tvb, ip4addr, offset, 4);
|
||||
snprintf(buf, buflen, "%s", ip_to_str(ip4addr));
|
||||
break;
|
||||
case SAFNUM_LBVPNIP:
|
||||
rd_type=tvb_get_ntohs(tvb,offset) ;
|
||||
switch (rd_type) {
|
||||
case FORMAT_AS2_LOC:
|
||||
length = 12;
|
||||
tvb_memcpy(tvb, ip4addr, offset + 8, 4);
|
||||
snprintf(buf, buflen, "Empty Label Stack RD=%u:%u IP=%s",
|
||||
tvb_get_ntohs(tvb, offset + 2),
|
||||
tvb_get_ntohl(tvb, offset + 4),
|
||||
ip_to_str(ip4addr));
|
||||
break;
|
||||
case FORMAT_IP_LOC:
|
||||
length = 12;
|
||||
tvb_memcpy(tvb, ip4addr, offset + 2, 4); /* IP part of the RD */
|
||||
tvb_memcpy(tvb, ip4addr2, offset +6, 4); /* IP address of the VPN-IPv4 */
|
||||
snprintf(buf, buflen, "Empty Label Stack RD=%s:%u IP=%s",
|
||||
ip_to_str(ip4addr),
|
||||
tvb_get_ntohs(tvb, offset + 6),
|
||||
ip_to_str(ip4addr2));
|
||||
break ;
|
||||
default:
|
||||
length = 0 ;
|
||||
snprintf(buf, buflen, "Unknown labeled VPN-IPv4 address format");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
length = 0 ;
|
||||
snprintf(buf, buflen, "Unknown SAFI value for AFI %u", afi);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AFNUM_INET6:
|
||||
length = 16 ;
|
||||
tvb_memcpy(tvb, ip6addr.u6_addr.u6_addr8,offset, sizeof(ip6addr));
|
||||
snprintf(buf, sizeof(buf), "%s", ip6_to_str(&ip6addr));
|
||||
break;
|
||||
default:
|
||||
length = 0 ;
|
||||
snprintf(buf, buflen, "Unknown AFI value");
|
||||
break;
|
||||
}
|
||||
return(length) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a multiprotocol prefix
|
||||
*/
|
||||
static int
|
||||
decode_prefix_MP(guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf, int buflen)
|
||||
{
|
||||
int length; /* length of the prefix in byte */
|
||||
int plen; /* length of the prefix in bit */
|
||||
int labnum; /* number of labels */
|
||||
guint8 ip4addr[4],ip4addr2[4]; /* IPv4 address */
|
||||
guint16 rd_type; /* Route Distinguisher type */
|
||||
char lab_stk[256]; /* label stack */
|
||||
|
||||
length = 0 ;
|
||||
|
||||
switch (afi) {
|
||||
case AFNUM_INET:
|
||||
switch (safi) {
|
||||
case SAFNUM_UNICAST:
|
||||
case SAFNUM_MULCAST:
|
||||
case SAFNUM_UNIMULC:
|
||||
length = decode_prefix4(tvb, offset, buf, buflen) - 1 ;
|
||||
break;
|
||||
case SAFNUM_LBVPNIP:
|
||||
plen = tvb_get_guint8(tvb,offset) ;
|
||||
|
||||
labnum = decode_MPLS_stack(tvb, offset + 1, lab_stk, sizeof(lab_stk));
|
||||
|
||||
offset += (1 + labnum * 3);
|
||||
plen -= (labnum * 3*8);
|
||||
|
||||
rd_type=tvb_get_ntohs(tvb,offset) ;
|
||||
plen -= 8*8;
|
||||
|
||||
switch (rd_type) {
|
||||
case FORMAT_AS2_LOC: /* Code borrowed from the decode_prefix4 function */
|
||||
if (plen < 0 || 32 < plen) {
|
||||
length = 0 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
length = (plen + 7) / 8;
|
||||
memset(ip4addr, 0, sizeof(ip4addr));
|
||||
tvb_memcpy(tvb, ip4addr, offset + 8, length);
|
||||
if (plen % 8)
|
||||
ip4addr[length - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
|
||||
|
||||
snprintf(buf,buflen, "Label Stack=%s RD=%u:%u, IP=%s/%d",
|
||||
lab_stk,
|
||||
tvb_get_ntohs(tvb, offset + 2),
|
||||
tvb_get_ntohl(tvb, offset + 4),
|
||||
ip_to_str(ip4addr),
|
||||
plen);
|
||||
length += (labnum * 3 + 8) ;
|
||||
break ;
|
||||
case FORMAT_IP_LOC: /* Code borrowed from the decode_prefix4 function */
|
||||
tvb_memcpy(tvb, ip4addr, offset + 2, 4);
|
||||
|
||||
if (plen < 0 || 32 < plen) {
|
||||
length = 0 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
length = (plen + 7) / 8;
|
||||
memset(ip4addr2, 0, sizeof(ip4addr2));
|
||||
tvb_memcpy(tvb, ip4addr2, offset + 8, length);
|
||||
if (plen % 8)
|
||||
ip4addr2[length - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
|
||||
|
||||
snprintf(buf,buflen, "Label Stack=%s RD=%s:%u, IP=%s/%d",
|
||||
lab_stk,
|
||||
ip_to_str(ip4addr),
|
||||
tvb_get_ntohs(tvb, offset + 6),
|
||||
ip_to_str(ip4addr2),
|
||||
plen);
|
||||
length += (labnum * 3 + 8) ;
|
||||
break ;
|
||||
default:
|
||||
length = 0 ;
|
||||
snprintf(buf,buflen, "Unkown labeled VPN-IPv4 address format");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
length = 0 ;
|
||||
snprintf(buf,buflen, "Unkown SAFI value for AFI %u", afi);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AFNUM_INET6:
|
||||
length = decode_prefix6(tvb, offset, buf, buflen) - 1 ;
|
||||
break;
|
||||
default:
|
||||
length = 0 ;
|
||||
snprintf(buf,buflen, "Unkown AFI value");
|
||||
break;
|
||||
}
|
||||
return(1 + length) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dissect a BGP OPEN message.
|
||||
*/
|
||||
|
@ -471,11 +682,13 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
gint o; /* packet offset */
|
||||
gint q; /* tmp */
|
||||
gint end; /* message end */
|
||||
gint ext_com; /* EXTENDED COMMUNITY type */
|
||||
int len; /* tmp */
|
||||
int advance; /* tmp */
|
||||
proto_item *ti; /* tree item */
|
||||
proto_tree *subtree; /* subtree for attibutes */
|
||||
proto_tree *subtree2; /* subtree for attibutes */
|
||||
proto_tree *subtree3; /* subtree for attibutes */
|
||||
proto_tree *subtree; /* subtree for attributes */
|
||||
proto_tree *subtree2; /* subtree for attributes */
|
||||
proto_tree *subtree3; /* subtree for attributes */
|
||||
proto_tree *as_paths_tree; /* subtree for AS_PATHs */
|
||||
proto_tree *as_path_tree; /* subtree for AS_PATH */
|
||||
proto_tree *communities_tree; /* subtree for COMMUNITIES */
|
||||
|
@ -487,9 +700,9 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
char *as_path_str = NULL; /* AS_PATH string */
|
||||
char *communities_str = NULL; /* COMMUNITIES string */
|
||||
char *cluster_list_str = NULL; /* CLUSTER_LIST string */
|
||||
char *ext_com_str = NULL; /* EXTENDED COMMUNITY list */
|
||||
char junk_buf[256]; /* tmp */
|
||||
guint8 ipaddr[4]; /* IPv4 address */
|
||||
struct e_in6_addr ip6addr; /* IPv6 address */
|
||||
|
||||
hlen = tvb_get_ntohs(tvb, offset + BGP_MARKER_SIZE);
|
||||
o = offset + BGP_HEADER_SIZE;
|
||||
|
@ -516,7 +729,6 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
else {
|
||||
o += len;
|
||||
}
|
||||
|
||||
/* check for advertisements */
|
||||
len = tvb_get_ntohs(tvb, o);
|
||||
proto_tree_add_text(tree, tvb, o, 2, "Total path attribute length: %u %s",
|
||||
|
@ -531,6 +743,7 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
int alen, aoff;
|
||||
char *msg;
|
||||
guint16 af;
|
||||
guint8 saf;
|
||||
int off, snpa;
|
||||
|
||||
tvb_memcpy(tvb, (guint8 *)&bgpa, o + i, sizeof(bgpa));
|
||||
|
@ -751,6 +964,30 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
cluster_list_str, alen + aoff,
|
||||
(alen + aoff == 1) ? "byte" : "bytes");
|
||||
break;
|
||||
case BGPTYPE_EXTENDED_COMMUNITY:
|
||||
if (alen %8 != 0)
|
||||
goto default_attribute_top;
|
||||
q = o + i + aoff ;
|
||||
end = o + i + aoff + alen ;
|
||||
ext_com_str = malloc((alen / 8)*MAX_SIZE_OF_EXT_COM_NAMES) ;
|
||||
if (ext_com_str == NULL) break ;
|
||||
ext_com_str[0] = '\0' ;
|
||||
while (q < end) {
|
||||
ext_com = tvb_get_ntohs(tvb,q) ;
|
||||
snprintf(junk_buf, sizeof(junk_buf), "%s", val_to_str(ext_com,bgpext_com_type,"Unknown"));
|
||||
strncat(ext_com_str,junk_buf,sizeof(junk_buf));
|
||||
q = q + 8 ;
|
||||
if (q<end) strncat(ext_com_str,",",1);
|
||||
}
|
||||
ti = proto_tree_add_text(subtree,tvb,o+i,alen+aoff,
|
||||
"%s : %s (%u %s)",
|
||||
val_to_str(bgpa.bgpa_type,bgpattr_type,"Unknown"),
|
||||
ext_com_str,
|
||||
alen,
|
||||
(alen ==1 ) ? "byte" : "bytes");
|
||||
free(ext_com_str) ;
|
||||
break;
|
||||
|
||||
default:
|
||||
default_attribute_top:
|
||||
ti = proto_tree_add_text(subtree, tvb, o + i, alen + aoff,
|
||||
|
@ -1050,58 +1287,29 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
proto_tree_add_text(subtree2, tvb, o + i + aoff, 2,
|
||||
"Address family: %s (%u)",
|
||||
val_to_str(af, afnumber, "Unknown"), af);
|
||||
saf = tvb_get_guint8(tvb, o + i + aoff + 2) ;
|
||||
proto_tree_add_text(subtree2, tvb, o + i + aoff + 2, 1,
|
||||
"Subsequent address family identifier: %s (%u)",
|
||||
val_to_str(tvb_get_guint8(tvb, o + i + aoff + 2), bgpattr_nlri_safi,
|
||||
tvb_get_guint8(tvb, o + i + aoff + 2) >= 128 ? "Vendor specific" : "Unknown"),
|
||||
tvb_get_guint8(tvb, o + i + aoff + 2));
|
||||
val_to_str(saf, bgpattr_nlri_safi, saf >= 128 ? "Vendor specific" : "Unknown"),
|
||||
saf);
|
||||
advance = tvb_get_guint8(tvb, o + i + aoff + 3);
|
||||
ti = proto_tree_add_text(subtree2, tvb, o + i + aoff + 3, 1,
|
||||
"Next hop network address (%d %s)",
|
||||
tvb_get_guint8(tvb, o + i + aoff + 3),
|
||||
(tvb_get_guint8(tvb, o + i + aoff + 3) == 1) ? "byte" : "bytes");
|
||||
if (af == AFNUM_INET || af == AFNUM_INET6) {
|
||||
int j, advance;
|
||||
const char *s;
|
||||
advance, (advance == 1) ? "byte" : "bytes");
|
||||
|
||||
subtree3 = proto_item_add_subtree(ti,
|
||||
ett_bgp_mp_reach_nlri);
|
||||
advance = mp_addr_to_str(af, saf, tvb, o + i + aoff + 4, junk_buf, sizeof(junk_buf)) ;
|
||||
proto_tree_add_text(subtree2, tvb,o + i + aoff + 4, advance,
|
||||
"Next hop: %s (%u)", junk_buf, advance);
|
||||
alen -= advance + 4;
|
||||
aoff += advance + 4 ;
|
||||
|
||||
j = 0;
|
||||
while (j < tvb_get_guint8(tvb, o + i + aoff + 3)) {
|
||||
if (af == AFNUM_INET)
|
||||
advance = 4;
|
||||
else if (af == AFNUM_INET6)
|
||||
advance = 16;
|
||||
else
|
||||
break;
|
||||
if (j + advance > tvb_get_guint8(tvb, o + i + aoff + 3))
|
||||
break;
|
||||
|
||||
if (af == AFNUM_INET) {
|
||||
tvb_memcpy(tvb, ipaddr, o + i + aoff + 4 + j, 4);
|
||||
s = ip_to_str(ipaddr);
|
||||
} else {
|
||||
tvb_memcpy(tvb, ip6addr.u6_addr.u6_addr8,
|
||||
o + i + aoff + 4 + j, sizeof ip6addr);
|
||||
s = ip6_to_str(&ip6addr);
|
||||
}
|
||||
proto_tree_add_text(subtree3, tvb,
|
||||
o + i + aoff + 4 + j, advance,
|
||||
"Next hop: %s", s);
|
||||
j += advance;
|
||||
}
|
||||
}
|
||||
|
||||
alen -= tvb_get_guint8(tvb, o + i + aoff + 3) + 4;
|
||||
aoff += tvb_get_guint8(tvb, o + i + aoff + 3) + 4;
|
||||
off = 0;
|
||||
snpa = tvb_get_guint8(tvb, o + i + aoff);
|
||||
ti = proto_tree_add_text(subtree2, tvb, o + i + aoff, 1,
|
||||
"Subnetwork points of attachment: %u", snpa);
|
||||
off++;
|
||||
if (snpa)
|
||||
subtree3 = proto_item_add_subtree(ti,
|
||||
ett_bgp_mp_reach_nlri);
|
||||
if (snpa) {
|
||||
subtree3 = proto_item_add_subtree(ti, ett_bgp_mp_snpa);
|
||||
for (/*nothing*/; snpa > 0; snpa--) {
|
||||
proto_tree_add_text(subtree3, tvb, o + i + aoff + off, 1,
|
||||
"SNPA length: %u", tvb_get_guint8(tvb, o + i + aoff + off));
|
||||
|
@ -1112,81 +1320,51 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
(tvb_get_guint8(tvb, o + i + aoff + off - 1) == 1) ? "byte" : "bytes");
|
||||
off += tvb_get_guint8(tvb, o + i + aoff + off - 1);
|
||||
}
|
||||
|
||||
}
|
||||
alen -= off;
|
||||
aoff += off;
|
||||
|
||||
ti = proto_tree_add_text(subtree2, tvb, o + i + aoff, alen,
|
||||
"Network layer reachability information (%u %s)",
|
||||
alen, (alen == 1) ? "byte" : "bytes");
|
||||
if (alen)
|
||||
subtree3 = proto_item_add_subtree(ti,
|
||||
ett_bgp_mp_unreach_nlri);
|
||||
if (alen) {
|
||||
subtree3 = proto_item_add_subtree(ti,ett_bgp_mp_reach_nlri);
|
||||
|
||||
while (alen > 0) {
|
||||
int advance;
|
||||
char buf[256];
|
||||
|
||||
if (af == AFNUM_INET) {
|
||||
advance = decode_prefix4(tvb, o + i + aoff, buf,
|
||||
sizeof(buf));
|
||||
} else if (af == AFNUM_INET6) {
|
||||
advance = decode_prefix6(tvb, o + i + aoff, buf,
|
||||
sizeof(buf));
|
||||
} else
|
||||
break;
|
||||
if (advance < 0)
|
||||
break;
|
||||
if (alen < advance)
|
||||
break;
|
||||
proto_tree_add_text(subtree3, tvb, o + i + aoff, advance,
|
||||
"Network layer reachability information: %s", buf);
|
||||
|
||||
advance = decode_prefix_MP(af, saf, tvb, o + i + aoff , junk_buf, sizeof(junk_buf)) ;
|
||||
proto_tree_add_text(subtree3, tvb, o + i + aoff, advance, "%s", junk_buf) ;
|
||||
alen -= advance;
|
||||
aoff += advance;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case BGPTYPE_MP_UNREACH_NLRI:
|
||||
af = tvb_get_ntohs(tvb, o + i + aoff);
|
||||
proto_tree_add_text(subtree2, tvb, o + i + aoff, 2,
|
||||
"Address family: %s (%u)",
|
||||
val_to_str(af, afnumber, "Unknown"), af);
|
||||
saf = tvb_get_guint8(tvb, o + i + aoff + 2) ;
|
||||
proto_tree_add_text(subtree2, tvb, o + i + aoff + 2, 1,
|
||||
"Subsequent address family identifier: %s (%u)",
|
||||
val_to_str(tvb_get_guint8(tvb, o + i + aoff + 2), bgpattr_nlri_safi,
|
||||
tvb_get_guint8(tvb, o + i + aoff + 2) >= 128 ? "Vendor specific" : "Unknown"),
|
||||
tvb_get_guint8(tvb, o + i + aoff + 2));
|
||||
val_to_str(saf, bgpattr_nlri_safi, saf >= 128 ? "Vendor specific" : "Unknown"),
|
||||
saf);
|
||||
ti = proto_tree_add_text(subtree2, tvb, o + i + aoff + 3,
|
||||
alen - 3, "Withdrawn routes (%u %s)", alen - 3,
|
||||
(alen - 3 == 1) ? "byte" : "bytes");
|
||||
|
||||
alen -= 3;
|
||||
aoff += 3;
|
||||
if (alen > 0)
|
||||
subtree3 = proto_item_add_subtree(ti,
|
||||
ett_bgp_mp_unreach_nlri);
|
||||
if (alen > 0) {
|
||||
subtree3 = proto_item_add_subtree(ti,ett_bgp_mp_unreach_nlri);
|
||||
|
||||
while (alen > 0) {
|
||||
int advance;
|
||||
char buf[256];
|
||||
|
||||
if (af == AFNUM_INET) {
|
||||
advance = decode_prefix4(tvb, o + i + aoff, buf,
|
||||
sizeof(buf));
|
||||
} else if (af == AFNUM_INET6) {
|
||||
advance = decode_prefix6(tvb, o + i + aoff, buf,
|
||||
sizeof(buf));
|
||||
} else
|
||||
break;
|
||||
if (advance < 0)
|
||||
break;
|
||||
if (alen < advance)
|
||||
break;
|
||||
proto_tree_add_text(subtree3, tvb, o + i + aoff, advance,
|
||||
"Withdrawn route: %s", buf);
|
||||
advance = decode_prefix_MP(af, saf, tvb, o + i + aoff , junk_buf, sizeof(junk_buf)) ;
|
||||
|
||||
proto_tree_add_text(subtree3, tvb, o + i + aoff, advance, "%s", junk_buf) ;
|
||||
alen -= advance;
|
||||
aoff += advance;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case BGPTYPE_CLUSTER_LIST:
|
||||
if (alen % 4 != 0) {
|
||||
|
@ -1219,6 +1397,44 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
|
||||
free(cluster_list_str);
|
||||
break;
|
||||
case BGPTYPE_EXTENDED_COMMUNITY:
|
||||
if (alen %8 != 0) {
|
||||
proto_tree_add_text(subtree3, tvb, o + i + aoff, alen, "Extended community (invalid) : %u %s", alen,
|
||||
(alen == 1) ? "byte" : "bytes") ;
|
||||
} else {
|
||||
q = o + i + aoff ;
|
||||
end = o + i + aoff + alen ;
|
||||
ext_com_str = malloc(MAX_SIZE_OF_EXT_COM_NAMES+MAX_SIZE_OF_IP_ADDR_STRING*2+1) ;
|
||||
if (ext_com_str == NULL) break ;
|
||||
ti = proto_tree_add_text(subtree2,tvb,q,alen, "Carried Extended communities");
|
||||
subtree3 = proto_item_add_subtree(ti,ett_bgp_extended_communities) ;
|
||||
|
||||
while (q < end) {
|
||||
ext_com_str[0] = '\0' ;
|
||||
ext_com = tvb_get_ntohs(tvb,q) ;
|
||||
snprintf(junk_buf, sizeof(junk_buf), "%s", val_to_str(ext_com,bgpext_com_type,"Unknown"));
|
||||
strncat(ext_com_str,junk_buf,sizeof(junk_buf));
|
||||
switch (ext_com) {
|
||||
case BGP_EXT_COM_RT_0:
|
||||
case BGP_EXT_COM_RO_0:
|
||||
snprintf(junk_buf, sizeof(junk_buf), ": %u%s%d",tvb_get_ntohs(tvb,q+2),":",tvb_get_ntohl(tvb,q+4));
|
||||
break ;
|
||||
case BGP_EXT_COM_RT_1:
|
||||
case BGP_EXT_COM_RO_1:
|
||||
tvb_memcpy(tvb,ipaddr,q+2,4);
|
||||
snprintf(junk_buf, sizeof(junk_buf), ": %s%s%u",ip_to_str(ipaddr),":",tvb_get_ntohs(tvb,q+6));
|
||||
break ;
|
||||
default:
|
||||
snprintf(junk_buf, sizeof(junk_buf), " ");
|
||||
break ;
|
||||
}
|
||||
strncat(ext_com_str,junk_buf,sizeof(junk_buf));
|
||||
proto_tree_add_text(subtree3,tvb,q,8, "%s",ext_com_str);
|
||||
q = q + 8 ;
|
||||
}
|
||||
free(ext_com_str) ;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_text(subtree2, tvb, o + i + aoff, alen,
|
||||
"Unknown (%d %s)", alen, (alen == 1) ? "byte" :
|
||||
|
@ -1228,6 +1444,7 @@ dissect_bgp_update(tvbuff_t *tvb, int offset, proto_tree *tree)
|
|||
|
||||
i += alen + aoff;
|
||||
}
|
||||
|
||||
o += 2 + len;
|
||||
|
||||
/* NLRI */
|
||||
|
@ -1486,6 +1703,7 @@ proto_register_bgp(void)
|
|||
&ett_bgp_attr_flags,
|
||||
&ett_bgp_mp_reach_nlri,
|
||||
&ett_bgp_mp_unreach_nlri,
|
||||
&ett_bgp_mp_snpa,
|
||||
&ett_bgp_nlri,
|
||||
&ett_bgp_open,
|
||||
&ett_bgp_update,
|
||||
|
@ -1496,6 +1714,7 @@ proto_register_bgp(void)
|
|||
&ett_bgp_cluster_list,
|
||||
&ett_bgp_options,
|
||||
&ett_bgp_option,
|
||||
&ett_bgp_extended_communities
|
||||
};
|
||||
|
||||
proto_bgp = proto_register_protocol("Border Gateway Protocol",
|
||||
|
|
20
packet-bgp.h
20
packet-bgp.h
|
@ -1,7 +1,7 @@
|
|||
/* packet-bgp.c
|
||||
* Definitions for BGP packet disassembly structures and routine
|
||||
*
|
||||
* $Id: packet-bgp.h,v 1.12 2001/05/16 18:52:36 guy Exp $
|
||||
* $Id: packet-bgp.h,v 1.13 2001/06/10 02:08:09 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -135,6 +135,18 @@ struct bgp_attr {
|
|||
#define BGPTYPE_RCID_PATH 13 /* RFC1863 */
|
||||
#define BGPTYPE_MP_REACH_NLRI 14 /* RFC2858 */
|
||||
#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2858 */
|
||||
#define BGPTYPE_EXTENDED_COMMUNITY 16 /* Draft Ramachandra */
|
||||
|
||||
/* Extended community type */
|
||||
#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) */
|
||||
#define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */
|
||||
#define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */
|
||||
|
||||
/* Extended community & Route dinstinguisher formats */
|
||||
#define FORMAT_AS2_LOC 0x00 /* Format AS(2bytes):AN(4bytes) */
|
||||
#define FORMAT_IP_LOC 0x01 /* Format IP address:AN(2bytes) */
|
||||
#define FORMAT_AS4_LOC 0x02 /* FOrmat AS(4bytes):AN(2bytes) */
|
||||
|
||||
/* RFC1700 address family numbers */
|
||||
#define AFNUM_INET 1
|
||||
|
@ -153,6 +165,12 @@ struct bgp_attr {
|
|||
#define AFNUM_BANYAN 14
|
||||
#define AFNUM_E164NSAP 15
|
||||
|
||||
/* RFC 2858 subsequent address family numbers */
|
||||
#define SAFNUM_UNICAST 1
|
||||
#define SAFNUM_MULCAST 2
|
||||
#define SAFNUM_UNIMULC 3
|
||||
#define SAFNUM_LBVPNIP 128 /* Draft-rosen-rfc2547bis-03 */
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue