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