]>
The Tcpdump Group git mirrors - tcpdump/blob - print-pim.c
2 * Copyright (c) 1995, 1996
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 static const char rcsid
[] =
24 "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.13 1999-11-21 09:36:59 fenner Exp $ (LBL)";
31 #include <sys/param.h>
33 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <netinet/in_systm.h>
37 #include <netinet/ip.h>
38 #include <netinet/ip_var.h>
39 #include <netinet/udp.h>
40 #include <netinet/udp_var.h>
41 #include <netinet/tcp.h>
44 * XXX: We consider a case where IPv6 is not ready yet for portability,
45 * but PIM dependent defintions should be independent of IPv6...
48 #include <netinet6/pim6.h>
51 #if defined(WORDS_BIGENDIAN) || (defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN))
52 u_int pim_type
:4, /* the PIM message type, currently they are:
53 * Hello, Register, Register-Stop, Join/Prune,
54 * Bootstrap, Assert, Graft (PIM-DM only),
55 * Graft-Ack (PIM-DM only), C-RP-Adv
57 pim_ver
:4; /* PIM version number; 2 for PIMv2 */
59 u_int pim_ver
:4, /* PIM version */
60 pim_type
:4; /* PIM type */
62 u_char pim_rsv
; /* Reserved */
63 u_short pim_cksum
; /* IP style check sum */
72 #include "interface.h"
73 #include "addrtoname.h"
75 static void pimv2_print(register const u_char
*bp
, register u_int len
);
78 igmp_pim_print(register const u_char
*bp
, register u_int len
)
80 register const u_char
*ep
;
83 ep
= (const u_char
*)snapend
;
91 (void)printf(" Query");
95 (void)printf(" Register");
99 (void)printf(" Register-Stop");
103 (void)printf(" Join/Prune");
107 (void)printf(" RP-reachable");
111 (void)printf(" Assert");
115 (void)printf(" Graft");
119 (void)printf(" Graft-ACK");
123 (void)printf(" Mode");
127 (void)printf(" [type %d]", type
);
133 pim_print(register const u_char
*bp
, register u_int len
)
135 register const u_char
*ep
;
136 register struct pim
*pim
= (struct pim
*)bp
;
138 ep
= (const u_char
*)snapend
;
141 #ifdef notyet /* currently we see only version and type */
142 TCHECK(pim
->pim_rsv
);
145 switch(pim
->pim_ver
) {
146 case 2: /* avoid hardcoding? */
148 pimv2_print(bp
, len
);
151 (void)printf("v%d", pim
->pim_ver
);
157 enum pimv2_addrtype
{
158 pimv2_unicast
, pimv2_group
, pimv2_source
161 static char *addrtypestr
[] = {
162 "unicast", "group", "source"
167 pimv2_addr_print(const u_char
*bp
, enum pimv2_addrtype at
, int silent
)
174 ep
= (const u_char
*)snapend
;
200 if (bp
+ 2 + len
> ep
)
203 (void)printf("%s", ipaddr_string(bp
+ 2));
206 else if (af
== AF_INET6
) {
208 if (bp
+ 2 + len
> ep
)
211 (void)printf("%s", ip6addr_string(bp
+ 2));
218 if (bp
+ 4 + len
> ep
)
221 (void)printf("%s/%u", ipaddr_string(bp
+ 4), bp
[3]);
224 else if (af
== AF_INET6
) {
226 if (bp
+ 4 + len
> ep
)
229 (void)printf("%s/%u", ip6addr_string(bp
+ 4), bp
[3]);
236 if (bp
+ 4 + len
> ep
)
239 (void)printf("%s/%u", ipaddr_string(bp
+ 4), bp
[3]);
242 else if (af
== AF_INET6
) {
244 if (bp
+ 4 + len
> ep
)
247 (void)printf("%s/%u", ip6addr_string(bp
+ 4), bp
[3]);
250 if (vflag
&& bp
[2] && !silent
) {
251 (void)printf("(%s%s%s)",
252 bp
[2] & 0x04 ? "S" : "",
253 bp
[2] & 0x02 ? "W" : "",
254 bp
[2] & 0x01 ? "R" : "");
263 pimv2_print(register const u_char
*bp
, register u_int len
)
265 register const u_char
*ep
;
266 register struct pim
*pim
= (struct pim
*)bp
;
269 ep
= (const u_char
*)snapend
;
272 #ifdef notyet /* currently we see only version and type */
273 TCHECK(pim
->pim_rsv
);
276 switch (pim
->pim_type
) {
279 u_int16_t otype
, olen
;
280 (void)printf(" Hello");
283 otype
= ntohs(*(u_int16_t
*)(bp
+ 0));
284 olen
= ntohs(*(u_int16_t
*)(bp
+ 2));
285 if (otype
== 1 && olen
== 2 && bp
+ 4 + olen
<= ep
) {
287 (void)printf(" holdtime=");
288 value
= ntohs(*(u_int16_t
*)(bp
+ 4));
290 (void)printf("infty");
292 (void)printf("%u", value
);
304 (void)printf(" Register");
305 if (vflag
&& bp
+ 8 <= ep
) {
306 (void)printf(" %s%s", bp
[4] & 0x80 ? "B" : "",
307 bp
[4] & 0x40 ? "N" : "");
311 /* encapsulated multicast packet */
314 ip
= (struct ip
*)bp
;
327 (void)printf(" IP ver %d", ip
->ip_v
);
334 (void)printf(" Register-Stop");
338 (void)printf(" group=");
339 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0)) < 0) {
343 bp
+= advance
; len
-= advance
;
346 (void)printf(" source=");
347 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
351 bp
+= advance
; len
-= advance
;
364 switch (pim
->pim_type
) {
366 (void)printf(" Join/Prune");
369 (void)printf(" Graft");
372 (void)printf(" Graft-ACK");
376 if (pim
->pim_type
!= 7) { /*not for Graft-ACK*/
379 (void)printf(" upstream-neighbor=");
380 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
384 bp
+= advance
; len
-= advance
;
389 holdtime
= ntohs(*(u_int16_t
*)(bp
+ 2));
390 (void)printf(" groups=%u", ngroup
);
391 if (pim
->pim_type
!= 7) { /*not for Graft-ACK*/
392 (void)printf(" holdtime=");
393 if (holdtime
== 0xffff)
394 (void)printf("infty");
396 (void)printf("%u", holdtime
);
399 for (i
= 0; i
< ngroup
; i
++) {
402 (void)printf(" (group%d: ", i
);
403 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0)) < 0) {
404 (void)printf("...)");
407 bp
+= advance
; len
-= advance
;
409 (void)printf("...)");
412 njoin
= ntohs(*(u_int16_t
*)(bp
+ 0));
413 nprune
= ntohs(*(u_int16_t
*)(bp
+ 2));
414 (void)printf(" join=%u", njoin
);
416 for (j
= 0; j
< njoin
; j
++) {
418 if ((advance
= pimv2_addr_print(bp
, pimv2_source
, 0)) < 0) {
419 (void)printf("...)");
422 bp
+= advance
; len
-= advance
;
424 (void)printf(" prune=%u", nprune
);
425 for (j
= 0; j
< nprune
; j
++) {
427 if ((advance
= pimv2_addr_print(bp
, pimv2_source
, 0)) < 0) {
428 (void)printf("...)");
431 bp
+= advance
; len
-= advance
;
443 (void)printf(" Bootstrap");
446 /* Fragment Tag, Hash Mask len, and BSR-priority */
447 if (bp
+ sizeof(u_int16_t
) >= ep
) break;
448 (void)printf(" tag=%x", ntohs(*(u_int16_t
*)bp
));
449 bp
+= sizeof(u_int16_t
);
451 (void)printf(" hashmlen=%d", bp
[0]);
452 if (bp
+ 1 >= ep
) break;
453 (void)printf(" BSRprio=%d", bp
[1]);
456 /* Encoded-Unicast-BSR-Address */
458 (void)printf(" BSR=");
459 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
465 for (i
= 0; bp
< ep
; i
++) {
466 /* Encoded-Group Address */
467 (void)printf(" (group%d: ", i
);
468 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0))
470 (void)printf("...)");
475 /* RP-Count, Frag RP-Cnt, and rsvd */
477 (void)printf("...)");
480 (void)printf(" RPcnt=%d", frpcnt
= bp
[0]);
482 (void)printf("...)");
485 (void)printf(" FRPcnt=%d", bp
[1]);
488 for (j
= 0; j
< frpcnt
&& bp
< ep
; j
++) {
490 (void)printf(" RP%d=", j
);
491 if ((advance
= pimv2_addr_print(bp
,
494 (void)printf("...)");
500 (void)printf("...)");
503 (void)printf(",holdtime=%d",
504 ntohs(*(u_int16_t
*)bp
));
506 (void)printf("...)");
509 (void)printf(",prio=%d", bp
[2]);
518 (void)printf(" Assert");
522 (void)printf(" group=");
523 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0)) < 0) {
527 bp
+= advance
; len
-= advance
;
530 (void)printf(" src=");
531 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
535 bp
+= advance
; len
-= advance
;
538 if (ntohl(*(u_int32_t
*)bp
) & 0x80000000)
539 (void)printf(" RPT");
540 (void)printf(" pref=%u", ntohl(*(u_int32_t
*)bp
& 0x7fffffff));
541 (void)printf(" metric=%u", ntohl(*(u_int32_t
*)(bp
+ 4)));
548 (void)printf(" Candidate-RP-Advertisement");
551 /* Prefix-Cnt, Priority, and Holdtime */
553 (void)printf(" prefix-cnt=%d", bp
[0]);
555 if (bp
+ 1 >= ep
) break;
556 (void)printf(" prio=%d", bp
[1]);
557 if (bp
+ 3 >= ep
) break;
558 (void)printf(" holdtime=%d", ntohs(*(u_int16_t
*)(bp
+ 2)));
561 /* Encoded-Unicast-RP-Address */
563 (void)printf(" RP=");
564 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
570 /* Encoded-Group Addresses */
571 for (i
= 0; i
< pfxcnt
&& bp
< ep
; i
++) {
572 (void)printf(" Group%d=", i
);
573 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0))
584 (void)printf(" [type %d]", pim
->pim_type
);