#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.91.2.3 2005-04-20 20:46:05 guy Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.91.2.9 2006-02-02 12:36:46 hannes Exp $";
#endif
#include <tcpdump-stdinc.h>
#define AFNUM_DECNET 13
#define AFNUM_BANYAN 14
#define AFNUM_E164NSAP 15
+#define AFNUM_VPLS 25
/* draft-kompella-ppvpn-l2vpn */
#define AFNUM_L2VPN 196 /* still to be approved by IANA */
{ AFNUM_BANYAN, "Banyan Vines"},
{ AFNUM_E164NSAP, "E.164 with NSAP subaddress"},
{ AFNUM_L2VPN, "Layer-2 VPN"},
+ { AFNUM_VPLS, "VPLS"},
{ 0, NULL},
};
#define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */
+/* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */
+#define BGP_EXT_COM_EIGRP_GEN 0x8800
+#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801
+#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802
+#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803
+#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804
+#define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805
+
static struct tok bgp_extd_comm_flag_values[] = {
{ 0x8000, "vendor-specific"},
{ 0x4000, "non-transitive"},
{ BGP_EXT_COM_OSPF_RID, "ospf-router-id"},
{ BGP_EXT_COM_OSPF_RID2, "ospf-router-id"},
{ BGP_EXT_COM_L2INFO, "layer2-info"},
+ { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" },
+ { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" },
+ { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" },
+ { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" },
+ { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" },
+ { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" },
{ 0, NULL},
};
stacked labels in a a single BGP message
*/
+ if (24 > plen)
+ return -1;
+
plen-=24; /* adjust prefixlen - labellength */
if (32 < plen)
TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
+ if (0 == plen)
+ return 1; /* default route target */
+
+ if (32 > plen)
+ return -1;
+
plen-=32; /* adjust prefix length */
- if (0 < plen)
+ if (64 < plen)
return -1;
memset(&route_target, 0, sizeof(route_target));
TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
+ if ((24+64) > plen)
+ return -1;
+
plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
if (32 < plen)
TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
+
+ if (24 > plen)
+ return -1;
+
plen-=24; /* adjust prefixlen - labellength */
if (128 < plen)
TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
+ if ((24+64) > plen)
+ return -1;
+
plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
if (128 < plen)
#endif
static int
-decode_labeled_clnp_prefix(const u_char *pptr, char *buf, u_int buflen)
+decode_clnp_prefix(const u_char *pptr, char *buf, u_int buflen)
{
u_int8_t addr[19];
u_int plen;
TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
- plen-=24; /* adjust prefixlen - labellength */
if (152 < plen)
return -1;
addr[(plen + 7) / 8 - 1] &=
((0xff00 >> (plen % 8)) & 0xff);
}
- /* the label may get offsetted by 4 bits so lets shift it right */
- snprintf(buf, buflen, "%s/%d, label:%u %s",
- isonsap_string(addr,(plen + 7) / 8 - 1),
- plen,
- EXTRACT_24BITS(pptr+1)>>4,
- ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
+ snprintf(buf, buflen, "%s/%d",
+ isonsap_string(addr,(plen + 7) / 8),
+ plen);
- return 4 + (plen + 7) / 8;
+ return 1 + (plen + 7) / 8;
trunc:
return -2;
TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
+ if ((24+64) > plen)
+ return -1;
+
plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
if (152 < plen)
/* the label may get offsetted by 4 bits so lets shift it right */
snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
bgp_vpn_rd_print(pptr+4),
- isonsap_string(addr,(plen + 7) / 8 - 1),
+ isonsap_string(addr,(plen + 7) / 8),
plen,
EXTRACT_24BITS(pptr+1)>>4,
((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
{
int i;
u_int16_t af;
- u_int8_t safi, snpa;
+ u_int8_t safi, snpa, nhlen;
union { /* copy buffer for bandwidth values */
float f;
u_int32_t i;
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
break;
default:
+ TCHECK2(tptr[0], tlen);
printf("\n\t no AFI %u / SAFI %u decoder",af,safi);
if (vflag <= 1)
print_unknown_data(tptr,"\n\t ",tlen);
tptr +=3;
TCHECK(tptr[0]);
- tlen = tptr[0];
+ nhlen = tptr[0];
+ tlen = nhlen;
tptr++;
if (tlen) {
}
break;
#endif
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
}
}
}
+ printf(", nh-length: %u", nhlen);
tptr += tlen;
TCHECK(tptr[0]);
printf("\n\t %s", buf);
break;
#endif
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
- advance = decode_labeled_clnp_prefix(tptr, buf, sizeof(buf));
+ advance = decode_clnp_prefix(tptr, buf, sizeof(buf));
if (advance == -1)
printf("\n\t (illegal prefix length)");
else if (advance == -2)
printf("\n\t %s", buf);
break;
#endif
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
- advance = decode_labeled_clnp_prefix(tptr, buf, sizeof(buf));
+ advance = decode_clnp_prefix(tptr, buf, sizeof(buf));
if (advance == -1)
printf("\n\t (illegal prefix length)");
else if (advance == -2)
EXTRACT_16BITS(tptr+4));
break;
default:
+ TCHECK2(*tptr,8);
print_unknown_data(tptr,"\n\t ",8);
break;
}
print_unknown_data(pptr,"\n\t ",len);
break;
}
- if (vflag > 1 && len) /* omit zero length attributes*/
+ if (vflag > 1 && len) { /* omit zero length attributes*/
+ TCHECK2(*pptr,len);
print_unknown_data(pptr,"\n\t ",len);
+ }
return 1;
trunc:
case BGP_CAPCODE_RR_CISCO:
break;
default:
+ TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len);
printf("\n\t\tno decoder for Capability %u",
cap_type);
if (vflag <= 1)
print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len);
break;
}
- if (vflag > 1)
+ if (vflag > 1) {
+ TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len);
print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len);
+ }
break;
case BGP_OPT_AUTH:
default:
p += 2 + len;
if (dat + length > p) {
- printf("\n\t Updated routes:");
+ printf("\n\t Updated routes:");
while (dat + length > p) {
char buf[MAXHOSTNAMELEN + 100];
i = decode_prefix4(p, buf, sizeof(buf));
- if (i == -1)
+ if (i == -1) {
printf("\n\t (illegal prefix length)");
- else if (i == -2)
+ break;
+ } else if (i == -2)
goto trunc;
else {
printf("\n\t %s", buf);
char tokbuf[TOKBUFSIZE];
char tokbuf2[TOKBUFSIZE];
+ TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE);
+
+ /* some little sanity checking */
+ if (len<BGP_ROUTE_REFRESH_SIZE)
+ return;
+
bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr;
printf("\n\t AFI %s (%u), SAFI %s (%u)",
tokbuf2, sizeof(tokbuf2)),
bgp_route_refresh_header->safi);
- if (vflag > 1)
+ if (vflag > 1) {
+ TCHECK2(*pptr, len);
print_unknown_data(pptr,"\n\t ", len);
+ }
return;
+trunc:
+ printf("[|BGP]");
}
static int
bgp_route_refresh_print(dat, length);
break;
default:
- /* we have no decoder for the BGP message */
- printf("\n\t no Message %u decoder",bgp.bgp_type);
- print_unknown_data(dat,"\n\t ",length);
+ /* we have no decoder for the BGP message */
+ TCHECK2(*dat, length);
+ printf("\n\t no Message %u decoder",bgp.bgp_type);
+ print_unknown_data(dat,"\n\t ",length);
break;
}
return 1;