]>
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.9 1999-10-30 05:11:19 itojun Exp $ (LBL)";
27 #include <sys/param.h>
29 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <netinet/in_systm.h>
33 #include <netinet/ip.h>
34 #include <netinet/ip_var.h>
35 #include <netinet/udp.h>
36 #include <netinet/udp_var.h>
37 #include <netinet/tcp.h>
40 * XXX: We consider a case where IPv6 is not ready yet for portability,
41 * but PIM dependent defintions should be independent of IPv6...
44 #include <netinet6/pim6.h>
47 #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
48 u_char pim_type
:4, /* the PIM message type, currently they are:
49 * Hello, Register, Register-Stop, Join/Prune,
50 * Bootstrap, Assert, Graft (PIM-DM only),
51 * Graft-Ack (PIM-DM only), C-RP-Adv
53 pim_ver
:4; /* PIM version number; 2 for PIMv2 */
55 u_char pim_ver
:4, /* PIM version */
56 pim_type
:4; /* PIM type */
58 u_char pim_rsv
; /* Reserved */
59 u_short pim_cksum
; /* IP style check sum */
68 #include "interface.h"
69 #include "addrtoname.h"
71 static void pimv2_print(register const u_char
*bp
, register u_int len
);
74 igmp_pim_print(register const u_char
*bp
, register u_int len
)
76 register const u_char
*ep
;
79 ep
= (const u_char
*)snapend
;
87 (void)printf(" Query");
91 (void)printf(" Register");
95 (void)printf(" Register-Stop");
99 (void)printf(" Join/Prune");
103 (void)printf(" RP-reachable");
107 (void)printf(" Assert");
111 (void)printf(" Graft");
115 (void)printf(" Graft-ACK");
119 (void)printf(" Mode");
123 (void)printf(" [type %d]", type
);
129 pim_print(register const u_char
*bp
, register u_int len
)
131 register const u_char
*ep
;
132 register struct pim
*pim
= (struct pim
*)bp
;
134 ep
= (const u_char
*)snapend
;
137 #ifdef notyet /* currently we see only version and type */
138 TCHECK(pim
->pim_rsv
);
141 switch(pim
->pim_ver
) {
142 case 2: /* avoid hardcoding? */
144 pimv2_print(bp
, len
);
147 (void)printf("v%d", pim
->pim_ver
);
153 enum pimv2_addrtype
{
154 pimv2_unicast
, pimv2_group
, pimv2_source
157 static char *addrtypestr
[] = {
158 "unicast", "group", "source"
163 pimv2_addr_print(const u_char
*bp
, enum pimv2_addrtype at
, int silent
)
170 ep
= (const u_char
*)snapend
;
196 if (bp
+ 2 + len
> ep
)
199 (void)printf("%s", ipaddr_string(bp
+ 2));
202 else if (af
== AF_INET6
) {
204 if (bp
+ 2 + len
> ep
)
207 (void)printf("%s", ip6addr_string(bp
+ 2));
214 if (bp
+ 4 + len
> ep
)
217 (void)printf("%s/%u", ipaddr_string(bp
+ 4), bp
[3]);
220 else if (af
== AF_INET6
) {
222 if (bp
+ 4 + len
> ep
)
225 (void)printf("%s/%u", ip6addr_string(bp
+ 4), bp
[3]);
232 if (bp
+ 4 + len
> ep
)
235 (void)printf("%s/%u", ipaddr_string(bp
+ 4), bp
[3]);
238 else if (af
== AF_INET6
) {
240 if (bp
+ 4 + len
> ep
)
243 (void)printf("%s/%u", ip6addr_string(bp
+ 4), bp
[3]);
246 if (vflag
&& bp
[2] && !silent
) {
247 (void)printf("(%s%s%s)",
248 bp
[2] & 0x04 ? "S" : "",
249 bp
[2] & 0x02 ? "W" : "",
250 bp
[2] & 0x01 ? "R" : "");
259 pimv2_print(register const u_char
*bp
, register u_int len
)
261 register const u_char
*ep
;
262 register struct pim
*pim
= (struct pim
*)bp
;
265 ep
= (const u_char
*)snapend
;
268 #ifdef notyet /* currently we see only version and type */
269 TCHECK(pim
->pim_rsv
);
272 switch (pim
->pim_type
) {
275 u_int16_t otype
, olen
;
276 (void)printf(" Hello");
279 otype
= ntohs(*(u_int16_t
*)(bp
+ 0));
280 olen
= ntohs(*(u_int16_t
*)(bp
+ 2));
281 if (otype
== 1 && olen
== 2 && bp
+ 4 + olen
<= ep
) {
283 (void)printf(" holdtime=");
284 value
= ntohs(*(u_int16_t
*)(bp
+ 4));
286 (void)printf("infty");
288 (void)printf("%u", value
);
300 (void)printf(" Register");
301 if (vflag
&& bp
+ 8 <= ep
) {
302 (void)printf(" %s%s", bp
[4] & 0x80 ? "B" : "",
303 bp
[4] & 0x40 ? "N" : "");
307 /* encapsulated multicast packet */
310 ip
= (struct ip
*)bp
;
323 (void)printf(" IP ver %d", ip
->ip_v
);
330 (void)printf(" Register-Stop");
334 (void)printf(" group=");
335 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0)) < 0) {
339 bp
+= advance
; len
-= advance
;
342 (void)printf(" source=");
343 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
347 bp
+= advance
; len
-= advance
;
360 switch (pim
->pim_type
) {
362 (void)printf(" Join/Prune");
365 (void)printf(" Graft");
368 (void)printf(" Graft-ACK");
372 if (pim
->pim_type
!= 7) { /*not for Graft-ACK*/
375 (void)printf(" upstream-neighbor=");
376 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
380 bp
+= advance
; len
-= advance
;
385 holdtime
= ntohs(*(u_int16_t
*)(bp
+ 2));
386 (void)printf(" groups=%u", ngroup
);
387 if (pim
->pim_type
!= 7) { /*not for Graft-ACK*/
388 (void)printf(" holdtime=");
389 if (holdtime
== 0xffff)
390 (void)printf("infty");
392 (void)printf("%u", holdtime
);
395 for (i
= 0; i
< ngroup
; i
++) {
398 (void)printf(" (group%d: ", i
);
399 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0)) < 0) {
400 (void)printf("...)");
403 bp
+= advance
; len
-= advance
;
405 (void)printf("...)");
408 njoin
= ntohs(*(u_int16_t
*)(bp
+ 0));
409 nprune
= ntohs(*(u_int16_t
*)(bp
+ 2));
410 (void)printf(" join=%u", njoin
);
412 for (j
= 0; j
< njoin
; j
++) {
414 if ((advance
= pimv2_addr_print(bp
, pimv2_source
, 0)) < 0) {
415 (void)printf("...)");
418 bp
+= advance
; len
-= advance
;
420 (void)printf(" prune=%u", nprune
);
421 for (j
= 0; j
< nprune
; j
++) {
423 if ((advance
= pimv2_addr_print(bp
, pimv2_source
, 0)) < 0) {
424 (void)printf("...)");
427 bp
+= advance
; len
-= advance
;
439 (void)printf(" Bootstrap");
442 /* Fragment Tag, Hash Mask len, and BSR-priority */
443 if (bp
+ sizeof(u_int16_t
) >= ep
) break;
444 (void)printf(" tag=%x", ntohs(*(u_int16_t
*)bp
));
445 bp
+= sizeof(u_int16_t
);
447 (void)printf(" hashmlen=%d", bp
[0]);
448 if (bp
+ 1 >= ep
) break;
449 (void)printf(" BSRprio=%d", bp
[1]);
452 /* Encoded-Unicast-BSR-Address */
454 (void)printf(" BSR=");
455 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
461 for (i
= 0; bp
< ep
; i
++) {
462 /* Encoded-Group Address */
463 (void)printf(" (group%d: ", i
);
464 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0))
466 (void)printf("...)");
471 /* RP-Count, Frag RP-Cnt, and rsvd */
473 (void)printf("...)");
476 (void)printf(" RPcnt=%d", frpcnt
= bp
[0]);
478 (void)printf("...)");
481 (void)printf(" FRPcnt=%d", bp
[1]);
484 for (j
= 0; j
< frpcnt
&& bp
< ep
; j
++) {
486 (void)printf(" RP%d=", j
);
487 if ((advance
= pimv2_addr_print(bp
,
490 (void)printf("...)");
496 (void)printf("...)");
499 (void)printf(",holdtime=%d",
500 ntohs(*(u_int16_t
*)bp
));
502 (void)printf("...)");
505 (void)printf(",prio=%d", bp
[3]);
514 (void)printf(" Assert");
518 (void)printf(" group=");
519 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0)) < 0) {
523 bp
+= advance
; len
-= advance
;
526 (void)printf(" src=");
527 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
531 bp
+= advance
; len
-= advance
;
534 if (ntohl(*(u_int32_t
*)bp
) & 0x80000000)
535 (void)printf(" RPT");
536 (void)printf(" pref=%u", ntohl(*(u_int32_t
*)bp
& 0x7fffffff));
537 (void)printf(" metric=%u", ntohl(*(u_int32_t
*)(bp
+ 4)));
544 (void)printf(" Candidate-RP-Advertisement");
547 /* Prefix-Cnt, Priority, and Holdtime */
549 (void)printf(" prefix-cnt=%d", bp
[0]);
551 if (bp
+ 1 >= ep
) break;
552 (void)printf(" prio=%d", bp
[1]);
553 if (bp
+ 3 >= ep
) break;
554 (void)printf(" holdtime=%d", ntohs(*(u_int16_t
*)(bp
+ 2)));
557 /* Encoded-Unicast-RP-Address */
559 (void)printf(" RP=");
560 if ((advance
= pimv2_addr_print(bp
, pimv2_unicast
, 0)) < 0) {
566 /* Encoded-Group Addresses */
567 for (i
= 0; i
< pfxcnt
&& bp
< ep
; i
++) {
568 (void)printf(" Group%d=", i
);
569 if ((advance
= pimv2_addr_print(bp
, pimv2_group
, 0))
580 (void)printf(" [type %d]", pim
->pim_type
);