Timo Sirainen pointed out a few problems with string handling in the

BGP code.  Replace many strings with GStrings.

svn path=/trunk/; revision=7693
This commit is contained in:
Gerald Combs 2003-05-20 03:01:21 +00:00
parent f921aee54d
commit 42d3c64449
1 changed files with 108 additions and 127 deletions

View File

@ -2,7 +2,7 @@
* Routines for BGP packet dissection.
* Copyright 1999, Jun-ichiro itojun Hagino <itojun@itojun.org>
*
* $Id: packet-bgp.c,v 1.79 2003/05/19 20:36:48 guy Exp $
* $Id: packet-bgp.c,v 1.80 2003/05/20 03:01:21 gerald Exp $
*
* Supports:
* RFC1771 A Border Gateway Protocol 4 (BGP-4)
@ -430,6 +430,7 @@ decode_prefix6(proto_tree *tree, int hf_addr, tvbuff_t *tvb, gint offset,
/*
* Decode an MPLS label stack
* XXX - Should we convert "buf" to a GString?
*/
static int
decode_MPLS_stack(tvbuff_t *tvb, gint offset, char *buf, size_t buflen)
@ -475,7 +476,7 @@ decode_MPLS_stack(tvbuff_t *tvb, gint offset, char *buf, size_t buflen)
*/
static int
mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf, int buflen)
mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, GString *buf)
{
int length; /* length of the address in byte */
guint8 ip4addr[4],ip4addr2[4]; /* IPv4 address */
@ -492,7 +493,7 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
case SAFNUM_MPLS_LABEL:
length = 4 ;
tvb_memcpy(tvb, ip4addr, offset, sizeof(ip4addr));
snprintf(buf, buflen, "%s", ip_to_str(ip4addr));
g_string_sprintf(buf, "%s", ip_to_str(ip4addr));
break;
case SAFNUM_LAB_VPNUNICAST:
case SAFNUM_LAB_VPNMULCAST:
@ -502,7 +503,7 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
case FORMAT_AS2_LOC:
length = 8 + sizeof(ip4addr);
tvb_memcpy(tvb, ip4addr, offset + 8, sizeof(ip4addr)); /* Next Hop */
snprintf(buf, buflen, "Empty Label Stack RD=%u:%u IP=%s",
g_string_sprintf(buf, "Empty Label Stack RD=%u:%u IP=%s",
tvb_get_ntohs(tvb, offset + 2),
tvb_get_ntohl(tvb, offset + 4),
ip_to_str(ip4addr));
@ -511,20 +512,20 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
length = 8 + sizeof(ip4addr);
tvb_memcpy(tvb, ip4addr, offset + 2, sizeof(ip4addr)); /* IP part of the RD */
tvb_memcpy(tvb, ip4addr2, offset + 8, sizeof(ip4addr)); /* Next Hop */
snprintf(buf, buflen, "Empty Label Stack RD=%s:%u IP=%s",
g_string_sprintf(buf, "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 (0x%04x)labeled VPN address format",rd_type);
g_string_sprintf(buf, "Unknown (0x%04x)labeled VPN address format",rd_type);
break;
}
break;
default:
length = 0 ;
snprintf(buf, buflen, "Unknown SAFI (%u) for AFI %u", safi, afi);
g_string_sprintf(buf, "Unknown SAFI (%u) for AFI %u", safi, afi);
break;
}
break;
@ -535,7 +536,7 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
case SAFNUM_UNIMULC:
length = 16 ;
tvb_memcpy(tvb, ip6addr.u6_addr.u6_addr8,offset, 16);
snprintf(buf, buflen, "%s", ip6_to_str(&ip6addr));
g_string_sprintf(buf, "%s", ip6_to_str(&ip6addr));
break;
case SAFNUM_LAB_VPNUNICAST:
case SAFNUM_LAB_VPNMULCAST:
@ -545,7 +546,7 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
case FORMAT_AS2_LOC:
length = 8 + 16;
tvb_memcpy(tvb, ip6addr.u6_addr.u6_addr8, offset + 8, 16); /* Next Hop */
snprintf(buf, buflen, "Empty Label Stack RD=%u:%u IP=%s",
g_string_sprintf(buf, "Empty Label Stack RD=%u:%u IP=%s",
tvb_get_ntohs(tvb, offset + 2),
tvb_get_ntohl(tvb, offset + 4),
ip6_to_str(&ip6addr));
@ -554,20 +555,20 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
length = 8 + 16;
tvb_memcpy(tvb, ip4addr, offset + 2, sizeof(ip4addr)); /* IP part of the RD */
tvb_memcpy(tvb, ip6addr.u6_addr.u6_addr8, offset + 8, 16); /* Next Hop */
snprintf(buf, buflen, "Empty Label Stack RD=%s:%u IP=%s",
g_string_sprintf(buf, "Empty Label Stack RD=%s:%u IP=%s",
ip_to_str(ip4addr),
tvb_get_ntohs(tvb, offset + 6),
ip6_to_str(&ip6addr));
break ;
default:
length = 0 ;
snprintf(buf, buflen, "Unknown (0x%04x)labeled VPN address format",rd_type);
g_string_sprintf(buf, "Unknown (0x%04x)labeled VPN address format",rd_type);
break;
}
break;
default:
length = 0 ;
snprintf(buf, buflen, "Unknown SAFI (%u) for AFI %u", safi, afi);
g_string_sprintf(buf, "Unknown SAFI (%u) for AFI %u", safi, afi);
break;
}
break;
@ -578,18 +579,18 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
case SAFNUM_LAB_VPNUNIMULC:
length = 4; /* the next-hop is simply an ipv4 addr */
tvb_memcpy(tvb, ip4addr, offset + 0, 4);
snprintf(buf, buflen, "IP=%s",
g_string_sprintf(buf, "IP=%s",
ip_to_str(ip4addr));
break;
default:
length = 0 ;
snprintf(buf, buflen, "Unknown SAFI (%u) for AFI %u", safi, afi);
g_string_sprintf(buf, "Unknown SAFI (%u) for AFI %u", safi, afi);
break;
}
break;
default:
length = 0 ;
snprintf(buf, buflen, "Unknown AFI (%u) value", afi);
g_string_sprintf(buf, "Unknown AFI (%u) value", afi);
break;
}
return(length) ;
@ -1307,16 +1308,17 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
guint8 length; /* AS_PATH length */
guint8 type; /* AS_PATH type */
guint32 as_path_item; /* item in AS_PATH segment */
char *as_path_str = NULL; /* AS_PATH string */
char *communities_str = NULL; /* COMMUNITIES string */
char *cluster_list_str = NULL; /* CLUSTER_LIST string */
char junk_buf[256]; /* tmp */
int junk_buf_len; /* tmp len */
static GString *as_path_gstr = NULL; /* AS_PATH GString */
static GString *communities_gstr = NULL; /* COMMUNITIES GString */
static GString *cluster_list_gstr = NULL; /* CLUSTER_LIST GString */
static GString *junk_gbuf = NULL; /* tmp */
guint8 ipaddr[4]; /* IPv4 address */
guint32 aggregator_as;
hlen = tvb_get_ntohs(tvb, BGP_MARKER_SIZE);
o = BGP_HEADER_SIZE;
if (junk_gbuf == NULL)
junk_gbuf = g_string_sized_new(0);
/* check for withdrawals */
len = tvb_get_ntohs(tvb, o);
@ -1394,9 +1396,10 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
/* must be freed by second switch! */
/* "tlen * 11" (10 digits + space) should be a good estimate
of how long the AS path string could be */
as_path_str = malloc((tlen + 1) * 11);
if (as_path_str == NULL) break;
as_path_str[0] = '\0';
if (as_path_gstr == NULL)
as_path_gstr = g_string_sized_new((tlen + 1) * 11);
if (as_path_gstr == NULL) break;
g_string_truncate(as_path_gstr, 0);
/* estimate the length of the AS number */
if (bgpa.bgpa_type == BGPTYPE_NEW_AS_PATH)
@ -1419,56 +1422,56 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
/* snarf each AS path */
while (q < end) {
type = tvb_get_guint8(tvb, q++);
if (strlen(as_path_str) != 0 &&
as_path_str[strlen(as_path_str) - 1] != ' ')
strcat(as_path_str, " ");
if (as_path_gstr->len > 1 &&
as_path_gstr->str[as_path_gstr->len - 1] != ' ')
g_string_append_c(as_path_gstr, ' ');
if (type == AS_SET) {
strcat(as_path_str, "{");
g_string_append_c(as_path_gstr, '{');
}
else if (type == AS_CONFED_SET) {
strcat(as_path_str, "[");
g_string_append_c(as_path_gstr, '[');
}
else if (type == AS_CONFED_SEQUENCE) {
strcat(as_path_str, "(");
g_string_append_c(as_path_gstr, '(');
}
length = tvb_get_guint8(tvb, q++);
/* snarf each value in path */
for (j = 0; j < length; j++) {
snprintf(junk_buf, sizeof(junk_buf), "%u%s",
g_string_sprintfa(as_path_gstr, "%u%s",
(asn_len == 2) ?
tvb_get_ntohs(tvb, q) : tvb_get_ntohl(tvb, q),
(type == AS_SET || type == AS_CONFED_SET) ?
", " : " ");
strncat(as_path_str, junk_buf, sizeof(junk_buf));
q += asn_len;
}
/* cleanup end of string */
if (type == AS_SET) {
as_path_str[strlen(as_path_str) - 2] = '}';
as_path_str[strlen(as_path_str) - 1] = '\0';
g_string_truncate(as_path_gstr, as_path_gstr->len - 2);
g_string_append_c(as_path_gstr, '}');
}
else if (type == AS_CONFED_SET) {
as_path_str[strlen(as_path_str) - 2] = ']';
as_path_str[strlen(as_path_str) - 1] = '\0';
g_string_truncate(as_path_gstr, as_path_gstr->len - 2);
g_string_append_c(as_path_gstr, ']');
}
else if (type == AS_CONFED_SEQUENCE) {
as_path_str[strlen(as_path_str) - 1] = ')';
g_string_truncate(as_path_gstr, as_path_gstr->len - 1);
g_string_append_c(as_path_gstr, ')');
}
else {
as_path_str[strlen(as_path_str) - 1] = '\0';
g_string_truncate(as_path_gstr, as_path_gstr->len - 1);
}
}
/* check for empty AS_PATH */
if (tlen == 0)
strncpy(as_path_str, "empty", 6);
g_string_sprintf(as_path_gstr, "empty");
ti = proto_tree_add_text(subtree, tvb, o + i, tlen + aoff,
"%s: %s (%u %s)",
val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
as_path_str, tlen + aoff,
as_path_gstr->str, tlen + aoff,
(tlen + aoff == 1) ? "byte" : "bytes");
break;
case BGPTYPE_NEXT_HOP:
@ -1535,36 +1538,34 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
/* "tlen * 12" (5 digits, a :, 5 digits + space ) should be
a good estimate of how long the communities string could
be */
communities_str = malloc((tlen + 1) * 12);
if (communities_str == NULL) break;
communities_str[0] = '\0';
memset(junk_buf, 0, sizeof(junk_buf));
if (communities_gstr == NULL)
communities_gstr = g_string_sized_new((tlen + 1) * 12);
if (communities_gstr == NULL) break;
g_string_truncate(communities_gstr, 0);
/* snarf each community */
while (q < end) {
/* check for well-known communities */
if (tvb_get_ntohl(tvb, q) == BGP_COMM_NO_EXPORT)
strncpy(junk_buf, "NO_EXPORT ", 10);
g_string_append(communities_gstr, "NO_EXPORT ");
else if (tvb_get_ntohl(tvb, q) == BGP_COMM_NO_ADVERTISE)
strncpy(junk_buf, "NO_ADVERTISE ", 13);
g_string_append(communities_gstr, "NO_ADVERTISE ");
else if (tvb_get_ntohl(tvb, q) == BGP_COMM_NO_EXPORT_SUBCONFED)
strncpy(junk_buf, "NO_EXPORT_SUBCONFED ", 20);
g_string_append(communities_gstr, "NO_EXPORT_SUBCONFED ");
else {
snprintf(junk_buf, sizeof(junk_buf), "%u:%u ",
g_string_sprintfa(communities_gstr, "%u:%u ",
tvb_get_ntohs(tvb, q),
tvb_get_ntohs(tvb, q + 2));
}
q += 4;
strncat(communities_str, junk_buf, sizeof(junk_buf));
}
/* cleanup end of string */
communities_str[strlen(communities_str) - 1] = '\0';
g_string_truncate(communities_gstr, communities_gstr->len - 1);
ti = proto_tree_add_text(subtree, tvb, o + i, tlen + aoff,
"%s: %s (%u %s)",
val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
communities_str, tlen + aoff,
communities_gstr->str, tlen + aoff,
(tlen + aoff == 1) ? "byte" : "bytes");
break;
case BGPTYPE_ORIGINATOR_ID:
@ -1589,25 +1590,24 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
/* "tlen * 16" (12 digits, 3 dots + space ) should be
a good estimate of how long the cluster_list string could
be */
cluster_list_str = malloc((tlen + 1) * 16);
if (cluster_list_str == NULL) break;
cluster_list_str[0] = '\0';
memset(junk_buf, 0, sizeof(junk_buf));
if (cluster_list_gstr == NULL)
cluster_list_gstr = g_string_sized_new((tlen + 1) * 16);
if (cluster_list_gstr == NULL) break;
g_string_truncate(cluster_list_gstr, 0);
/* snarf each cluster list */
tvb_memcpy(tvb, ipaddr, q, 4);
while (q < end) {
snprintf(junk_buf, sizeof(junk_buf), "%s ", ip_to_str(ipaddr));
strncat(cluster_list_str, junk_buf, sizeof(junk_buf));
g_string_sprintfa(cluster_list_gstr, "%s ", ip_to_str(ipaddr));
q += 4;
}
/* cleanup end of string */
cluster_list_str[strlen(cluster_list_str) - 1] = '\0';
g_string_truncate(cluster_list_gstr, cluster_list_gstr->len - 1);
ti = proto_tree_add_text(subtree, tvb, o + i, tlen + aoff,
"%s: %s (%u %s)",
val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
cluster_list_str, tlen + aoff,
cluster_list_gstr->str, tlen + aoff,
(tlen + aoff == 1) ? "byte" : "bytes");
break;
case BGPTYPE_EXTENDED_COMMUNITY:
@ -1630,34 +1630,33 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
subtree2 = proto_item_add_subtree(ti, ett_bgp_attr);
/* figure out flags */
junk_buf[0] = '\0';
g_string_truncate(junk_gbuf, 0);
if (bgpa.bgpa_flags & BGP_ATTR_FLAG_OPTIONAL) {
strncat(junk_buf, "Optional, ", 10);
g_string_append(junk_gbuf, "Optional, ");
}
else {
strncat(junk_buf, "Well-known, ", 12);
g_string_append(junk_gbuf, "Well-known, ");
}
if (bgpa.bgpa_flags & BGP_ATTR_FLAG_TRANSITIVE) {
strncat(junk_buf, "Transitive, ", 12);
g_string_append(junk_gbuf, "Transitive, ");
}
else {
strncat(junk_buf, "Non-transitive, ", 16);
g_string_append(junk_gbuf, "Non-transitive, ");
}
if (bgpa.bgpa_flags & BGP_ATTR_FLAG_PARTIAL) {
strncat(junk_buf, "Partial, ", 9);
g_string_append(junk_gbuf, "Partial, ");
}
else {
strncat(junk_buf, "Complete, ", 10);
g_string_append(junk_gbuf, "Complete, ");
}
if (bgpa.bgpa_flags & BGP_ATTR_FLAG_EXTENDED_LENGTH) {
strncat(junk_buf, "Extended Length, ", 17);
g_string_append(junk_gbuf, "Extended Length, ");
}
/* stomp last ", " */
j = strlen(junk_buf);
junk_buf[j - 2] = '\0';
g_string_truncate(junk_gbuf, junk_gbuf->len - 2);
ti = proto_tree_add_text(subtree2, tvb,
o + i + offsetof(struct bgp_attr, bgpa_flags), 1,
"Flags: 0x%02x (%s)", bgpa.bgpa_flags, junk_buf);
"Flags: 0x%02x (%s)", bgpa.bgpa_flags, junk_gbuf->str);
subtree3 = proto_item_add_subtree(ti, ett_bgp_attr_flags);
/* add flag bitfield subtrees */
@ -1705,14 +1704,8 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
break;
case BGPTYPE_AS_PATH:
case BGPTYPE_NEW_AS_PATH:
/* check for empty AS_PATH */
if (tlen == 0) {
free(as_path_str);
break;
}
ti = proto_tree_add_text(subtree2, tvb, o + i + aoff, tlen,
"AS path: %s", as_path_str);
"AS path: %s", as_path_gstr->str);
as_paths_tree = proto_item_add_subtree(ti, ett_bgp_as_paths);
/* (o + i + aoff) =
@ -1722,50 +1715,53 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
/* snarf each AS path tuple, we have to step through each one
again to make a separate subtree so we can't just reuse
as_path_str from above */
as_path_gstr from above */
/* XXX - Can we use some g_string*() trickery instead, e.g.
g_string_erase()? */
while (q < end) {
as_path_str[0] = '\0';
g_string_truncate(as_path_gstr, 0);
type = tvb_get_guint8(tvb, q++);
if (type == AS_SET) {
snprintf(as_path_str, 2, "{");
g_string_append_c(as_path_gstr, '{');
}
else if (type == AS_CONFED_SET) {
snprintf(as_path_str, 2, "[");
g_string_append_c(as_path_gstr, '[');
}
else if (type == AS_CONFED_SEQUENCE) {
snprintf(as_path_str, 2, "(");
g_string_append_c(as_path_gstr, '(');
}
length = tvb_get_guint8(tvb, q++);
/* snarf each value in path, we're just going to reuse
as_path_str since we already have it malloced */
/* snarf each value in path */
for (j = 0; j < length; j++) {
snprintf(junk_buf, sizeof(junk_buf), "%u%s",
g_string_sprintfa(as_path_gstr, "%u%s",
(asn_len == 2) ?
tvb_get_ntohs(tvb, q) : tvb_get_ntohl(tvb, q),
(type == AS_SET || type == AS_CONFED_SET) ? ", " : " ");
strncat(as_path_str, junk_buf, sizeof(junk_buf));
q += asn_len;
}
/* cleanup end of string */
if (type == AS_SET) {
as_path_str[strlen(as_path_str) - 2] = '}';
g_string_truncate(as_path_gstr, as_path_gstr->len - 2);
g_string_append_c(as_path_gstr, '}');
}
else if (type == AS_CONFED_SET) {
as_path_str[strlen(as_path_str) - 2] = ']';
g_string_truncate(as_path_gstr, as_path_gstr->len - 2);
g_string_append_c(as_path_gstr, ']');
}
else if (type == AS_CONFED_SEQUENCE) {
as_path_str[strlen(as_path_str) - 1] = ')';
g_string_truncate(as_path_gstr, as_path_gstr->len - 1);
g_string_append_c(as_path_gstr, ')');
}
else {
as_path_str[strlen(as_path_str) - 1] = '\0';
g_string_truncate(as_path_gstr, as_path_gstr->len - 1);
}
/* length here means number of ASs, ie length * 2 bytes */
ti = proto_tree_add_text(as_paths_tree, tvb,
q - length * asn_len - 2,
length * asn_len + 2, "AS path segment: %s", as_path_str);
length * asn_len + 2, "AS path segment: %s", as_path_gstr->str);
as_path_tree = proto_item_add_subtree(ti, ett_bgp_as_paths);
proto_tree_add_text(as_path_tree, tvb, q - length * asn_len - 2,
1, "Path segment type: %s (%u)",
@ -1790,7 +1786,6 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
}
}
free(as_path_str);
break;
case BGPTYPE_NEXT_HOP:
if (tlen != 4) {
@ -1857,12 +1852,11 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
proto_tree_add_text(subtree2, tvb, o + i + aoff, tlen,
"Communities (invalid): %u %s", tlen,
(tlen == 1) ? "byte" : "bytes");
free(communities_str);
break;
}
ti = proto_tree_add_text(subtree2, tvb, o + i + aoff, tlen,
"Communities: %s", communities_str);
"Communities: %s", communities_gstr->str);
communities_tree = proto_item_add_subtree(ti,
ett_bgp_communities);
@ -1898,7 +1892,6 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
q += 4;
}
free(communities_str);
break;
case BGPTYPE_ORIGINATOR_ID:
if (tlen != 4) {
@ -1953,13 +1946,13 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
j = 0;
while (j < nexthop_len) {
advance = mp_addr_to_str(af, saf, tvb, o + i + aoff + 4 + j,
junk_buf, sizeof(junk_buf)) ;
junk_gbuf) ;
if (advance == 0) /* catch if this is a unknown AFI type*/
break;
if (j + advance > nexthop_len)
break;
proto_tree_add_text(subtree3, tvb,o + i + aoff + 4 + j,
advance, "Next hop: %s (%u)", junk_buf, advance);
advance, "Next hop: %s (%u)", junk_gbuf->str, advance);
j += advance;
}
tlen -= nexthop_len + 4;
@ -2042,12 +2035,11 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
proto_tree_add_text(subtree2, tvb, o + i + aoff, tlen,
"Cluster list (invalid): %u %s", tlen,
(tlen == 1) ? "byte" : "bytes");
free(cluster_list_str);
break;
}
ti = proto_tree_add_text(subtree2, tvb, o + i + aoff, tlen,
"Cluster list: %s", cluster_list_str);
"Cluster list: %s", cluster_list_gstr->str);
cluster_list_tree = proto_item_add_subtree(ti,
ett_bgp_cluster_list);
@ -2063,7 +2055,6 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
q += 4;
}
free(cluster_list_str);
break;
case BGPTYPE_EXTENDED_COMMUNITY:
if (tlen %8 != 0) {
@ -2076,60 +2067,52 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
subtree3 = proto_item_add_subtree(ti,ett_bgp_extended_communities) ;
while (q < end) {
junk_buf_len=0;
ext_com = tvb_get_ntohs(tvb,q) ;
junk_buf_len=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf), "%s",
g_string_sprintfa(junk_gbuf, "%s",
val_to_str(ext_com,bgpext_com_type,"Unknown"));
switch (ext_com) {
case BGP_EXT_COM_RT_0:
case BGP_EXT_COM_RT_2:
case BGP_EXT_COM_RO_0:
case BGP_EXT_COM_RO_2:
junk_buf_len+=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf)-junk_buf_len, ": %u%s%d",
g_string_sprintfa(junk_gbuf, ": %u%s%d",
tvb_get_ntohs(tvb,q+2),":",tvb_get_ntohl(tvb,q+4));
junk_buf[junk_buf_len]='\0';
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_buf);
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_gbuf->str);
break ;
case BGP_EXT_COM_RT_1:
case BGP_EXT_COM_RO_1:
tvb_memcpy(tvb,ipaddr,q+2,4);
junk_buf_len+=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf)-junk_buf_len, ": %s%s%u",
g_string_sprintfa(junk_gbuf, ": %s%s%u",
ip_to_str(ipaddr),":",tvb_get_ntohs(tvb,q+6));
junk_buf[junk_buf_len]='\0';
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_buf);
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_gbuf->str);
break;
case BGP_EXT_COM_VPN_ORIGIN:
case BGP_EXT_COM_OSPF_RID:
tvb_memcpy(tvb,ipaddr,q+2,4);
junk_buf_len+=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf)-junk_buf_len, ": %s",
ip_to_str(ipaddr));
junk_buf[junk_buf_len]='\0';
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_buf);
g_string_sprintfa(junk_gbuf, ": %s", ip_to_str(ipaddr));
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_gbuf->str);
break;
case BGP_EXT_COM_OSPF_RTYPE:
tvb_memcpy(tvb,ipaddr,q+2,4);
junk_buf_len+=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf)-junk_buf_len, ": Area:%s %s",
ip_to_str(ipaddr),
g_string_sprintfa(junk_gbuf, ": Area:%s %s", ip_to_str(ipaddr),
val_to_str(tvb_get_guint8(tvb,q+6),bgpext_ospf_rtype,"Unknown"));
/* print OSPF Metric type if selected */
/* always print E2 even if not external route -- receiving router should ignore */
if ( (tvb_get_guint8(tvb,q+7)) & BGP_OSPF_RTYPE_METRIC_TYPE ) {
junk_buf_len+=snprintf(junk_buf+junk_buf_len,sizeof(junk_buf)-junk_buf_len," E2");
g_string_sprintfa(junk_gbuf," E2");
} else if (tvb_get_guint8(tvb,q+6)==(BGP_OSPF_RTYPE_EXT ||BGP_OSPF_RTYPE_NSSA ) ) {
junk_buf_len+=snprintf(junk_buf+junk_buf_len,sizeof(junk_buf)-junk_buf_len," E1");
g_string_sprintfa(junk_gbuf," E1");
}
junk_buf[junk_buf_len]='\0';
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_buf);
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_gbuf->str);
break;
case BGP_EXT_COM_LINKBAND:
tvb_memcpy(tvb,ipaddr,q+2,4); /* need to check on IEEE format on all platforms */
junk_buf_len+=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf)-junk_buf_len, ": %.3f Mbps",
g_string_sprintfa(junk_gbuf, ": %.3f Mbps",
((double)*ipaddr)*8/1000000);
junk_buf[junk_buf_len]='\0';
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_buf);
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_gbuf->str);
break;
case BGP_EXT_COM_L2INFO:
junk_buf_len+=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf)-junk_buf_len,
g_string_sprintf(junk_gbuf,
": %s, Control Flags: %s%s%s%s%s, MTU: %u %s",
val_to_str(tvb_get_guint8(tvb,q+2),bgp_l2vpn_encaps,"Unknown"),
tvb_get_guint8(tvb,q+3) ? "" : "none",
@ -2139,8 +2122,7 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
tvb_get_ntohs(tvb,q+3)&0x01 ? "S" : "",
tvb_get_ntohs(tvb,q+4),
tvb_get_ntohs(tvb,q+4)==1 ? "byte" : "bytes");
junk_buf[junk_buf_len]='\0';
ti = proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_buf);
ti = proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_gbuf->str);
subtree4 = proto_item_add_subtree(ti,ett_bgp_extended_communities) ;
proto_tree_add_text(subtree4,tvb,q+2,1, "Encapsulation: %s",
@ -2155,9 +2137,8 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
tvb_get_ntohs(tvb,q+4)==1 ? "byte" : "bytes");
break;
default:
junk_buf_len+=snprintf(junk_buf+junk_buf_len, sizeof(junk_buf)-junk_buf_len, " ");
junk_buf[junk_buf_len]='\0';
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_buf);
g_string_sprintf(junk_gbuf, " ");
proto_tree_add_text(subtree3,tvb,q,8, "%s",junk_gbuf->str);
break ;
}
q = q + 8 ;