📄 _pim.c
字号:
bp += hdrlen;
switch (at)
{
case pimv2_unicast:
TCHECK2 (bp[0], len);
if (af == AF_INET)
{
if (!silent)
PUTS (ipaddr_string (bp));
}
#ifdef USE_INET6
else if (af == AF_INET6)
{
if (!silent)
PUTS (ip6addr_string (bp));
}
#endif
return hdrlen + len;
case pimv2_group:
case pimv2_source:
TCHECK2 (bp[0], len + 2);
if (af == AF_INET)
{
if (!silent)
{
PUTS (ipaddr_string (bp + 2));
if (bp[1] != 32)
PRINTF ("/%u", bp[1]);
}
}
#ifdef USE_INET6
else if (af == AF_INET6)
{
if (!silent)
{
PUTS (ip6addr_string (bp + 2));
if (bp[1] != 128)
PRINTF ("/%u", bp[1]);
}
}
#endif
if (bp[0] && !silent)
{
if (at == pimv2_group)
PRINTF ("(0x%02x)", bp[0]);
else
{
PRINTF ("(%s%s%s",
bp[0] & 0x04 ? "S" : "",
bp[0] & 0x02 ? "W" : "",
bp[0] & 0x01 ? "R" : "");
if (bp[0] & 0xf8)
PRINTF ("+0x%02x", bp[0] & 0xf8);
PUTCHAR (')');
}
}
return hdrlen + 2 + len;
default:
return -1;
}
trunc:
return -1;
}
static void pimv2_print (const u_char * bp, u_int len)
{
struct pim *pim = (struct pim *) bp;
const u_char *ep = (const u_char *) snapend;
int advance;
if (bp >= ep)
return;
TCHECK (pim->pim_rsv);
pimv2_addr_len = pim->pim_rsv;
if (pimv2_addr_len != 0)
PUTS ("[RFC2117-encoding] ");
switch (PIM_TYPE (pim->pim_typever))
{
case 0:
{
u_int16_t otype, olen;
PUTS (" Hello");
bp += 4;
while (bp < ep)
{
TCHECK2 (bp[0], 4);
otype = EXTRACT_16BITS (&bp[0]);
olen = EXTRACT_16BITS (&bp[2]);
TCHECK2 (bp[0], 4 + olen);
switch (otype)
{
case 1: /* Hold time */
PUTS (" (Hold-time ");
relts_print (EXTRACT_16BITS (&bp[4]));
PUTCHAR (')');
break;
/* XXX
* draft-ietf-idmr-pimv2-dr-priority-00.txt
* says that DR-Priority is option 19.
* draft-ietf-pim-v2-sm-00.txt says it's 18.
*/
case 18: /* DR-Priority */
PRINTF (" (DR-Priority: %d)", EXTRACT_32BITS (&bp[4]));
break;
case 19: /* Bidir-Capable */
if (olen == 4)
PRINTF (" (OLD-DR-Priority: %d)", EXTRACT_32BITS (&bp[4]));
else PUTS (" (bidir-capable)");
break;
case 20:
PRINTF (" (Genid: 0x%08x)", EXTRACT_32BITS (&bp[4]));
break;
case 21:
PUTS (" (State Refresh Capable");
if (EXTRACT_32BITS (&bp[4]) != 1)
PRINTF (" ?0x%x?", EXTRACT_32BITS (&bp[4]));
PUTCHAR (')');
break;
default:
if (vflag)
PRINTF (" [Hello option %d]", otype);
}
bp += 4 + olen;
}
break;
}
case 1:
{
struct ip *ip;
PUTS (" Register");
if (vflag && bp + 8 <= ep)
PRINTF (" %s%s",
bp[4] & 0x80 ? "B" : "",
bp[4] & 0x40 ? "N" : "");
bp += 8;
len -= 8;
/* encapsulated multicast packet */
if (bp >= ep)
break;
ip = (struct ip *) bp;
switch (ip->ip_v)
{
case 4: /* IPv4 */
PUTCHAR (' ');
ip_print (bp, len);
break;
#ifdef USE_INET6
case 6: /* IPv6 */
PUTCHAR (' ');
ip6_print (bp, len);
break;
#endif
default:
PRINTF (" IP ver %d", ip->ip_v);
break;
}
break;
}
case 2:
PUTS (" Register-Stop");
bp += 4;
len -= 4;
if (bp >= ep)
break;
PUTS (" group=");
if ((advance = pimv2_addr_print (bp, pimv2_group, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
len -= advance;
if (bp >= ep)
break;
PUTS (" source=");
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
len -= advance;
break;
case 3:
case 6:
case 7:
{
u_int8_t ngroup;
u_int16_t holdtime;
u_int16_t njoin;
u_int16_t nprune;
int i, j;
switch (PIM_TYPE (pim->pim_typever))
{
case 3:
PUTS (" Join/Prune");
break;
case 6:
PUTS (" Graft");
break;
case 7:
PUTS (" Graft-ACK");
break;
}
bp += 4;
len -= 4;
if (PIM_TYPE (pim->pim_typever) != 7)
{ /* not for Graft-ACK */
if (bp >= ep)
break;
PUTS (" upstream-neighbor=");
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
len -= advance;
}
if (bp + 4 > ep)
break;
ngroup = bp[1];
holdtime = EXTRACT_16BITS (&bp[2]);
PRINTF (" groups=%u", ngroup);
if (PIM_TYPE (pim->pim_typever) != 7)
{ /*not for Graft-ACK */
PUTS (" holdtime=");
if (holdtime == 0xffff)
PUTS ("infty");
else relts_print (holdtime);
}
bp += 4;
len -= 4;
for (i = 0; i < ngroup; i++)
{
if (bp >= ep)
goto jp_done;
PRINTF (" (group%d: ", i);
if ((advance = pimv2_addr_print (bp, pimv2_group, 0)) < 0)
{
PUTS ("...)");
goto jp_done;
}
bp += advance;
len -= advance;
if (bp + 4 > ep)
{
PUTS ("...)");
goto jp_done;
}
njoin = EXTRACT_16BITS (&bp[0]);
nprune = EXTRACT_16BITS (&bp[2]);
PRINTF (" join=%u", njoin);
bp += 4;
len -= 4;
for (j = 0; j < njoin; j++)
{
PUTCHAR (' ');
if ((advance = pimv2_addr_print (bp, pimv2_source, 0)) < 0)
{
PUTS ("...)");
goto jp_done;
}
bp += advance;
len -= advance;
}
PRINTF (" prune=%u", nprune);
for (j = 0; j < nprune; j++)
{
PUTCHAR (' ');
if ((advance = pimv2_addr_print (bp, pimv2_source, 0)) < 0)
{
PUTS ("...)");
goto jp_done;
}
bp += advance;
len -= advance;
}
PUTCHAR (')');
}
jp_done:
break;
}
case 4:
{
int i, j, frpcnt;
PUTS (" Bootstrap");
bp += 4;
/* Fragment Tag, Hash Mask len, and BSR-priority */
if (bp + sizeof(u_int16_t) >= ep)
break;
PRINTF (" tag=%x", EXTRACT_16BITS (bp));
bp += sizeof(u_int16_t);
if (bp >= ep)
break;
PRINTF (" hashmlen=%d", bp[0]);
if (bp + 1 >= ep)
break;
PRINTF (" BSRprio=%d", bp[1]);
bp += 2;
/* Encoded-Unicast-BSR-Address */
if (bp >= ep)
break;
PUTS (" BSR=");
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
for (i = 0; bp < ep; i++)
{
/* Encoded-Group Address */
PRINTF (" (group%d: ", i);
if ((advance = pimv2_addr_print (bp, pimv2_group, 0)) < 0)
{
PUTS ("...)");
goto bs_done;
}
bp += advance;
/* RP-Count, Frag RP-Cnt, and rsvd */
if (bp >= ep)
{
PUTS ("...)");
goto bs_done;
}
PRINTF (" RPcnt=%d", frpcnt = bp[0]);
if (bp + 1 >= ep)
{
PUTS ("...)");
goto bs_done;
}
PRINTF (" FRPcnt=%d", bp[1]);
bp += 4;
for (j = 0; j < frpcnt && bp < ep; j++)
{
/* each RP info */
PRINTF (" RP%d=", j);
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...)");
goto bs_done;
}
bp += advance;
if (bp + 1 >= ep)
{
PUTS ("...)");
goto bs_done;
}
PUTS (",holdtime=");
relts_print (EXTRACT_16BITS (bp));
if (bp + 2 >= ep)
{
PUTS ("...)");
goto bs_done;
}
PRINTF (",prio=%d", bp[2]);
bp += 4;
}
PUTCHAR (')');
}
bs_done:
break;
}
case 5:
PUTS (" Assert");
bp += 4;
len -= 4;
if (bp >= ep)
break;
PUTS (" group=");
if ((advance = pimv2_addr_print (bp, pimv2_group, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
len -= advance;
if (bp >= ep)
break;
PUTS (" src=");
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
len -= advance;
if (bp + 8 > ep)
break;
if (bp[0] & 0x80)
PUTS (" RPT");
PRINTF (" pref=%u", EXTRACT_32BITS (&bp[0]) & 0x7fffffff);
PRINTF (" metric=%u", EXTRACT_32BITS (&bp[4]));
break;
case 8:
{
int i, pfxcnt;
PUTS (" Candidate-RP-Advertisement");
bp += 4;
/* Prefix-Cnt, Priority, and Holdtime */
if (bp >= ep)
break;
PRINTF (" prefix-cnt=%d", bp[0]);
pfxcnt = bp[0];
if (bp + 1 >= ep)
break;
PRINTF (" prio=%d", bp[1]);
if (bp + 3 >= ep)
break;
PUTS (" holdtime=");
relts_print (EXTRACT_16BITS (&bp[2]));
bp += 4;
/* Encoded-Unicast-RP-Address */
if (bp >= ep)
break;
PUTS (" RP=");
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
/* Encoded-Group Addresses */
for (i = 0; i < pfxcnt && bp < ep; i++)
{
PRINTF (" Group%d=", i);
if ((advance = pimv2_addr_print (bp, pimv2_group, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
}
break;
}
case 9:
PUTS (" Prune-Refresh");
PUTS (" src=");
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
PUTS (" grp=");
if ((advance = pimv2_addr_print (bp, pimv2_group, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
PUTS (" forwarder=");
if ((advance = pimv2_addr_print (bp, pimv2_unicast, 0)) < 0)
{
PUTS ("...");
break;
}
bp += advance;
TCHECK2 (bp[0], 2);
PUTS (" TUNR ");
relts_print (EXTRACT_16BITS (bp));
break;
default:
PRINTF (" [type %d]", PIM_TYPE (pim->pim_typever));
break;
}
return;
trunc:
PUTS ("[|pim]");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -