14edb46e9SPaul Traina /* 24edb46e9SPaul Traina * Copyright (c) 1995, 1996 34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved. 44edb46e9SPaul Traina * 54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without 64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions 74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and 94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials 104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 114edb46e9SPaul Traina * features or use of this software display the following acknowledgement: 124edb46e9SPaul Traina * ``This product includes software developed by the University of California, 134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse 154edb46e9SPaul Traina * or promote products derived from this software without specific prior 164edb46e9SPaul Traina * written permission. 174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 209537d84eSBill Fenner * 219537d84eSBill Fenner * $FreeBSD$ 224edb46e9SPaul Traina */ 234edb46e9SPaul Traina 244edb46e9SPaul Traina #ifndef lint 254de76e31SBill Fenner static const char rcsid[] = 26a1c2090eSBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.29 2001/07/04 21:36:15 fenner Exp $ (LBL)"; 27b0453382SBill Fenner #endif 28b0453382SBill Fenner 29b0453382SBill Fenner #ifdef HAVE_CONFIG_H 30b0453382SBill Fenner #include "config.h" 314edb46e9SPaul Traina #endif 324edb46e9SPaul Traina 334edb46e9SPaul Traina #include <sys/param.h> 344edb46e9SPaul Traina #include <sys/time.h> 354edb46e9SPaul Traina #include <sys/socket.h> 364edb46e9SPaul Traina 374edb46e9SPaul Traina #include <netinet/in.h> 38b0453382SBill Fenner 39b0453382SBill Fenner /* 40b0453382SBill Fenner * XXX: We consider a case where IPv6 is not ready yet for portability, 41b0453382SBill Fenner * but PIM dependent defintions should be independent of IPv6... 42b0453382SBill Fenner */ 43b0453382SBill Fenner 44b0453382SBill Fenner struct pim { 45b0453382SBill Fenner u_int8_t pim_typever; 469537d84eSBill Fenner /* upper 4bit: PIM version number; 2 for PIMv2 */ 479537d84eSBill Fenner /* lower 4bit: the PIM message type, currently they are: 48b0453382SBill Fenner * Hello, Register, Register-Stop, Join/Prune, 49b0453382SBill Fenner * Bootstrap, Assert, Graft (PIM-DM only), 50b0453382SBill Fenner * Graft-Ack (PIM-DM only), C-RP-Adv 51b0453382SBill Fenner */ 529537d84eSBill Fenner #define PIM_VER(x) (((x) & 0xf0) >> 4) 539537d84eSBill Fenner #define PIM_TYPE(x) ((x) & 0x0f) 54b0453382SBill Fenner u_char pim_rsv; /* Reserved */ 55b0453382SBill Fenner u_short pim_cksum; /* IP style check sum */ 56b0453382SBill Fenner }; 57b0453382SBill Fenner 584edb46e9SPaul Traina 594edb46e9SPaul Traina #include <stdio.h> 604edb46e9SPaul Traina #include <stdlib.h> 614edb46e9SPaul Traina #include <unistd.h> 624edb46e9SPaul Traina 634edb46e9SPaul Traina #include "interface.h" 644edb46e9SPaul Traina #include "addrtoname.h" 65b0453382SBill Fenner #include "extract.h" 66b0453382SBill Fenner 67943ee2b1SBill Fenner #include "ip.h" 68943ee2b1SBill Fenner 69b0453382SBill Fenner static void pimv2_print(register const u_char *bp, register u_int len); 70b0453382SBill Fenner 71b0453382SBill Fenner static void 72b0453382SBill Fenner pimv1_join_prune_print(register const u_char *bp, register u_int len) 73b0453382SBill Fenner { 74b0453382SBill Fenner int maddrlen, addrlen, ngroups, njoin, nprune; 75b0453382SBill Fenner int njp; 76b0453382SBill Fenner 77b0453382SBill Fenner /* If it's a single group and a single source, use 1-line output. */ 78b0453382SBill Fenner if (TTEST2(bp[0], 30) && bp[11] == 1 && 79b0453382SBill Fenner ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { 80b0453382SBill Fenner int hold; 81b0453382SBill Fenner 82b0453382SBill Fenner (void)printf(" RPF %s ", ipaddr_string(bp)); 83b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[6]); 84b0453382SBill Fenner if (hold != 180) { 85b0453382SBill Fenner (void)printf("Hold "); 86b0453382SBill Fenner relts_print(hold); 87b0453382SBill Fenner } 88b0453382SBill Fenner (void)printf("%s (%s/%d, %s", njoin ? "Join" : "Prune", 89b0453382SBill Fenner ipaddr_string(&bp[26]), bp[25] & 0x3f, 90b0453382SBill Fenner ipaddr_string(&bp[12])); 91b0453382SBill Fenner if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) 92b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[16])); 93b0453382SBill Fenner (void)printf(") %s%s %s", 94b0453382SBill Fenner (bp[24] & 0x01) ? "Sparse" : "Dense", 95b0453382SBill Fenner (bp[25] & 0x80) ? " WC" : "", 96b0453382SBill Fenner (bp[25] & 0x40) ? "RP" : "SPT"); 97b0453382SBill Fenner return; 98b0453382SBill Fenner } 99b0453382SBill Fenner 100b0453382SBill Fenner TCHECK2(bp[0], 4); 101a1c2090eSBill Fenner if (vflag > 1) 102a1c2090eSBill Fenner (void)printf("\n"); 103a1c2090eSBill Fenner (void)printf(" Upstream Nbr: %s", ipaddr_string(bp)); 104b0453382SBill Fenner TCHECK2(bp[6], 2); 105a1c2090eSBill Fenner if (vflag > 1) 106a1c2090eSBill Fenner (void)printf("\n"); 107a1c2090eSBill Fenner (void)printf(" Hold time: "); 108b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[6])); 109a1c2090eSBill Fenner if (vflag < 2) 110a1c2090eSBill Fenner return; 111a1c2090eSBill Fenner bp += 8; 112a1c2090eSBill Fenner len -= 8; 113b0453382SBill Fenner 114b0453382SBill Fenner TCHECK2(bp[0], 4); 115b0453382SBill Fenner maddrlen = bp[1]; 116b0453382SBill Fenner addrlen = bp[2]; 117b0453382SBill Fenner ngroups = bp[3]; 118a1c2090eSBill Fenner bp += 4; 119a1c2090eSBill Fenner len -= 4; 120b0453382SBill Fenner while (ngroups--) { 121b0453382SBill Fenner TCHECK2(bp[0], 4); 122b0453382SBill Fenner (void)printf("\n\tGroup: %s", ipaddr_string(bp)); 123b0453382SBill Fenner if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) 124b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[4])); 125b0453382SBill Fenner TCHECK2(bp[8], 4); 126b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[8]); 127b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[10]); 128b0453382SBill Fenner (void)printf(" joined: %d pruned: %d", njoin, nprune); 129a1c2090eSBill Fenner bp += 12; 130a1c2090eSBill Fenner len -= 12; 131b0453382SBill Fenner for (njp = 0; njp < (njoin + nprune); njp++) { 132b0453382SBill Fenner char *type; 133b0453382SBill Fenner 134a1c2090eSBill Fenner if (njp < njoin) 135b0453382SBill Fenner type = "Join "; 136a1c2090eSBill Fenner else 137b0453382SBill Fenner type = "Prune"; 138b0453382SBill Fenner TCHECK2(bp[0], 6); 139b0453382SBill Fenner (void)printf("\n\t%s %s%s%s%s/%d", type, 140b0453382SBill Fenner (bp[0] & 0x01) ? "Sparse " : "Dense ", 141b0453382SBill Fenner (bp[1] & 0x80) ? "WC " : "", 142b0453382SBill Fenner (bp[1] & 0x40) ? "RP " : "SPT ", 143b0453382SBill Fenner ipaddr_string(&bp[2]), bp[1] & 0x3f); 144a1c2090eSBill Fenner bp += 6; 145a1c2090eSBill Fenner len -= 6; 146b0453382SBill Fenner } 147b0453382SBill Fenner } 148b0453382SBill Fenner return; 149b0453382SBill Fenner trunc: 150b0453382SBill Fenner (void)printf("[|pim]"); 151b0453382SBill Fenner return; 152b0453382SBill Fenner } 1534edb46e9SPaul Traina 1544edb46e9SPaul Traina void 155b0453382SBill Fenner pimv1_print(register const u_char *bp, register u_int len) 1564edb46e9SPaul Traina { 1574edb46e9SPaul Traina register const u_char *ep; 1584edb46e9SPaul Traina register u_char type; 1594edb46e9SPaul Traina 1604edb46e9SPaul Traina ep = (const u_char *)snapend; 1614edb46e9SPaul Traina if (bp >= ep) 1624edb46e9SPaul Traina return; 1634edb46e9SPaul Traina 1644edb46e9SPaul Traina type = bp[1]; 1654edb46e9SPaul Traina 1664edb46e9SPaul Traina switch (type) { 1674edb46e9SPaul Traina case 0: 1684edb46e9SPaul Traina (void)printf(" Query"); 169b0453382SBill Fenner if (TTEST(bp[8])) { 170b0453382SBill Fenner switch (bp[8] >> 4) { 171a1c2090eSBill Fenner case 0: 172a1c2090eSBill Fenner (void)printf(" Dense-mode"); 173b0453382SBill Fenner break; 174a1c2090eSBill Fenner case 1: 175a1c2090eSBill Fenner (void)printf(" Sparse-mode"); 176b0453382SBill Fenner break; 177a1c2090eSBill Fenner case 2: 178a1c2090eSBill Fenner (void)printf(" Sparse-Dense-mode"); 179b0453382SBill Fenner break; 180a1c2090eSBill Fenner default: 181a1c2090eSBill Fenner (void)printf(" mode-%d", bp[8] >> 4); 182b0453382SBill Fenner break; 183b0453382SBill Fenner } 184b0453382SBill Fenner } 185b0453382SBill Fenner if (vflag) { 186b0453382SBill Fenner TCHECK2(bp[10],2); 187b0453382SBill Fenner (void)printf(" (Hold-time "); 188b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[10])); 189b0453382SBill Fenner (void)printf(")"); 190b0453382SBill Fenner } 1914edb46e9SPaul Traina break; 1924edb46e9SPaul Traina 1934edb46e9SPaul Traina case 1: 1944edb46e9SPaul Traina (void)printf(" Register"); 195b0453382SBill Fenner TCHECK2(bp[8], 20); /* ip header */ 196b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[20]), 197b0453382SBill Fenner ipaddr_string(&bp[24])); 1984edb46e9SPaul Traina break; 1994edb46e9SPaul Traina case 2: 2004edb46e9SPaul Traina (void)printf(" Register-Stop"); 201b0453382SBill Fenner TCHECK2(bp[12], 4); 202b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[8]), 203b0453382SBill Fenner ipaddr_string(&bp[12])); 2044edb46e9SPaul Traina break; 2054edb46e9SPaul Traina case 3: 2064edb46e9SPaul Traina (void)printf(" Join/Prune"); 207a1c2090eSBill Fenner if (vflag) 208b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2094edb46e9SPaul Traina break; 2104edb46e9SPaul Traina case 4: 2114edb46e9SPaul Traina (void)printf(" RP-reachable"); 212b0453382SBill Fenner if (vflag) { 213b0453382SBill Fenner TCHECK2(bp[22], 2); 214b0453382SBill Fenner (void)printf(" group %s", 215b0453382SBill Fenner ipaddr_string(&bp[8])); 216b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 217b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[12])); 218a1c2090eSBill Fenner (void)printf(" RP %s hold ", ipaddr_string(&bp[16])); 219b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[22])); 220b0453382SBill Fenner } 2214edb46e9SPaul Traina break; 2224edb46e9SPaul Traina case 5: 2234edb46e9SPaul Traina (void)printf(" Assert"); 224b0453382SBill Fenner TCHECK2(bp[16], 4); 225b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[16]), 226b0453382SBill Fenner ipaddr_string(&bp[8])); 227b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 228b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[12])); 229b0453382SBill Fenner TCHECK2(bp[24], 4); 230b0453382SBill Fenner (void)printf(" %s pref %d metric %d", 231b0453382SBill Fenner (bp[20] & 0x80) ? "RP-tree" : "SPT", 232b0453382SBill Fenner EXTRACT_32BITS(&bp[20]) & 0x7fffffff, 233b0453382SBill Fenner EXTRACT_32BITS(&bp[24])); 2344edb46e9SPaul Traina break; 2354edb46e9SPaul Traina case 6: 2364edb46e9SPaul Traina (void)printf(" Graft"); 237a1c2090eSBill Fenner if (vflag) 238b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2394edb46e9SPaul Traina break; 2404edb46e9SPaul Traina case 7: 2414edb46e9SPaul Traina (void)printf(" Graft-ACK"); 242a1c2090eSBill Fenner if (vflag) 243b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2444edb46e9SPaul Traina break; 2454edb46e9SPaul Traina case 8: 2464edb46e9SPaul Traina (void)printf(" Mode"); 2474edb46e9SPaul Traina break; 2484edb46e9SPaul Traina default: 2494edb46e9SPaul Traina (void)printf(" [type %d]", type); 2504edb46e9SPaul Traina break; 2514edb46e9SPaul Traina } 252b0453382SBill Fenner if ((bp[4] >> 4) != 1) 253b0453382SBill Fenner (void)printf(" [v%d]", bp[4] >> 4); 254b0453382SBill Fenner return; 255b0453382SBill Fenner 256b0453382SBill Fenner trunc: 257b0453382SBill Fenner (void)printf("[|pim]"); 258b0453382SBill Fenner return; 259b0453382SBill Fenner } 260b0453382SBill Fenner 261b0453382SBill Fenner /* 262b0453382SBill Fenner * auto-RP is a cisco protocol, documented at 263a1c2090eSBill Fenner * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt 264a1c2090eSBill Fenner * 265a1c2090eSBill Fenner * This implements version 1+, dated Sept 9, 1998. 266b0453382SBill Fenner */ 267b0453382SBill Fenner void 268b0453382SBill Fenner cisco_autorp_print(register const u_char *bp, register u_int len) 269b0453382SBill Fenner { 270b0453382SBill Fenner int type; 271b0453382SBill Fenner int numrps; 272b0453382SBill Fenner int hold; 273b0453382SBill Fenner 274b0453382SBill Fenner TCHECK(bp[0]); 275b0453382SBill Fenner (void)printf(" auto-rp "); 276b0453382SBill Fenner type = bp[0]; 277b0453382SBill Fenner switch (type) { 278b0453382SBill Fenner case 0x11: 279b0453382SBill Fenner (void)printf("candidate-advert"); 280b0453382SBill Fenner break; 281b0453382SBill Fenner case 0x12: 282b0453382SBill Fenner (void)printf("mapping"); 283b0453382SBill Fenner break; 284b0453382SBill Fenner default: 285b0453382SBill Fenner (void)printf("type-0x%02x", type); 286b0453382SBill Fenner break; 287b0453382SBill Fenner } 288b0453382SBill Fenner 289b0453382SBill Fenner TCHECK(bp[1]); 290b0453382SBill Fenner numrps = bp[1]; 291b0453382SBill Fenner 292b0453382SBill Fenner TCHECK2(bp[2], 2); 293b0453382SBill Fenner (void)printf(" Hold "); 294b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[2]); 295b0453382SBill Fenner if (hold) 296b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[2])); 297b0453382SBill Fenner else 298b0453382SBill Fenner printf("FOREVER"); 299b0453382SBill Fenner 300b0453382SBill Fenner /* Next 4 bytes are reserved. */ 301b0453382SBill Fenner 302b0453382SBill Fenner bp += 8; len -= 8; 303b0453382SBill Fenner 304b0453382SBill Fenner /*XXX skip unless -v? */ 305b0453382SBill Fenner 306b0453382SBill Fenner /* 307b0453382SBill Fenner * Rest of packet: 308b0453382SBill Fenner * numrps entries of the form: 309b0453382SBill Fenner * 32 bits: RP 310b0453382SBill Fenner * 6 bits: reserved 311b0453382SBill Fenner * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2". 312b0453382SBill Fenner * 8 bits: # of entries for this RP 313b0453382SBill Fenner * each entry: 7 bits: reserved, 1 bit: negative, 314b0453382SBill Fenner * 8 bits: mask 32 bits: source 315b0453382SBill Fenner * lather, rinse, repeat. 316b0453382SBill Fenner */ 317b0453382SBill Fenner while (numrps--) { 318b0453382SBill Fenner int nentries; 319b0453382SBill Fenner char s; 320b0453382SBill Fenner 321b0453382SBill Fenner TCHECK2(bp[0], 4); 322b0453382SBill Fenner (void)printf(" RP %s", ipaddr_string(bp)); 323b0453382SBill Fenner TCHECK(bp[4]); 324b0453382SBill Fenner switch (bp[4] & 0x3) { 325b0453382SBill Fenner case 0: printf(" PIMv?"); 326b0453382SBill Fenner break; 327b0453382SBill Fenner case 1: printf(" PIMv1"); 328b0453382SBill Fenner break; 329b0453382SBill Fenner case 2: printf(" PIMv2"); 330b0453382SBill Fenner break; 331b0453382SBill Fenner case 3: printf(" PIMv1+2"); 332b0453382SBill Fenner break; 333b0453382SBill Fenner } 334a1c2090eSBill Fenner if (bp[4] & 0xfc) 335a1c2090eSBill Fenner (void)printf(" [rsvd=0x%02x]", bp[4] & 0xfc); 336b0453382SBill Fenner TCHECK(bp[5]); 337b0453382SBill Fenner nentries = bp[5]; 338b0453382SBill Fenner bp += 6; len -= 6; 339b0453382SBill Fenner s = ' '; 340b0453382SBill Fenner for (; nentries; nentries--) { 341b0453382SBill Fenner TCHECK2(bp[0], 6); 342b0453382SBill Fenner (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "", 343b0453382SBill Fenner ipaddr_string(&bp[2]), bp[1]); 344a1c2090eSBill Fenner if (bp[0] & 0xfe) 345a1c2090eSBill Fenner (void)printf("[rsvd=0x%02x]", bp[0] & 0xfe); 346b0453382SBill Fenner s = ','; 347b0453382SBill Fenner bp += 6; len -= 6; 348b0453382SBill Fenner } 349b0453382SBill Fenner } 350b0453382SBill Fenner return; 351b0453382SBill Fenner 352b0453382SBill Fenner trunc: 353b0453382SBill Fenner (void)printf("[|autorp]"); 354b0453382SBill Fenner return; 355b0453382SBill Fenner } 356b0453382SBill Fenner 357b0453382SBill Fenner void 358b0453382SBill Fenner pim_print(register const u_char *bp, register u_int len) 359b0453382SBill Fenner { 360b0453382SBill Fenner register const u_char *ep; 361b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 362b0453382SBill Fenner 363b0453382SBill Fenner ep = (const u_char *)snapend; 364b0453382SBill Fenner if (bp >= ep) 365b0453382SBill Fenner return; 366b0453382SBill Fenner #ifdef notyet /* currently we see only version and type */ 367b0453382SBill Fenner TCHECK(pim->pim_rsv); 368b0453382SBill Fenner #endif 369b0453382SBill Fenner 370b0453382SBill Fenner switch (PIM_VER(pim->pim_typever)) { 371b0453382SBill Fenner case 2: /* avoid hardcoding? */ 3729537d84eSBill Fenner (void)printf("pim v2"); 373b0453382SBill Fenner pimv2_print(bp, len); 374b0453382SBill Fenner break; 375b0453382SBill Fenner default: 3769537d84eSBill Fenner (void)printf("pim v%d", PIM_VER(pim->pim_typever)); 377b0453382SBill Fenner break; 378b0453382SBill Fenner } 379b0453382SBill Fenner return; 380b0453382SBill Fenner } 381b0453382SBill Fenner 382b0453382SBill Fenner /* 383b0453382SBill Fenner * PIMv2 uses encoded address representations. 384b0453382SBill Fenner * 385b0453382SBill Fenner * The last PIM-SM I-D before RFC2117 was published specified the 386b0453382SBill Fenner * following representation for unicast addresses. However, RFC2117 387b0453382SBill Fenner * specified no encoding for unicast addresses with the unicast 388b0453382SBill Fenner * address length specified in the header. Therefore, we have to 389b0453382SBill Fenner * guess which encoding is being used (Cisco's PIMv2 implementation 390b0453382SBill Fenner * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" 391b0453382SBill Fenner * field into a 'unicast-address-length-in-bytes' field. We guess 392b0453382SBill Fenner * that it's the draft encoding if this reserved field is zero. 393b0453382SBill Fenner * 394b0453382SBill Fenner * RFC2362 goes back to the encoded format, and calls the addr length 395b0453382SBill Fenner * field "reserved" again. 396b0453382SBill Fenner * 397b0453382SBill Fenner * The first byte is the address family, from: 398b0453382SBill Fenner * 399b0453382SBill Fenner * 0 Reserved 400b0453382SBill Fenner * 1 IP (IP version 4) 401b0453382SBill Fenner * 2 IP6 (IP version 6) 402b0453382SBill Fenner * 3 NSAP 403b0453382SBill Fenner * 4 HDLC (8-bit multidrop) 404b0453382SBill Fenner * 5 BBN 1822 405b0453382SBill Fenner * 6 802 (includes all 802 media plus Ethernet "canonical format") 406b0453382SBill Fenner * 7 E.163 407b0453382SBill Fenner * 8 E.164 (SMDS, Frame Relay, ATM) 408b0453382SBill Fenner * 9 F.69 (Telex) 409b0453382SBill Fenner * 10 X.121 (X.25, Frame Relay) 410b0453382SBill Fenner * 11 IPX 411b0453382SBill Fenner * 12 Appletalk 412b0453382SBill Fenner * 13 Decnet IV 413b0453382SBill Fenner * 14 Banyan Vines 414b0453382SBill Fenner * 15 E.164 with NSAP format subaddress 415b0453382SBill Fenner * 416b0453382SBill Fenner * In addition, the second byte is an "Encoding". 0 is the default 417b0453382SBill Fenner * encoding for the address family, and no other encodings are currently 418b0453382SBill Fenner * specified. 419b0453382SBill Fenner * 420b0453382SBill Fenner */ 421b0453382SBill Fenner 422b0453382SBill Fenner static int pimv2_addr_len; 423b0453382SBill Fenner 424b0453382SBill Fenner enum pimv2_addrtype { 425b0453382SBill Fenner pimv2_unicast, pimv2_group, pimv2_source 426b0453382SBill Fenner }; 427b0453382SBill Fenner 428b0453382SBill Fenner /* 0 1 2 3 429b0453382SBill Fenner * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 430b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 431b0453382SBill Fenner * | Addr Family | Encoding Type | Unicast Address | 432b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ 433b0453382SBill Fenner * 0 1 2 3 434b0453382SBill Fenner * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 435b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 436b0453382SBill Fenner * | Addr Family | Encoding Type | Reserved | Mask Len | 437b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 438b0453382SBill Fenner * | Group multicast Address | 439b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 440b0453382SBill Fenner * 0 1 2 3 441b0453382SBill Fenner * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 442b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 443b0453382SBill Fenner * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | 444b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 445b0453382SBill Fenner * | Source Address | 446b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 447b0453382SBill Fenner */ 448b0453382SBill Fenner static int 449b0453382SBill Fenner pimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent) 450b0453382SBill Fenner { 451b0453382SBill Fenner int af; 452b0453382SBill Fenner char *afstr; 453b0453382SBill Fenner int len, hdrlen; 454b0453382SBill Fenner 455b0453382SBill Fenner TCHECK(bp[0]); 456b0453382SBill Fenner 457b0453382SBill Fenner if (pimv2_addr_len == 0) { 458b0453382SBill Fenner TCHECK(bp[1]); 459b0453382SBill Fenner switch (bp[0]) { 460b0453382SBill Fenner case 1: 461b0453382SBill Fenner af = AF_INET; 462b0453382SBill Fenner afstr = "IPv4"; 463b0453382SBill Fenner len = 4; 464b0453382SBill Fenner break; 465b0453382SBill Fenner #ifdef INET6 466b0453382SBill Fenner case 2: 467b0453382SBill Fenner af = AF_INET6; 468b0453382SBill Fenner afstr = "IPv6"; 469b0453382SBill Fenner len = 16; 470b0453382SBill Fenner break; 471b0453382SBill Fenner #endif 472b0453382SBill Fenner default: 473b0453382SBill Fenner return -1; 474b0453382SBill Fenner } 475b0453382SBill Fenner if (bp[1] != 0) 476b0453382SBill Fenner return -1; 477b0453382SBill Fenner hdrlen = 2; 478b0453382SBill Fenner } else { 479b0453382SBill Fenner switch (pimv2_addr_len) { 480b0453382SBill Fenner case 4: 481b0453382SBill Fenner af = AF_INET; 482b0453382SBill Fenner afstr = "IPv4"; 483b0453382SBill Fenner break; 484b0453382SBill Fenner #ifdef INET6 485b0453382SBill Fenner case 16: 486b0453382SBill Fenner af = AF_INET6; 487b0453382SBill Fenner afstr = "IPv6"; 488b0453382SBill Fenner break; 489b0453382SBill Fenner #endif 490b0453382SBill Fenner default: 491b0453382SBill Fenner return -1; 492b0453382SBill Fenner break; 493b0453382SBill Fenner } 494b0453382SBill Fenner len = pimv2_addr_len; 495b0453382SBill Fenner hdrlen = 0; 496b0453382SBill Fenner } 497b0453382SBill Fenner 498b0453382SBill Fenner bp += hdrlen; 499b0453382SBill Fenner switch (at) { 500b0453382SBill Fenner case pimv2_unicast: 501b0453382SBill Fenner TCHECK2(bp[0], len); 502b0453382SBill Fenner if (af == AF_INET) { 503b0453382SBill Fenner if (!silent) 504b0453382SBill Fenner (void)printf("%s", ipaddr_string(bp)); 505b0453382SBill Fenner } 506b0453382SBill Fenner #ifdef INET6 507b0453382SBill Fenner else if (af == AF_INET6) { 508b0453382SBill Fenner if (!silent) 509b0453382SBill Fenner (void)printf("%s", ip6addr_string(bp)); 510b0453382SBill Fenner } 511b0453382SBill Fenner #endif 512b0453382SBill Fenner return hdrlen + len; 513b0453382SBill Fenner case pimv2_group: 514b0453382SBill Fenner case pimv2_source: 515b0453382SBill Fenner TCHECK2(bp[0], len + 2); 516b0453382SBill Fenner if (af == AF_INET) { 517b0453382SBill Fenner if (!silent) { 518b0453382SBill Fenner (void)printf("%s", ipaddr_string(bp + 2)); 519b0453382SBill Fenner if (bp[1] != 32) 520b0453382SBill Fenner (void)printf("/%u", bp[1]); 521b0453382SBill Fenner } 522b0453382SBill Fenner } 523b0453382SBill Fenner #ifdef INET6 524b0453382SBill Fenner else if (af == AF_INET6) { 525b0453382SBill Fenner if (!silent) { 526b0453382SBill Fenner (void)printf("%s", ip6addr_string(bp + 2)); 527b0453382SBill Fenner if (bp[1] != 128) 528b0453382SBill Fenner (void)printf("/%u", bp[1]); 529b0453382SBill Fenner } 530b0453382SBill Fenner } 531b0453382SBill Fenner #endif 532b0453382SBill Fenner if (bp[0] && !silent) { 533b0453382SBill Fenner if (at == pimv2_group) { 534b0453382SBill Fenner (void)printf("(0x%02x)", bp[0]); 535b0453382SBill Fenner } else { 536b0453382SBill Fenner (void)printf("(%s%s%s", 537b0453382SBill Fenner bp[0] & 0x04 ? "S" : "", 538b0453382SBill Fenner bp[0] & 0x02 ? "W" : "", 539b0453382SBill Fenner bp[0] & 0x01 ? "R" : ""); 540b0453382SBill Fenner if (bp[0] & 0xf8) { 541b0453382SBill Fenner (void) printf("+0x%02x", bp[0] & 0xf8); 542b0453382SBill Fenner } 543b0453382SBill Fenner (void)printf(")"); 544b0453382SBill Fenner } 545b0453382SBill Fenner } 546b0453382SBill Fenner return hdrlen + 2 + len; 547b0453382SBill Fenner default: 548b0453382SBill Fenner return -1; 549b0453382SBill Fenner } 550b0453382SBill Fenner trunc: 551b0453382SBill Fenner return -1; 552b0453382SBill Fenner } 553b0453382SBill Fenner 554b0453382SBill Fenner static void 555b0453382SBill Fenner pimv2_print(register const u_char *bp, register u_int len) 556b0453382SBill Fenner { 557b0453382SBill Fenner register const u_char *ep; 558b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 559b0453382SBill Fenner int advance; 560b0453382SBill Fenner 561b0453382SBill Fenner ep = (const u_char *)snapend; 562b0453382SBill Fenner if (bp >= ep) 563b0453382SBill Fenner return; 5649537d84eSBill Fenner if (ep > bp + len) 5659537d84eSBill Fenner ep = bp + len; 566b0453382SBill Fenner TCHECK(pim->pim_rsv); 567b0453382SBill Fenner pimv2_addr_len = pim->pim_rsv; 568b0453382SBill Fenner if (pimv2_addr_len != 0) 569b0453382SBill Fenner (void)printf("[RFC2117-encoding] "); 570b0453382SBill Fenner 571b0453382SBill Fenner switch (PIM_TYPE(pim->pim_typever)) { 572b0453382SBill Fenner case 0: 573b0453382SBill Fenner { 574b0453382SBill Fenner u_int16_t otype, olen; 575b0453382SBill Fenner (void)printf(" Hello"); 576b0453382SBill Fenner bp += 4; 577b0453382SBill Fenner while (bp < ep) { 578b0453382SBill Fenner TCHECK2(bp[0], 4); 579b0453382SBill Fenner otype = EXTRACT_16BITS(&bp[0]); 580b0453382SBill Fenner olen = EXTRACT_16BITS(&bp[2]); 581b0453382SBill Fenner TCHECK2(bp[0], 4 + olen); 582b0453382SBill Fenner switch (otype) { 583b0453382SBill Fenner case 1: /* Hold time */ 584b0453382SBill Fenner (void)printf(" (Hold-time "); 585b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[4])); 586b0453382SBill Fenner (void)printf(")"); 587b0453382SBill Fenner break; 588b0453382SBill Fenner 589a1c2090eSBill Fenner case 19: /* DR-Priority */ 590a1c2090eSBill Fenner (void)printf(" (DR-Priority: "); 591a1c2090eSBill Fenner if (olen != 4) { 592a1c2090eSBill Fenner (void)printf("!olen=%d!)", olen); 593a1c2090eSBill Fenner } else { 594a1c2090eSBill Fenner (void)printf("%d)", EXTRACT_32BITS(&bp[4])); 595a1c2090eSBill Fenner } 596b0453382SBill Fenner break; 597b0453382SBill Fenner 598b0453382SBill Fenner case 20: 599b0453382SBill Fenner (void)printf(" (Genid: 0x%08x)", EXTRACT_32BITS(&bp[4])); 600b0453382SBill Fenner break; 601b0453382SBill Fenner 602b0453382SBill Fenner case 21: 603a1c2090eSBill Fenner (void)printf(" (State Refresh Capable; v%d", bp[4]); 604a1c2090eSBill Fenner if (bp[5] != 0) { 605a1c2090eSBill Fenner (void)printf(" interval "); 606a1c2090eSBill Fenner relts_print(bp[5]); 607a1c2090eSBill Fenner } 608a1c2090eSBill Fenner if (EXTRACT_16BITS(&bp[6]) != 0) { 609a1c2090eSBill Fenner (void)printf(" ?0x%04x?", EXTRACT_16BITS(&bp[6])); 610b0453382SBill Fenner } 611b0453382SBill Fenner (void)printf(")"); 612b0453382SBill Fenner break; 613b0453382SBill Fenner 614a1c2090eSBill Fenner case 22: /* Bidir-Capable */ 615a1c2090eSBill Fenner (void)printf(" (bidir-capable)"); 616a1c2090eSBill Fenner break; 617a1c2090eSBill Fenner 618b0453382SBill Fenner default: 619b0453382SBill Fenner if (vflag) 620b0453382SBill Fenner (void)printf(" [Hello option %d]", otype); 621b0453382SBill Fenner } 622b0453382SBill Fenner bp += 4 + olen; 623b0453382SBill Fenner } 624b0453382SBill Fenner break; 625b0453382SBill Fenner } 626b0453382SBill Fenner 627b0453382SBill Fenner case 1: 628b0453382SBill Fenner { 629b0453382SBill Fenner struct ip *ip; 630b0453382SBill Fenner 631b0453382SBill Fenner (void)printf(" Register"); 632b0453382SBill Fenner if (vflag && bp + 8 <= ep) { 633b0453382SBill Fenner (void)printf(" %s%s", bp[4] & 0x80 ? "B" : "", 634b0453382SBill Fenner bp[4] & 0x40 ? "N" : ""); 635b0453382SBill Fenner } 636b0453382SBill Fenner bp += 8; len -= 8; 637b0453382SBill Fenner 638b0453382SBill Fenner /* encapsulated multicast packet */ 639b0453382SBill Fenner if (bp >= ep) 640b0453382SBill Fenner break; 641b0453382SBill Fenner ip = (struct ip *)bp; 642943ee2b1SBill Fenner switch (IP_V(ip)) { 643b0453382SBill Fenner case 4: /* IPv4 */ 644b0453382SBill Fenner printf(" "); 645b0453382SBill Fenner ip_print(bp, len); 646b0453382SBill Fenner break; 647b0453382SBill Fenner #ifdef INET6 648b0453382SBill Fenner case 6: /* IPv6 */ 649b0453382SBill Fenner printf(" "); 650b0453382SBill Fenner ip6_print(bp, len); 651b0453382SBill Fenner break; 652b0453382SBill Fenner #endif 653b0453382SBill Fenner default: 654943ee2b1SBill Fenner (void)printf(" IP ver %d", IP_V(ip)); 655b0453382SBill Fenner break; 656b0453382SBill Fenner } 657b0453382SBill Fenner break; 658b0453382SBill Fenner } 659b0453382SBill Fenner 660b0453382SBill Fenner case 2: 661b0453382SBill Fenner (void)printf(" Register-Stop"); 662b0453382SBill Fenner bp += 4; len -= 4; 663b0453382SBill Fenner if (bp >= ep) 664b0453382SBill Fenner break; 665b0453382SBill Fenner (void)printf(" group="); 666b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 667b0453382SBill Fenner (void)printf("..."); 668b0453382SBill Fenner break; 669b0453382SBill Fenner } 670b0453382SBill Fenner bp += advance; len -= advance; 671b0453382SBill Fenner if (bp >= ep) 672b0453382SBill Fenner break; 673b0453382SBill Fenner (void)printf(" source="); 674b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 675b0453382SBill Fenner (void)printf("..."); 676b0453382SBill Fenner break; 677b0453382SBill Fenner } 678b0453382SBill Fenner bp += advance; len -= advance; 679b0453382SBill Fenner break; 680b0453382SBill Fenner 681b0453382SBill Fenner case 3: 682b0453382SBill Fenner case 6: 683b0453382SBill Fenner case 7: 684b0453382SBill Fenner { 685b0453382SBill Fenner u_int8_t ngroup; 686b0453382SBill Fenner u_int16_t holdtime; 687b0453382SBill Fenner u_int16_t njoin; 688b0453382SBill Fenner u_int16_t nprune; 689b0453382SBill Fenner int i, j; 690b0453382SBill Fenner 691b0453382SBill Fenner switch (PIM_TYPE(pim->pim_typever)) { 692b0453382SBill Fenner case 3: 693b0453382SBill Fenner (void)printf(" Join/Prune"); 694b0453382SBill Fenner break; 695b0453382SBill Fenner case 6: 696b0453382SBill Fenner (void)printf(" Graft"); 697b0453382SBill Fenner break; 698b0453382SBill Fenner case 7: 699b0453382SBill Fenner (void)printf(" Graft-ACK"); 700b0453382SBill Fenner break; 701b0453382SBill Fenner } 702b0453382SBill Fenner bp += 4; len -= 4; 703b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 704b0453382SBill Fenner if (bp >= ep) 705b0453382SBill Fenner break; 706b0453382SBill Fenner (void)printf(" upstream-neighbor="); 707b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 708b0453382SBill Fenner (void)printf("..."); 709b0453382SBill Fenner break; 710b0453382SBill Fenner } 711b0453382SBill Fenner bp += advance; len -= advance; 712b0453382SBill Fenner } 713b0453382SBill Fenner if (bp + 4 > ep) 714b0453382SBill Fenner break; 715b0453382SBill Fenner ngroup = bp[1]; 716b0453382SBill Fenner holdtime = EXTRACT_16BITS(&bp[2]); 717b0453382SBill Fenner (void)printf(" groups=%u", ngroup); 718b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 719b0453382SBill Fenner (void)printf(" holdtime="); 720b0453382SBill Fenner if (holdtime == 0xffff) 721b0453382SBill Fenner (void)printf("infty"); 722b0453382SBill Fenner else 723b0453382SBill Fenner relts_print(holdtime); 724b0453382SBill Fenner } 725b0453382SBill Fenner bp += 4; len -= 4; 726b0453382SBill Fenner for (i = 0; i < ngroup; i++) { 727b0453382SBill Fenner if (bp >= ep) 728b0453382SBill Fenner goto jp_done; 729b0453382SBill Fenner (void)printf(" (group%d: ", i); 730b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 731b0453382SBill Fenner (void)printf("...)"); 732b0453382SBill Fenner goto jp_done; 733b0453382SBill Fenner } 734b0453382SBill Fenner bp += advance; len -= advance; 735b0453382SBill Fenner if (bp + 4 > ep) { 736b0453382SBill Fenner (void)printf("...)"); 737b0453382SBill Fenner goto jp_done; 738b0453382SBill Fenner } 739b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[0]); 740b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[2]); 741b0453382SBill Fenner (void)printf(" join=%u", njoin); 742b0453382SBill Fenner bp += 4; len -= 4; 743b0453382SBill Fenner for (j = 0; j < njoin; j++) { 744b0453382SBill Fenner (void)printf(" "); 745b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { 746b0453382SBill Fenner (void)printf("...)"); 747b0453382SBill Fenner goto jp_done; 748b0453382SBill Fenner } 749b0453382SBill Fenner bp += advance; len -= advance; 750b0453382SBill Fenner } 751b0453382SBill Fenner (void)printf(" prune=%u", nprune); 752b0453382SBill Fenner for (j = 0; j < nprune; j++) { 753b0453382SBill Fenner (void)printf(" "); 754b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { 755b0453382SBill Fenner (void)printf("...)"); 756b0453382SBill Fenner goto jp_done; 757b0453382SBill Fenner } 758b0453382SBill Fenner bp += advance; len -= advance; 759b0453382SBill Fenner } 760b0453382SBill Fenner (void)printf(")"); 761b0453382SBill Fenner } 762b0453382SBill Fenner jp_done: 763b0453382SBill Fenner break; 764b0453382SBill Fenner } 765b0453382SBill Fenner 766b0453382SBill Fenner case 4: 767b0453382SBill Fenner { 768b0453382SBill Fenner int i, j, frpcnt; 769b0453382SBill Fenner 770b0453382SBill Fenner (void)printf(" Bootstrap"); 771b0453382SBill Fenner bp += 4; 772b0453382SBill Fenner 773b0453382SBill Fenner /* Fragment Tag, Hash Mask len, and BSR-priority */ 774b0453382SBill Fenner if (bp + sizeof(u_int16_t) >= ep) break; 775b0453382SBill Fenner (void)printf(" tag=%x", EXTRACT_16BITS(bp)); 776b0453382SBill Fenner bp += sizeof(u_int16_t); 777b0453382SBill Fenner if (bp >= ep) break; 778b0453382SBill Fenner (void)printf(" hashmlen=%d", bp[0]); 779b0453382SBill Fenner if (bp + 1 >= ep) break; 780b0453382SBill Fenner (void)printf(" BSRprio=%d", bp[1]); 781b0453382SBill Fenner bp += 2; 782b0453382SBill Fenner 783b0453382SBill Fenner /* Encoded-Unicast-BSR-Address */ 784b0453382SBill Fenner if (bp >= ep) break; 785b0453382SBill Fenner (void)printf(" BSR="); 786b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 787b0453382SBill Fenner (void)printf("..."); 788b0453382SBill Fenner break; 789b0453382SBill Fenner } 790b0453382SBill Fenner bp += advance; 791b0453382SBill Fenner 792b0453382SBill Fenner for (i = 0; bp < ep; i++) { 793b0453382SBill Fenner /* Encoded-Group Address */ 794b0453382SBill Fenner (void)printf(" (group%d: ", i); 795b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) 796b0453382SBill Fenner < 0) { 797b0453382SBill Fenner (void)printf("...)"); 798b0453382SBill Fenner goto bs_done; 799b0453382SBill Fenner } 800b0453382SBill Fenner bp += advance; 801b0453382SBill Fenner 802b0453382SBill Fenner /* RP-Count, Frag RP-Cnt, and rsvd */ 803b0453382SBill Fenner if (bp >= ep) { 804b0453382SBill Fenner (void)printf("...)"); 805b0453382SBill Fenner goto bs_done; 806b0453382SBill Fenner } 807943ee2b1SBill Fenner (void)printf(" RPcnt=%d", bp[0]); 808b0453382SBill Fenner if (bp + 1 >= ep) { 809b0453382SBill Fenner (void)printf("...)"); 810b0453382SBill Fenner goto bs_done; 811b0453382SBill Fenner } 812943ee2b1SBill Fenner (void)printf(" FRPcnt=%d", frpcnt = bp[1]); 813b0453382SBill Fenner bp += 4; 814b0453382SBill Fenner 815b0453382SBill Fenner for (j = 0; j < frpcnt && bp < ep; j++) { 816b0453382SBill Fenner /* each RP info */ 817b0453382SBill Fenner (void)printf(" RP%d=", j); 818b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, 819b0453382SBill Fenner pimv2_unicast, 820b0453382SBill Fenner 0)) < 0) { 821b0453382SBill Fenner (void)printf("...)"); 822b0453382SBill Fenner goto bs_done; 823b0453382SBill Fenner } 824b0453382SBill Fenner bp += advance; 825b0453382SBill Fenner 826b0453382SBill Fenner if (bp + 1 >= ep) { 827b0453382SBill Fenner (void)printf("...)"); 828b0453382SBill Fenner goto bs_done; 829b0453382SBill Fenner } 830b0453382SBill Fenner (void)printf(",holdtime="); 831b0453382SBill Fenner relts_print(EXTRACT_16BITS(bp)); 832b0453382SBill Fenner if (bp + 2 >= ep) { 833b0453382SBill Fenner (void)printf("...)"); 834b0453382SBill Fenner goto bs_done; 835b0453382SBill Fenner } 836b0453382SBill Fenner (void)printf(",prio=%d", bp[2]); 837b0453382SBill Fenner bp += 4; 838b0453382SBill Fenner } 839b0453382SBill Fenner (void)printf(")"); 840b0453382SBill Fenner } 841b0453382SBill Fenner bs_done: 842b0453382SBill Fenner break; 843b0453382SBill Fenner } 844b0453382SBill Fenner case 5: 845b0453382SBill Fenner (void)printf(" Assert"); 846b0453382SBill Fenner bp += 4; len -= 4; 847b0453382SBill Fenner if (bp >= ep) 848b0453382SBill Fenner break; 849b0453382SBill Fenner (void)printf(" group="); 850b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 851b0453382SBill Fenner (void)printf("..."); 852b0453382SBill Fenner break; 853b0453382SBill Fenner } 854b0453382SBill Fenner bp += advance; len -= advance; 855b0453382SBill Fenner if (bp >= ep) 856b0453382SBill Fenner break; 857b0453382SBill Fenner (void)printf(" src="); 858b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 859b0453382SBill Fenner (void)printf("..."); 860b0453382SBill Fenner break; 861b0453382SBill Fenner } 862b0453382SBill Fenner bp += advance; len -= advance; 863b0453382SBill Fenner if (bp + 8 > ep) 864b0453382SBill Fenner break; 865b0453382SBill Fenner if (bp[0] & 0x80) 866b0453382SBill Fenner (void)printf(" RPT"); 867b0453382SBill Fenner (void)printf(" pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff); 868b0453382SBill Fenner (void)printf(" metric=%u", EXTRACT_32BITS(&bp[4])); 869b0453382SBill Fenner break; 870b0453382SBill Fenner 871b0453382SBill Fenner case 8: 872b0453382SBill Fenner { 873b0453382SBill Fenner int i, pfxcnt; 874b0453382SBill Fenner 875b0453382SBill Fenner (void)printf(" Candidate-RP-Advertisement"); 876b0453382SBill Fenner bp += 4; 877b0453382SBill Fenner 878b0453382SBill Fenner /* Prefix-Cnt, Priority, and Holdtime */ 879b0453382SBill Fenner if (bp >= ep) break; 880b0453382SBill Fenner (void)printf(" prefix-cnt=%d", bp[0]); 881b0453382SBill Fenner pfxcnt = bp[0]; 882b0453382SBill Fenner if (bp + 1 >= ep) break; 883b0453382SBill Fenner (void)printf(" prio=%d", bp[1]); 884b0453382SBill Fenner if (bp + 3 >= ep) break; 885b0453382SBill Fenner (void)printf(" holdtime="); 886b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[2])); 887b0453382SBill Fenner bp += 4; 888b0453382SBill Fenner 889b0453382SBill Fenner /* Encoded-Unicast-RP-Address */ 890b0453382SBill Fenner if (bp >= ep) break; 891b0453382SBill Fenner (void)printf(" RP="); 892b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 893b0453382SBill Fenner (void)printf("..."); 894b0453382SBill Fenner break; 895b0453382SBill Fenner } 896b0453382SBill Fenner bp += advance; 897b0453382SBill Fenner 898b0453382SBill Fenner /* Encoded-Group Addresses */ 899b0453382SBill Fenner for (i = 0; i < pfxcnt && bp < ep; i++) { 900b0453382SBill Fenner (void)printf(" Group%d=", i); 901b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) 902b0453382SBill Fenner < 0) { 903b0453382SBill Fenner (void)printf("..."); 904b0453382SBill Fenner break; 905b0453382SBill Fenner } 906b0453382SBill Fenner bp += advance; 907b0453382SBill Fenner } 908b0453382SBill Fenner break; 909b0453382SBill Fenner } 910b0453382SBill Fenner 911b0453382SBill Fenner case 9: 912b0453382SBill Fenner (void)printf(" Prune-Refresh"); 913b0453382SBill Fenner (void)printf(" src="); 914b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 915b0453382SBill Fenner (void)printf("..."); 916b0453382SBill Fenner break; 917b0453382SBill Fenner } 918b0453382SBill Fenner bp += advance; 919b0453382SBill Fenner (void)printf(" grp="); 920b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 921b0453382SBill Fenner (void)printf("..."); 922b0453382SBill Fenner break; 923b0453382SBill Fenner } 924b0453382SBill Fenner bp += advance; 925b0453382SBill Fenner (void)printf(" forwarder="); 926b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 927b0453382SBill Fenner (void)printf("..."); 928b0453382SBill Fenner break; 929b0453382SBill Fenner } 930b0453382SBill Fenner bp += advance; 931b0453382SBill Fenner TCHECK2(bp[0], 2); 932b0453382SBill Fenner (void)printf(" TUNR "); 933b0453382SBill Fenner relts_print(EXTRACT_16BITS(bp)); 934b0453382SBill Fenner break; 935b0453382SBill Fenner 936b0453382SBill Fenner 937b0453382SBill Fenner default: 938b0453382SBill Fenner (void)printf(" [type %d]", PIM_TYPE(pim->pim_typever)); 939b0453382SBill Fenner break; 940b0453382SBill Fenner } 941b0453382SBill Fenner 942b0453382SBill Fenner return; 943b0453382SBill Fenner 944b0453382SBill Fenner trunc: 945b0453382SBill Fenner (void)printf("[|pim]"); 9464edb46e9SPaul Traina } 947