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