upport BGP multiprotocol extension (required for IPv6 BGP exchange).
svn path=/trunk/; revision=858
This commit is contained in:
parent
06f434844b
commit
a4e1535f19
223
packet-bgp.c
223
packet-bgp.c
|
@ -2,7 +2,7 @@
|
||||||
* Routines for BGP packet dissection
|
* Routines for BGP packet dissection
|
||||||
* Copyright 1999, Jun-ichiro itojun Hagino <itojun@itojun.org>
|
* Copyright 1999, Jun-ichiro itojun Hagino <itojun@itojun.org>
|
||||||
*
|
*
|
||||||
* $Id: packet-bgp.c,v 1.2 1999/10/16 00:21:07 itojun Exp $
|
* $Id: packet-bgp.c,v 1.3 1999/10/16 15:35:27 itojun Exp $
|
||||||
*
|
*
|
||||||
* Ethereal - Network traffic analyzer
|
* Ethereal - Network traffic analyzer
|
||||||
* By Gerald Combs <gerald@unicom.net>
|
* By Gerald Combs <gerald@unicom.net>
|
||||||
|
@ -38,9 +38,19 @@
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEED_SNPRINTF_H
|
||||||
|
# ifdef HAVE_STDARG_H
|
||||||
|
# include <stdarg.h>
|
||||||
|
# else
|
||||||
|
# include <varargs.h>
|
||||||
|
# endif
|
||||||
|
# include "snprintf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
#include "packet-ipv6.h"
|
||||||
|
|
||||||
struct bgp {
|
struct bgp {
|
||||||
guint8 bgp_marker[16];
|
guint8 bgp_marker[16];
|
||||||
|
@ -174,12 +184,51 @@ static const value_string bgpattr_type[] = {
|
||||||
|
|
||||||
/* Subsequent address family identifier, RFC2283 section 7 */
|
/* Subsequent address family identifier, RFC2283 section 7 */
|
||||||
static const value_string bgpattr_nlri_safi[] = {
|
static const value_string bgpattr_nlri_safi[] = {
|
||||||
|
{ 0, "Reserved" },
|
||||||
{ 1, "Unicast" },
|
{ 1, "Unicast" },
|
||||||
{ 2, "Multicast" },
|
{ 2, "Multicast" },
|
||||||
{ 3, "Unicast+Multicast" },
|
{ 3, "Unicast+Multicast" },
|
||||||
{ 0, NULL },
|
{ 0, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* RFC1700 address family numbers */
|
||||||
|
#define AFNUM_INET 1
|
||||||
|
#define AFNUM_INET6 2
|
||||||
|
#define AFNUM_NSAP 3
|
||||||
|
#define AFNUM_HDLC 4
|
||||||
|
#define AFNUM_BBN1822 5
|
||||||
|
#define AFNUM_802 6
|
||||||
|
#define AFNUM_E163 7
|
||||||
|
#define AFNUM_E164 8
|
||||||
|
#define AFNUM_F69 9
|
||||||
|
#define AFNUM_X121 10
|
||||||
|
#define AFNUM_IPX 11
|
||||||
|
#define AFNUM_ATALK 12
|
||||||
|
#define AFNUM_DECNET 13
|
||||||
|
#define AFNUM_BANYAN 14
|
||||||
|
#define AFNUM_E164NSAP 15
|
||||||
|
|
||||||
|
static const value_string afnumber[] = {
|
||||||
|
{ 0, "Reserved" },
|
||||||
|
{ AFNUM_INET, "IPv4" },
|
||||||
|
{ AFNUM_INET6, "IPv6" },
|
||||||
|
{ AFNUM_NSAP, "NSAP" },
|
||||||
|
{ AFNUM_HDLC, "HDLC" },
|
||||||
|
{ AFNUM_BBN1822, "BBN 1822" },
|
||||||
|
{ AFNUM_802, "802" },
|
||||||
|
{ AFNUM_E163, "E.163" },
|
||||||
|
{ AFNUM_E164, "E.164" },
|
||||||
|
{ AFNUM_F69, "F.69" },
|
||||||
|
{ AFNUM_X121, "X.121" },
|
||||||
|
{ AFNUM_IPX, "IPX" },
|
||||||
|
{ AFNUM_ATALK, "Appletalk" },
|
||||||
|
{ AFNUM_DECNET, "Decnet IV" },
|
||||||
|
{ AFNUM_BANYAN, "Banyan Vines" },
|
||||||
|
{ AFNUM_E164NSAP, "E.164 with NSAP subaddress" },
|
||||||
|
{ 65535, "Reserved" },
|
||||||
|
{ 0, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int proto_bgp = -1;
|
static int proto_bgp = -1;
|
||||||
|
|
||||||
|
@ -187,6 +236,42 @@ static int proto_bgp = -1;
|
||||||
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
|
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
decode_prefix4(const u_char *pd, char *buf, int buflen)
|
||||||
|
{
|
||||||
|
guint8 addr[4];
|
||||||
|
int plen;
|
||||||
|
|
||||||
|
plen = pd[0];
|
||||||
|
if (plen < 0 || 32 < plen)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(addr, 0, sizeof(addr));
|
||||||
|
memcpy(addr, &pd[1], (plen + 7) / 8);
|
||||||
|
if (plen % 8)
|
||||||
|
addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
|
||||||
|
snprintf(buf, buflen, "%s/%d", ip_to_str(addr), plen);
|
||||||
|
return 1 + (plen + 7) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
decode_prefix6(const u_char *pd, char *buf, int buflen)
|
||||||
|
{
|
||||||
|
struct e_in6_addr addr;
|
||||||
|
int plen;
|
||||||
|
|
||||||
|
plen = pd[0];
|
||||||
|
if (plen < 0 || 128 < plen)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
memcpy(&addr, &pd[1], (plen + 7) / 8);
|
||||||
|
if (plen % 8)
|
||||||
|
addr.s6_addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
|
||||||
|
snprintf(buf, buflen, "%s/%d", ip6_to_str(&addr), plen);
|
||||||
|
return 1 + (plen + 7) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_bgp_open(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
|
dissect_bgp_open(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
|
||||||
{
|
{
|
||||||
|
@ -253,6 +338,8 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
int alen, aoff;
|
int alen, aoff;
|
||||||
char *msg;
|
char *msg;
|
||||||
|
guint16 af;
|
||||||
|
int off, snpa;
|
||||||
|
|
||||||
memcpy(&bgpa, &p[i], sizeof(bgpa));
|
memcpy(&bgpa, &p[i], sizeof(bgpa));
|
||||||
if (bgpa.bgpa_flags & 0x10) {
|
if (bgpa.bgpa_flags & 0x10) {
|
||||||
|
@ -393,6 +480,140 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
|
||||||
"Aggregator origin: %s",
|
"Aggregator origin: %s",
|
||||||
ip_to_str(&p[i + aoff + 2]));
|
ip_to_str(&p[i + aoff + 2]));
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case BGPTYPE_MP_REACH_NLRI:
|
||||||
|
af = ntohs(*(guint16 *)&p[i + aoff]);
|
||||||
|
proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
|
||||||
|
"Address family: %s (%u)",
|
||||||
|
val_to_str(af, afnumber, "Unknown"), af);
|
||||||
|
proto_tree_add_text(subtree2, p - pd + i + aoff + 2, 1,
|
||||||
|
"Subsequent address family identifier: %s (%u)",
|
||||||
|
val_to_str(p[i + aoff + 2], bgpattr_nlri_safi,
|
||||||
|
p[i + aoff + 2] >= 128 ? "Vendor specific" : "Unknown"),
|
||||||
|
p[i + aoff + 2]);
|
||||||
|
ti = proto_tree_add_text(subtree2, p - pd + i + aoff + 3, 1,
|
||||||
|
"Next hop network address (%d bytes)",
|
||||||
|
p[i + aoff + 3]);
|
||||||
|
if (af == AFNUM_INET || af == AFNUM_INET6) {
|
||||||
|
int j, advance;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
subtree3 = proto_item_add_subtree(ti, ETT_BGP);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
while (j < p[i + aoff + 3]) {
|
||||||
|
if (af == AFNUM_INET)
|
||||||
|
advance = 4;
|
||||||
|
else if (af == AFNUM_INET6)
|
||||||
|
advance = 16;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
if (j + advance > p[i + aoff + 3])
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (af == AFNUM_INET)
|
||||||
|
s = ip_to_str(&p[i + aoff + 4 + j]);
|
||||||
|
else {
|
||||||
|
s = ip6_to_str((struct e_in6_addr *)
|
||||||
|
&p[i + aoff + 4 + j]);
|
||||||
|
}
|
||||||
|
proto_tree_add_text(subtree3,
|
||||||
|
p - pd + i + aoff + 4 + j, advance,
|
||||||
|
"Next hop: %s", s);
|
||||||
|
j += advance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alen -= (p[i + aoff + 3] + 4);
|
||||||
|
aoff += (p[i + aoff + 3] + 4);
|
||||||
|
off = 0;
|
||||||
|
snpa = p[i + aoff];
|
||||||
|
ti = proto_tree_add_text(subtree2, p - pd + i + aoff, 1,
|
||||||
|
"Subnetwork points of attachment: %u", snpa);
|
||||||
|
off++;
|
||||||
|
if (snpa)
|
||||||
|
subtree3 = proto_item_add_subtree(ti, ETT_BGP);
|
||||||
|
for (/*nothing*/; snpa > 0; snpa--) {
|
||||||
|
proto_tree_add_text(subtree3, p - pd + i + aoff + off, 1,
|
||||||
|
"SNPA length: ", p[i + aoff + off]);
|
||||||
|
off++;
|
||||||
|
proto_tree_add_text(subtree3, p - pd + i + aoff + off,
|
||||||
|
p[i + aoff + off - 1],
|
||||||
|
"SNPA (%u bytes)", p[i + aoff + off - 1]);
|
||||||
|
off += p[i + aoff + off - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
alen -= off;
|
||||||
|
aoff += off;
|
||||||
|
ti = proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||||
|
"Network Layer Reachability Information (%u bytes)",
|
||||||
|
alen);
|
||||||
|
if (alen)
|
||||||
|
subtree3 = proto_item_add_subtree(ti, ETT_BGP);
|
||||||
|
while (alen > 0) {
|
||||||
|
int advance;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (af == AFNUM_INET) {
|
||||||
|
advance = decode_prefix4(&p[i + aoff], buf,
|
||||||
|
sizeof(buf));
|
||||||
|
} else if (af == AFNUM_INET6) {
|
||||||
|
advance = decode_prefix6(&p[i + aoff], buf,
|
||||||
|
sizeof(buf));
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
if (advance < 0)
|
||||||
|
break;
|
||||||
|
if (alen < advance)
|
||||||
|
break;
|
||||||
|
proto_tree_add_text(subtree3, p - pd + i + aoff, advance,
|
||||||
|
"Network Layer Reachability Information: %s", buf);
|
||||||
|
|
||||||
|
alen -= advance;
|
||||||
|
aoff += advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case BGPTYPE_MP_UNREACH_NLRI:
|
||||||
|
af = ntohs(*(guint16 *)&p[i + aoff]);
|
||||||
|
proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
|
||||||
|
"Address family: %s (%u)",
|
||||||
|
val_to_str(af, afnumber, "Unknown"), af);
|
||||||
|
proto_tree_add_text(subtree2, p - pd + i + aoff + 2, 1,
|
||||||
|
"Subsequent address family identifier: %s (%u)",
|
||||||
|
val_to_str(p[i + aoff + 2], bgpattr_nlri_safi,
|
||||||
|
p[i + aoff + 2] >= 128 ? "Vendor specific" : "Unknown"),
|
||||||
|
p[i + aoff + 2]);
|
||||||
|
ti = proto_tree_add_text(subtree2, p - pd + i + aoff + 3,
|
||||||
|
alen - 3, "Withdrawn Routes (%u bytes)", alen - 3);
|
||||||
|
|
||||||
|
alen -= 3;
|
||||||
|
aoff += 3;
|
||||||
|
if (alen > 0)
|
||||||
|
subtree3 = proto_item_add_subtree(ti, ETT_BGP);
|
||||||
|
while (alen > 0) {
|
||||||
|
int advance;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (af == AFNUM_INET) {
|
||||||
|
advance = decode_prefix4(&p[i + aoff], buf,
|
||||||
|
sizeof(buf));
|
||||||
|
} else if (af == AFNUM_INET6) {
|
||||||
|
advance = decode_prefix6(&p[i + aoff], buf,
|
||||||
|
sizeof(buf));
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
if (advance < 0)
|
||||||
|
break;
|
||||||
|
if (alen < advance)
|
||||||
|
break;
|
||||||
|
proto_tree_add_text(subtree3, p - pd + i + aoff, advance,
|
||||||
|
"Withdrawn route: %s", buf);
|
||||||
|
|
||||||
|
alen -= advance;
|
||||||
|
aoff += advance;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
|
||||||
|
|
Loading…
Reference in New Issue