update RFC1966 (BGP route reflection) support.
From: Greg Hankins <gregh@twoguys.org> svn path=/trunk/; revision=1759
This commit is contained in:
parent
c317b042a8
commit
01d2363d0e
86
packet-bgp.c
86
packet-bgp.c
|
@ -6,11 +6,11 @@
|
|||
*
|
||||
* Supports:
|
||||
* RFC1771 A Border Gateway Protocol 4 (BGP-4)
|
||||
* RFC1966 BGP Route Reflection An alternative to full mesh IBGP
|
||||
* RFC1997 BGP Communities Attribute
|
||||
* RFC2283 Multiprotocol Extensions for BGP-4
|
||||
*
|
||||
* TODO:
|
||||
* RFC1966 BGP Route Reflection An alternative to full mesh IBGP
|
||||
* RFC1863 A BGP/IDRP Route Server alternative to a full mesh routing
|
||||
* RFC1965 Autonomous System Confederations for BGP
|
||||
* Destination Preference Attribute for BGP (work in progress)
|
||||
|
@ -198,6 +198,7 @@ static gint ett_bgp_update = -1;
|
|||
static gint ett_bgp_notification = -1;
|
||||
static gint ett_bgp_as_paths = -1;
|
||||
static gint ett_bgp_communities = -1;
|
||||
static gint ett_bgp_cluster_list = -1;
|
||||
|
||||
/*
|
||||
* Decode an IPv4 prefix.
|
||||
|
@ -298,7 +299,7 @@ dissect_bgp_open(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
|
|||
static void
|
||||
dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
||||
proto_tree *tree)
|
||||
{
|
||||
{
|
||||
struct bgp bgp; /* BGP header */
|
||||
struct bgp_attr bgpa; /* path attributes */
|
||||
int hlen; /* message length */
|
||||
|
@ -314,11 +315,13 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
|||
proto_tree *as_path_tree; /* subtree for AS_PATH */
|
||||
proto_tree *communities_tree; /* subtree for COMMUNITIES */
|
||||
proto_tree *community_tree; /* subtree for a community */
|
||||
proto_tree *cluster_list_tree; /* subtree for CLUSTER_LIST */
|
||||
int i, j; /* tmp */
|
||||
guint8 length; /* AS_PATH length */
|
||||
guint8 type; /* AS_PATH type */
|
||||
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 */
|
||||
|
||||
|
||||
|
@ -543,13 +546,44 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
|||
? "byte" : "bytes");
|
||||
break;
|
||||
case BGPTYPE_CLUSTER_LIST:
|
||||
if (alen % 4 != 0)
|
||||
goto default_attribute_top;
|
||||
|
||||
/* (p + i + 3) =
|
||||
(p + current attribute + 3 bytes to first tuple) */
|
||||
end = p + alen + i + 3;
|
||||
q = p + i + 3;
|
||||
/* must be freed by second switch! */
|
||||
/* "alen * 16" (12 digits, 3 dots + space ) should be
|
||||
a good estimate of how long the cluster_list string could
|
||||
be */
|
||||
cluster_list_str = malloc((alen + 1) * 16);
|
||||
if (cluster_list_str == NULL) break;
|
||||
cluster_list_str[0] = '\0';
|
||||
memset(junk_buf, 0, sizeof(junk_buf));
|
||||
|
||||
/* snarf each cluster list */
|
||||
while (q < end) {
|
||||
snprintf(junk_buf, sizeof(junk_buf), "%s ", ip_to_str(q));
|
||||
strncat(cluster_list_str, junk_buf, sizeof(junk_buf));
|
||||
q += 4;
|
||||
}
|
||||
/* cleanup end of string */
|
||||
cluster_list_str[strlen(cluster_list_str) - 1] = '\0';
|
||||
|
||||
ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
|
||||
"%s: %s (%u %s)",
|
||||
val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
|
||||
cluster_list_str, alen + aoff,
|
||||
(alen + aoff == 1) ? "byte" : "bytes");
|
||||
break;
|
||||
default:
|
||||
default_attribute_top:
|
||||
ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
|
||||
"%s (%u %s)",
|
||||
val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
|
||||
alen + aoff, (alen + aoff == 1) ? "byte" : "bytes");
|
||||
}
|
||||
} /* end of first switch */
|
||||
subtree2 = proto_item_add_subtree(ti, ett_bgp_attr);
|
||||
|
||||
/* figure out flags */
|
||||
|
@ -705,11 +739,11 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
|||
case BGPTYPE_MULTI_EXIT_DISC:
|
||||
if (alen != 4) {
|
||||
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
"Multi exit discriminator (invalid): %u %s",
|
||||
"Multiple exit discriminator (invalid): %u %s",
|
||||
alen, (alen == 1) ? "byte" : "bytes");
|
||||
} else {
|
||||
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
"Multi exit discriminator: %u",
|
||||
"Multiple exit discriminator: %u",
|
||||
pntohl(&p[i + aoff]));
|
||||
}
|
||||
break;
|
||||
|
@ -720,8 +754,7 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
|||
(alen == 1) ? "byte" : "bytes");
|
||||
} else {
|
||||
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
"Local preference: %u",
|
||||
pntohl(&p[i + aoff]));
|
||||
"Local preference: %u", pntohl(&p[i + aoff]));
|
||||
}
|
||||
break;
|
||||
case BGPTYPE_ATOMIC_AGGREGATE:
|
||||
|
@ -738,8 +771,7 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
|||
(alen == 1) ? "byte" : "bytes");
|
||||
} else {
|
||||
proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
|
||||
"Aggregator AS: %u",
|
||||
pntohs(&p[i + aoff]));
|
||||
"Aggregator AS: %u", pntohs(&p[i + aoff]));
|
||||
proto_tree_add_text(subtree2, p - pd + i + aoff + 2, 4,
|
||||
"Aggregator origin: %s",
|
||||
ip_to_str(&p[i + aoff + 2]));
|
||||
|
@ -750,6 +782,8 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
|||
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
"Communities (invalid): %u %s", alen,
|
||||
(alen == 1) ? "byte" : "bytes");
|
||||
free(communities_str);
|
||||
break;
|
||||
}
|
||||
|
||||
ti = proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
|
@ -952,12 +986,41 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
|||
|
||||
break;
|
||||
case BGPTYPE_CLUSTER_LIST:
|
||||
if (alen % 4 != 0) {
|
||||
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
"Cluster list (invalid): %u %s", alen,
|
||||
(alen == 1) ? "byte" : "bytes");
|
||||
free(cluster_list_str);
|
||||
break;
|
||||
}
|
||||
|
||||
ti = proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
"Cluster list: %s", cluster_list_str);
|
||||
cluster_list_tree = proto_item_add_subtree(ti,
|
||||
ett_bgp_cluster_list);
|
||||
|
||||
/* (p + i + 3) =
|
||||
(p + current attribute + 3 bytes to first tuple) */
|
||||
end = p + alen + i + 3;
|
||||
q = p + i + 3;
|
||||
|
||||
/* snarf each cluster identifier */
|
||||
while (q < end) {
|
||||
ti = proto_tree_add_text(cluster_list_tree,
|
||||
q - pd - 3 + aoff, 4, "Cluster identifier: %s",
|
||||
ip_to_str(q));
|
||||
|
||||
q += 4;
|
||||
}
|
||||
|
||||
free(cluster_list_str);
|
||||
break;
|
||||
default:
|
||||
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||
"Unknown (%d %s)", alen, (alen == 1) ? "byte" :
|
||||
"bytes");
|
||||
break;
|
||||
}
|
||||
} /* end of second switch */
|
||||
|
||||
i += alen + aoff;
|
||||
}
|
||||
|
@ -1134,7 +1197,7 @@ dissect_bgp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
|
|||
}
|
||||
|
||||
proto_tree_add_text(bgp1_tree, offset + i, BGP_MARKER_SIZE,
|
||||
"Marker");
|
||||
"Marker: 16 bytes");
|
||||
|
||||
if (hlen < BGP_HEADER_SIZE || hlen > BGP_MAX_PACKET_SIZE) {
|
||||
proto_tree_add_text(bgp1_tree,
|
||||
|
@ -1197,6 +1260,7 @@ proto_register_bgp(void)
|
|||
&ett_bgp_notification,
|
||||
&ett_bgp_as_paths,
|
||||
&ett_bgp_communities,
|
||||
&ett_bgp_cluster_list,
|
||||
};
|
||||
|
||||
proto_bgp = proto_register_protocol("Border Gateway Protocol", "bgp");
|
||||
|
|
Loading…
Reference in New Issue