📄 _bgp.c
字号:
p += 2 + p[1] * 2;
}
break;
case BGPTYPE_NEXT_HOP:
if (len != 4)
PUTS (" invalid len");
else PRINTF (" %s", ipaddr_string(p));
break;
case BGPTYPE_MULTI_EXIT_DISC:
case BGPTYPE_LOCAL_PREF:
if (len != 4)
PUTS (" invalid len");
else PRINTF (" %lu", ntohl (*(u_int32_t*)p));
break;
case BGPTYPE_ATOMIC_AGGREGATE:
if (len != 0)
PUTS (" invalid len");
break;
case BGPTYPE_AGGREGATOR:
if (len != 6)
{
PUTS (" invalid len");
break;
}
PRINTF (" AS #%u, origin %s",
ntohs(*(u_int16_t*)p), ipaddr_string(p+2));
break;
case BGPTYPE_COMMUNITIES:
if (len % 4)
{
PUTS (" invalid len");
break;
}
for (i = 0; i < len; i += 4)
{
u_int32_t comm;
comm = (u_int32_t) ntohl (*(u_int32_t *) & p[i]);
switch (comm)
{
case BGP_COMMUNITY_NO_EXPORT:
PUTS (" NO_EXPORT");
break;
case BGP_COMMUNITY_NO_ADVERT:
PUTS (" NO_ADVERTISE");
break;
case BGP_COMMUNITY_NO_EXPORT_SUBCONFED:
PUTS (" NO_EXPORT_SUBCONFED");
break;
default:
PRINTF (" (AS #%d value 0x%04x)",
(comm >> 16) & 0xffff, comm & 0xffff);
break;
}
}
break;
case BGPTYPE_MP_REACH_NLRI:
af = ntohs (*(u_int16_t *) p);
safi = p[2];
if (safi >= 128)
PRINTF (" %s vendor specific,", af_name (af));
else PRINTF (" %s %s,", af_name (af), bgp_attr_nlri_safi (safi));
p += 3;
if (af == AFNUM_INET)
;
#ifdef USE_INET6
else if (af == AFNUM_INET6)
;
#endif
else
break;
tlen = p[0];
if (tlen)
{
PUTS (" nexthop");
if (af == AFNUM_INET)
advance = 4;
#ifdef USE_INET6
else if (af == AFNUM_INET6)
advance = 16;
#endif
for (i = 0; i < tlen; i += advance)
{
if (af == AFNUM_INET)
PRINTF (" %s", ipaddr_string (p + 1 + i));
#ifdef USE_INET6
else if (af == AFNUM_INET6)
PRINTF (" %s", ip6addr_string (p + 1 + i));
#endif
}
PUTCHAR (',');
}
p += 1 + tlen;
snpa = p[0];
p++;
if (snpa)
{
PRINTF (" %u snpa", snpa);
for ( /*nothing */ ; snpa > 0; snpa--)
{
PRINTF ("(%d bytes)", p[0]);
p += p[0] + 1;
}
PUTCHAR (',');
}
PUTS (" NLRI");
while (len - (p - dat) > 0)
{
if (af == AFNUM_INET)
advance = decode_prefix4 (p, buf, sizeof(buf));
#ifdef USE_INET6
else if (af == AFNUM_INET6)
advance = decode_prefix6 (p, buf, sizeof(buf));
#endif
PRINTF (" %s", buf);
p += advance;
}
break;
case BGPTYPE_MP_UNREACH_NLRI:
af = ntohs (*(u_int16_t *) p);
safi = p[2];
if (safi >= 128)
PRINTF (" %s vendor specific,", af_name (af));
else PRINTF (" %s %s,", af_name (af), bgp_attr_nlri_safi (safi));
p += 3;
PUTS (" Withdraw");
while (len - (p - dat) > 0)
{
if (af == AFNUM_INET)
advance = decode_prefix4 (p, buf, sizeof(buf));
#ifdef USE_INET6
else if (af == AFNUM_INET6)
advance = decode_prefix6 (p, buf, sizeof(buf));
#endif
PRINTF (" %s", buf);
p += advance;
}
break;
default:
break;
}
}
static void bgp_open_print (const u_char * dat, int length)
{
struct bgp_open bgpo;
struct bgp_opt bgpopt;
const u_char *opt;
int i, hlen;
memcpy (&bgpo, dat, sizeof(bgpo));
hlen = ntohs (bgpo.bgpo_len);
PRINTF (": Version %d, AS #%u, Holdtime %u, ID %s, Option length %u",
bgpo.bgpo_version, ntohs (bgpo.bgpo_myas),
ntohs (bgpo.bgpo_holdtime), ipaddr_string(&bgpo.bgpo_id),
bgpo.bgpo_optlen);
opt = &((struct bgp_open*)dat)->bgpo_optlen;
opt++;
for (i = 0; i < bgpo.bgpo_optlen; )
{
memcpy (&bgpopt, &opt[i], sizeof(bgpopt));
if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen)
{
PRINTF (" [|opt %d %d]", bgpopt.bgpopt_len, bgpopt.bgpopt_type);
break;
}
PRINTF (" (option %s, len=%d)", bgp_opttype (bgpopt.bgpopt_type),
bgpopt.bgpopt_len);
i += sizeof(bgpopt) + bgpopt.bgpopt_len;
}
}
static void bgp_update_print (const u_char * dat, int length)
{
struct bgp bgp;
struct bgp_attr bgpa;
const u_char *p;
int i, hlen, len, newline;
memcpy (&bgp, dat, sizeof(bgp));
hlen = ntohs (bgp.bgp_len);
p = dat + BGP_SIZE;
PUTCHAR (':');
/* Unfeasible routes */
len = ntohs (*(u_int16_t *) p);
if (len)
PRINTF (" (Withdrawn routes: %d bytes)", len);
p += 2 + len;
len = ntohs (*(u_int16_t *) p);
if (len)
{
/* do something more useful! */
i = 2;
PUTS (" (Path attributes:");
newline = 0;
while (i < 2 + len)
{
int alen, aoff;
memcpy (&bgpa, &p[i], sizeof(bgpa));
alen = bgp_attr_len (&bgpa);
aoff = bgp_attr_off (&bgpa);
if (vflag && newline)
PUTS ("\n\t\t(");
else PUTS (" (");
PUTS (bgp_attr_type (bgpa.bgpa_type));
if (bgpa.bgpa_flags)
{
PRINTF ("[%s%s%s%s]",
bgpa.bgpa_flags & 0x80 ? "O" : "",
bgpa.bgpa_flags & 0x40 ? "T" : "",
bgpa.bgpa_flags & 0x20 ? "P" : "",
bgpa.bgpa_flags & 0x00 ? "E" : "");
}
bgp_attr_print (&bgpa, &p[i+aoff], alen);
newline = 1;
PUTCHAR (')');
i += aoff + alen;
}
PUTCHAR (')');
}
p += 2 + len;
if (len && dat + length > p)
PUTS ("\n\t\t");
if (dat + length > p)
{
PUTS ("(NLRI:");
while (dat + length > p)
{
char buf[256];
i = decode_prefix4 (p, buf, sizeof(buf));
PRINTF (" %s", buf);
if (i < 0)
break;
p += i;
}
PUTCHAR (')');
}
}
static void bgp_notification_print (const u_char *dat, int length)
{
struct bgp_notification bgpn;
int hlen;
memcpy (&bgpn, dat, sizeof(bgpn));
hlen = ntohs (bgpn.bgpn_len);
PRINTF (": error %s,", bgp_notify_major (bgpn.bgpn_major));
PRINTF (" subcode %s", bgp_notify_minor (bgpn.bgpn_major, bgpn.bgpn_minor));
}
static void bgp_header_print (const u_char *dat, int length)
{
struct bgp bgp;
memcpy (&bgp, dat, sizeof(bgp));
PRINTF ("(%s", bgp_type (bgp.bgp_type));
switch (bgp.bgp_type)
{
case BGP_OPEN:
bgp_open_print (dat, length);
break;
case BGP_UPDATE:
bgp_update_print (dat, length);
break;
case BGP_NOTIFICATION:
bgp_notification_print (dat, length);
break;
}
PUTCHAR (')');
}
void bgp_print (const u_char * dat, int length)
{
struct bgp bgp;
u_int16_t hlen;
int newline;
const u_char *p;
const u_char *ep;
const u_char *start;
const u_char marker[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
ep = dat + length;
if (snapend < dat + length)
ep = snapend;
PUTS (": BGP");
p = dat;
newline = 0;
start = p;
while (p < snapend)
{
if (!TTEST2 (p[0], 1))
break;
if (p[0] != 0xff)
{
p++;
continue;
}
if (!TTEST2 (p[0], sizeof(marker)))
break;
if (memcmp (p, marker, sizeof(marker)) != 0)
{
p++;
continue;
}
/* found BGP header */
TCHECK2 (p[0], BGP_SIZE);
memcpy (&bgp, p, sizeof(bgp));
if (start != p)
PUTS (" [|BGP]");
hlen = ntohs (bgp.bgp_len);
if (vflag && newline)
PUTS ("\n\t");
else PUTCHAR (' ');
if (TTEST2 (p[0], hlen))
{
bgp_header_print (p, hlen);
newline = 1;
p += hlen;
start = p;
}
else
{
PRINTF ("[|BGP %s]", bgp_type (bgp.bgp_type));
break;
}
}
return;
trunc:
PUTS (" [|BGP]");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -