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 25cc391cceSBruce M Simpson static const char rcsid[] _U_ = 26cc391cceSBruce M Simpson "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.37.2.4 2004/03/24 02:52:37 guy Exp $ (LBL)"; 27b0453382SBill Fenner #endif 28b0453382SBill Fenner 29b0453382SBill Fenner #ifdef HAVE_CONFIG_H 30b0453382SBill Fenner #include "config.h" 314edb46e9SPaul Traina #endif 324edb46e9SPaul Traina 33cc391cceSBruce M Simpson #include <tcpdump-stdinc.h> 34b0453382SBill Fenner 35b0453382SBill Fenner /* 36b0453382SBill Fenner * XXX: We consider a case where IPv6 is not ready yet for portability, 37b0453382SBill Fenner * but PIM dependent defintions should be independent of IPv6... 38b0453382SBill Fenner */ 39b0453382SBill Fenner 40b0453382SBill Fenner struct pim { 41b0453382SBill Fenner u_int8_t pim_typever; 429537d84eSBill Fenner /* upper 4bit: PIM version number; 2 for PIMv2 */ 439537d84eSBill Fenner /* lower 4bit: the PIM message type, currently they are: 44b0453382SBill Fenner * Hello, Register, Register-Stop, Join/Prune, 45b0453382SBill Fenner * Bootstrap, Assert, Graft (PIM-DM only), 46b0453382SBill Fenner * Graft-Ack (PIM-DM only), C-RP-Adv 47b0453382SBill Fenner */ 489537d84eSBill Fenner #define PIM_VER(x) (((x) & 0xf0) >> 4) 499537d84eSBill Fenner #define PIM_TYPE(x) ((x) & 0x0f) 50b0453382SBill Fenner u_char pim_rsv; /* Reserved */ 51b0453382SBill Fenner u_short pim_cksum; /* IP style check sum */ 52b0453382SBill Fenner }; 53b0453382SBill Fenner 544edb46e9SPaul Traina 554edb46e9SPaul Traina #include <stdio.h> 564edb46e9SPaul Traina #include <stdlib.h> 574edb46e9SPaul Traina 584edb46e9SPaul Traina #include "interface.h" 594edb46e9SPaul Traina #include "addrtoname.h" 60b0453382SBill Fenner #include "extract.h" 61b0453382SBill Fenner 62943ee2b1SBill Fenner #include "ip.h" 63943ee2b1SBill Fenner 64b0453382SBill Fenner static void pimv2_print(register const u_char *bp, register u_int len); 65b0453382SBill Fenner 66b0453382SBill Fenner static void 67b0453382SBill Fenner pimv1_join_prune_print(register const u_char *bp, register u_int len) 68b0453382SBill Fenner { 69b0453382SBill Fenner int maddrlen, addrlen, ngroups, njoin, nprune; 70b0453382SBill Fenner int njp; 71b0453382SBill Fenner 72b0453382SBill Fenner /* If it's a single group and a single source, use 1-line output. */ 73b0453382SBill Fenner if (TTEST2(bp[0], 30) && bp[11] == 1 && 74b0453382SBill Fenner ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { 75b0453382SBill Fenner int hold; 76b0453382SBill Fenner 77b0453382SBill Fenner (void)printf(" RPF %s ", ipaddr_string(bp)); 78b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[6]); 79b0453382SBill Fenner if (hold != 180) { 80b0453382SBill Fenner (void)printf("Hold "); 81b0453382SBill Fenner relts_print(hold); 82b0453382SBill Fenner } 83b0453382SBill Fenner (void)printf("%s (%s/%d, %s", njoin ? "Join" : "Prune", 84b0453382SBill Fenner ipaddr_string(&bp[26]), bp[25] & 0x3f, 85b0453382SBill Fenner ipaddr_string(&bp[12])); 86b0453382SBill Fenner if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) 87b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[16])); 88b0453382SBill Fenner (void)printf(") %s%s %s", 89b0453382SBill Fenner (bp[24] & 0x01) ? "Sparse" : "Dense", 90b0453382SBill Fenner (bp[25] & 0x80) ? " WC" : "", 91b0453382SBill Fenner (bp[25] & 0x40) ? "RP" : "SPT"); 92b0453382SBill Fenner return; 93b0453382SBill Fenner } 94b0453382SBill Fenner 95b0453382SBill Fenner TCHECK2(bp[0], 4); 96a1c2090eSBill Fenner if (vflag > 1) 97a1c2090eSBill Fenner (void)printf("\n"); 98a1c2090eSBill Fenner (void)printf(" Upstream Nbr: %s", ipaddr_string(bp)); 99b0453382SBill Fenner TCHECK2(bp[6], 2); 100a1c2090eSBill Fenner if (vflag > 1) 101a1c2090eSBill Fenner (void)printf("\n"); 102a1c2090eSBill Fenner (void)printf(" Hold time: "); 103b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[6])); 104a1c2090eSBill Fenner if (vflag < 2) 105a1c2090eSBill Fenner return; 106a1c2090eSBill Fenner bp += 8; 107a1c2090eSBill Fenner len -= 8; 108b0453382SBill Fenner 109b0453382SBill Fenner TCHECK2(bp[0], 4); 110b0453382SBill Fenner maddrlen = bp[1]; 111b0453382SBill Fenner addrlen = bp[2]; 112b0453382SBill Fenner ngroups = bp[3]; 113a1c2090eSBill Fenner bp += 4; 114a1c2090eSBill Fenner len -= 4; 115b0453382SBill Fenner while (ngroups--) { 116b0453382SBill Fenner TCHECK2(bp[0], 4); 117b0453382SBill Fenner (void)printf("\n\tGroup: %s", ipaddr_string(bp)); 118cc391cceSBruce M Simpson TCHECK2(bp[4], 4); 119b0453382SBill Fenner if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) 120b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[4])); 121b0453382SBill Fenner TCHECK2(bp[8], 4); 122b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[8]); 123b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[10]); 124b0453382SBill Fenner (void)printf(" joined: %d pruned: %d", njoin, nprune); 125a1c2090eSBill Fenner bp += 12; 126a1c2090eSBill Fenner len -= 12; 127b0453382SBill Fenner for (njp = 0; njp < (njoin + nprune); njp++) { 128cc391cceSBruce M Simpson const char *type; 129b0453382SBill Fenner 130a1c2090eSBill Fenner if (njp < njoin) 131b0453382SBill Fenner type = "Join "; 132a1c2090eSBill Fenner else 133b0453382SBill Fenner type = "Prune"; 134b0453382SBill Fenner TCHECK2(bp[0], 6); 135b0453382SBill Fenner (void)printf("\n\t%s %s%s%s%s/%d", type, 136b0453382SBill Fenner (bp[0] & 0x01) ? "Sparse " : "Dense ", 137b0453382SBill Fenner (bp[1] & 0x80) ? "WC " : "", 138b0453382SBill Fenner (bp[1] & 0x40) ? "RP " : "SPT ", 139b0453382SBill Fenner ipaddr_string(&bp[2]), bp[1] & 0x3f); 140a1c2090eSBill Fenner bp += 6; 141a1c2090eSBill Fenner len -= 6; 142b0453382SBill Fenner } 143b0453382SBill Fenner } 144b0453382SBill Fenner return; 145b0453382SBill Fenner trunc: 146b0453382SBill Fenner (void)printf("[|pim]"); 147b0453382SBill Fenner return; 148b0453382SBill Fenner } 1494edb46e9SPaul Traina 1504edb46e9SPaul Traina void 151b0453382SBill Fenner pimv1_print(register const u_char *bp, register u_int len) 1524edb46e9SPaul Traina { 1534edb46e9SPaul Traina register const u_char *ep; 1544edb46e9SPaul Traina register u_char type; 1554edb46e9SPaul Traina 1564edb46e9SPaul Traina ep = (const u_char *)snapend; 1574edb46e9SPaul Traina if (bp >= ep) 1584edb46e9SPaul Traina return; 1594edb46e9SPaul Traina 160cc391cceSBruce M Simpson TCHECK(bp[1]); 1614edb46e9SPaul Traina type = bp[1]; 1624edb46e9SPaul Traina 1634edb46e9SPaul Traina switch (type) { 1644edb46e9SPaul Traina case 0: 1654edb46e9SPaul Traina (void)printf(" Query"); 166b0453382SBill Fenner if (TTEST(bp[8])) { 167b0453382SBill Fenner switch (bp[8] >> 4) { 168a1c2090eSBill Fenner case 0: 169a1c2090eSBill Fenner (void)printf(" Dense-mode"); 170b0453382SBill Fenner break; 171a1c2090eSBill Fenner case 1: 172a1c2090eSBill Fenner (void)printf(" Sparse-mode"); 173b0453382SBill Fenner break; 174a1c2090eSBill Fenner case 2: 175a1c2090eSBill Fenner (void)printf(" Sparse-Dense-mode"); 176b0453382SBill Fenner break; 177a1c2090eSBill Fenner default: 178a1c2090eSBill Fenner (void)printf(" mode-%d", bp[8] >> 4); 179b0453382SBill Fenner break; 180b0453382SBill Fenner } 181b0453382SBill Fenner } 182b0453382SBill Fenner if (vflag) { 183b0453382SBill Fenner TCHECK2(bp[10],2); 184b0453382SBill Fenner (void)printf(" (Hold-time "); 185b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[10])); 186b0453382SBill Fenner (void)printf(")"); 187b0453382SBill Fenner } 1884edb46e9SPaul Traina break; 1894edb46e9SPaul Traina 1904edb46e9SPaul Traina case 1: 1914edb46e9SPaul Traina (void)printf(" Register"); 192b0453382SBill Fenner TCHECK2(bp[8], 20); /* ip header */ 193b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[20]), 194b0453382SBill Fenner ipaddr_string(&bp[24])); 1954edb46e9SPaul Traina break; 1964edb46e9SPaul Traina case 2: 1974edb46e9SPaul Traina (void)printf(" Register-Stop"); 198b0453382SBill Fenner TCHECK2(bp[12], 4); 199b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[8]), 200b0453382SBill Fenner ipaddr_string(&bp[12])); 2014edb46e9SPaul Traina break; 2024edb46e9SPaul Traina case 3: 2034edb46e9SPaul Traina (void)printf(" Join/Prune"); 204a1c2090eSBill Fenner if (vflag) 205b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2064edb46e9SPaul Traina break; 2074edb46e9SPaul Traina case 4: 2084edb46e9SPaul Traina (void)printf(" RP-reachable"); 209b0453382SBill Fenner if (vflag) { 210b0453382SBill Fenner TCHECK2(bp[22], 2); 211b0453382SBill Fenner (void)printf(" group %s", 212b0453382SBill Fenner ipaddr_string(&bp[8])); 213b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 214b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[12])); 215a1c2090eSBill Fenner (void)printf(" RP %s hold ", ipaddr_string(&bp[16])); 216b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[22])); 217b0453382SBill Fenner } 2184edb46e9SPaul Traina break; 2194edb46e9SPaul Traina case 5: 2204edb46e9SPaul Traina (void)printf(" Assert"); 221b0453382SBill Fenner TCHECK2(bp[16], 4); 222b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[16]), 223b0453382SBill Fenner ipaddr_string(&bp[8])); 224b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 225b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[12])); 226b0453382SBill Fenner TCHECK2(bp[24], 4); 227b0453382SBill Fenner (void)printf(" %s pref %d metric %d", 228b0453382SBill Fenner (bp[20] & 0x80) ? "RP-tree" : "SPT", 229b0453382SBill Fenner EXTRACT_32BITS(&bp[20]) & 0x7fffffff, 230b0453382SBill Fenner EXTRACT_32BITS(&bp[24])); 2314edb46e9SPaul Traina break; 2324edb46e9SPaul Traina case 6: 2334edb46e9SPaul Traina (void)printf(" Graft"); 234a1c2090eSBill Fenner if (vflag) 235b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2364edb46e9SPaul Traina break; 2374edb46e9SPaul Traina case 7: 2384edb46e9SPaul Traina (void)printf(" Graft-ACK"); 239a1c2090eSBill Fenner if (vflag) 240b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2414edb46e9SPaul Traina break; 2424edb46e9SPaul Traina case 8: 2434edb46e9SPaul Traina (void)printf(" Mode"); 2444edb46e9SPaul Traina break; 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 260a1c2090eSBill Fenner * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt 261a1c2090eSBill Fenner * 262a1c2090eSBill Fenner * This implements version 1+, dated Sept 9, 1998. 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 } 331a1c2090eSBill Fenner if (bp[4] & 0xfc) 332a1c2090eSBill Fenner (void)printf(" [rsvd=0x%02x]", bp[4] & 0xfc); 333b0453382SBill Fenner TCHECK(bp[5]); 334b0453382SBill Fenner nentries = bp[5]; 335b0453382SBill Fenner bp += 6; len -= 6; 336b0453382SBill Fenner s = ' '; 337b0453382SBill Fenner for (; nentries; nentries--) { 338b0453382SBill Fenner TCHECK2(bp[0], 6); 339b0453382SBill Fenner (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "", 340b0453382SBill Fenner ipaddr_string(&bp[2]), bp[1]); 341a1c2090eSBill Fenner if (bp[0] & 0xfe) 342a1c2090eSBill Fenner (void)printf("[rsvd=0x%02x]", bp[0] & 0xfe); 343b0453382SBill Fenner s = ','; 344b0453382SBill Fenner bp += 6; len -= 6; 345b0453382SBill Fenner } 346b0453382SBill Fenner } 347b0453382SBill Fenner return; 348b0453382SBill Fenner 349b0453382SBill Fenner trunc: 350b0453382SBill Fenner (void)printf("[|autorp]"); 351b0453382SBill Fenner return; 352b0453382SBill Fenner } 353b0453382SBill Fenner 354b0453382SBill Fenner void 355b0453382SBill Fenner pim_print(register const u_char *bp, register u_int len) 356b0453382SBill Fenner { 357b0453382SBill Fenner register const u_char *ep; 358b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 359b0453382SBill Fenner 360b0453382SBill Fenner ep = (const u_char *)snapend; 361b0453382SBill Fenner if (bp >= ep) 362b0453382SBill Fenner return; 363b0453382SBill Fenner #ifdef notyet /* currently we see only version and type */ 364b0453382SBill Fenner TCHECK(pim->pim_rsv); 365b0453382SBill Fenner #endif 366b0453382SBill Fenner 367b0453382SBill Fenner switch (PIM_VER(pim->pim_typever)) { 368b0453382SBill Fenner case 2: /* avoid hardcoding? */ 3699537d84eSBill Fenner (void)printf("pim v2"); 370b0453382SBill Fenner pimv2_print(bp, len); 371b0453382SBill Fenner break; 372b0453382SBill Fenner default: 3739537d84eSBill Fenner (void)printf("pim v%d", PIM_VER(pim->pim_typever)); 374b0453382SBill Fenner break; 375b0453382SBill Fenner } 376b0453382SBill Fenner return; 377b0453382SBill Fenner } 378b0453382SBill Fenner 379b0453382SBill Fenner /* 380b0453382SBill Fenner * PIMv2 uses encoded address representations. 381b0453382SBill Fenner * 382b0453382SBill Fenner * The last PIM-SM I-D before RFC2117 was published specified the 383b0453382SBill Fenner * following representation for unicast addresses. However, RFC2117 384b0453382SBill Fenner * specified no encoding for unicast addresses with the unicast 385b0453382SBill Fenner * address length specified in the header. Therefore, we have to 386b0453382SBill Fenner * guess which encoding is being used (Cisco's PIMv2 implementation 387b0453382SBill Fenner * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" 388b0453382SBill Fenner * field into a 'unicast-address-length-in-bytes' field. We guess 389b0453382SBill Fenner * that it's the draft encoding if this reserved field is zero. 390b0453382SBill Fenner * 391b0453382SBill Fenner * RFC2362 goes back to the encoded format, and calls the addr length 392b0453382SBill Fenner * field "reserved" again. 393b0453382SBill Fenner * 394b0453382SBill Fenner * The first byte is the address family, from: 395b0453382SBill Fenner * 396b0453382SBill Fenner * 0 Reserved 397b0453382SBill Fenner * 1 IP (IP version 4) 398b0453382SBill Fenner * 2 IP6 (IP version 6) 399b0453382SBill Fenner * 3 NSAP 400b0453382SBill Fenner * 4 HDLC (8-bit multidrop) 401b0453382SBill Fenner * 5 BBN 1822 402b0453382SBill Fenner * 6 802 (includes all 802 media plus Ethernet "canonical format") 403b0453382SBill Fenner * 7 E.163 404b0453382SBill Fenner * 8 E.164 (SMDS, Frame Relay, ATM) 405b0453382SBill Fenner * 9 F.69 (Telex) 406b0453382SBill Fenner * 10 X.121 (X.25, Frame Relay) 407b0453382SBill Fenner * 11 IPX 408b0453382SBill Fenner * 12 Appletalk 409b0453382SBill Fenner * 13 Decnet IV 410b0453382SBill Fenner * 14 Banyan Vines 411b0453382SBill Fenner * 15 E.164 with NSAP format subaddress 412b0453382SBill Fenner * 413b0453382SBill Fenner * In addition, the second byte is an "Encoding". 0 is the default 414b0453382SBill Fenner * encoding for the address family, and no other encodings are currently 415b0453382SBill Fenner * specified. 416b0453382SBill Fenner * 417b0453382SBill Fenner */ 418b0453382SBill Fenner 419b0453382SBill Fenner static int pimv2_addr_len; 420b0453382SBill Fenner 421b0453382SBill Fenner enum pimv2_addrtype { 422b0453382SBill Fenner pimv2_unicast, pimv2_group, pimv2_source 423b0453382SBill Fenner }; 424b0453382SBill Fenner 425b0453382SBill Fenner /* 0 1 2 3 426b0453382SBill 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 427b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 428b0453382SBill Fenner * | Addr Family | Encoding Type | Unicast Address | 429b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ 430b0453382SBill Fenner * 0 1 2 3 431b0453382SBill 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 432b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 433b0453382SBill Fenner * | Addr Family | Encoding Type | Reserved | Mask Len | 434b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 435b0453382SBill Fenner * | Group multicast Address | 436b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 437b0453382SBill Fenner * 0 1 2 3 438b0453382SBill 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 439b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 440b0453382SBill Fenner * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | 441b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 442b0453382SBill Fenner * | Source Address | 443b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 444b0453382SBill Fenner */ 445b0453382SBill Fenner static int 446b0453382SBill Fenner pimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent) 447b0453382SBill Fenner { 448b0453382SBill Fenner int af; 449cc391cceSBruce M Simpson const char *afstr; 450b0453382SBill Fenner int len, hdrlen; 451b0453382SBill Fenner 452b0453382SBill Fenner TCHECK(bp[0]); 453b0453382SBill Fenner 454b0453382SBill Fenner if (pimv2_addr_len == 0) { 455b0453382SBill Fenner TCHECK(bp[1]); 456b0453382SBill Fenner switch (bp[0]) { 457b0453382SBill Fenner case 1: 458b0453382SBill Fenner af = AF_INET; 459b0453382SBill Fenner afstr = "IPv4"; 460b0453382SBill Fenner len = 4; 461b0453382SBill Fenner break; 462b0453382SBill Fenner #ifdef INET6 463b0453382SBill Fenner case 2: 464b0453382SBill Fenner af = AF_INET6; 465b0453382SBill Fenner afstr = "IPv6"; 466b0453382SBill Fenner len = 16; 467b0453382SBill Fenner break; 468b0453382SBill Fenner #endif 469b0453382SBill Fenner default: 470b0453382SBill Fenner return -1; 471b0453382SBill Fenner } 472b0453382SBill Fenner if (bp[1] != 0) 473b0453382SBill Fenner return -1; 474b0453382SBill Fenner hdrlen = 2; 475b0453382SBill Fenner } else { 476b0453382SBill Fenner switch (pimv2_addr_len) { 477b0453382SBill Fenner case 4: 478b0453382SBill Fenner af = AF_INET; 479b0453382SBill Fenner afstr = "IPv4"; 480b0453382SBill Fenner break; 481b0453382SBill Fenner #ifdef INET6 482b0453382SBill Fenner case 16: 483b0453382SBill Fenner af = AF_INET6; 484b0453382SBill Fenner afstr = "IPv6"; 485b0453382SBill Fenner break; 486b0453382SBill Fenner #endif 487b0453382SBill Fenner default: 488b0453382SBill Fenner return -1; 489b0453382SBill Fenner break; 490b0453382SBill Fenner } 491b0453382SBill Fenner len = pimv2_addr_len; 492b0453382SBill Fenner hdrlen = 0; 493b0453382SBill Fenner } 494b0453382SBill Fenner 495b0453382SBill Fenner bp += hdrlen; 496b0453382SBill Fenner switch (at) { 497b0453382SBill Fenner case pimv2_unicast: 498b0453382SBill Fenner TCHECK2(bp[0], len); 499b0453382SBill Fenner if (af == AF_INET) { 500b0453382SBill Fenner if (!silent) 501b0453382SBill Fenner (void)printf("%s", ipaddr_string(bp)); 502b0453382SBill Fenner } 503b0453382SBill Fenner #ifdef INET6 504b0453382SBill Fenner else if (af == AF_INET6) { 505b0453382SBill Fenner if (!silent) 506b0453382SBill Fenner (void)printf("%s", ip6addr_string(bp)); 507b0453382SBill Fenner } 508b0453382SBill Fenner #endif 509b0453382SBill Fenner return hdrlen + len; 510b0453382SBill Fenner case pimv2_group: 511b0453382SBill Fenner case pimv2_source: 512b0453382SBill Fenner TCHECK2(bp[0], len + 2); 513b0453382SBill Fenner if (af == AF_INET) { 514b0453382SBill Fenner if (!silent) { 515b0453382SBill Fenner (void)printf("%s", ipaddr_string(bp + 2)); 516b0453382SBill Fenner if (bp[1] != 32) 517b0453382SBill Fenner (void)printf("/%u", bp[1]); 518b0453382SBill Fenner } 519b0453382SBill Fenner } 520b0453382SBill Fenner #ifdef INET6 521b0453382SBill Fenner else if (af == AF_INET6) { 522b0453382SBill Fenner if (!silent) { 523b0453382SBill Fenner (void)printf("%s", ip6addr_string(bp + 2)); 524b0453382SBill Fenner if (bp[1] != 128) 525b0453382SBill Fenner (void)printf("/%u", bp[1]); 526b0453382SBill Fenner } 527b0453382SBill Fenner } 528b0453382SBill Fenner #endif 529b0453382SBill Fenner if (bp[0] && !silent) { 530b0453382SBill Fenner if (at == pimv2_group) { 531b0453382SBill Fenner (void)printf("(0x%02x)", bp[0]); 532b0453382SBill Fenner } else { 533b0453382SBill Fenner (void)printf("(%s%s%s", 534b0453382SBill Fenner bp[0] & 0x04 ? "S" : "", 535b0453382SBill Fenner bp[0] & 0x02 ? "W" : "", 536b0453382SBill Fenner bp[0] & 0x01 ? "R" : ""); 537b0453382SBill Fenner if (bp[0] & 0xf8) { 538b0453382SBill Fenner (void) printf("+0x%02x", bp[0] & 0xf8); 539b0453382SBill Fenner } 540b0453382SBill Fenner (void)printf(")"); 541b0453382SBill Fenner } 542b0453382SBill Fenner } 543b0453382SBill Fenner return hdrlen + 2 + len; 544b0453382SBill Fenner default: 545b0453382SBill Fenner return -1; 546b0453382SBill Fenner } 547b0453382SBill Fenner trunc: 548b0453382SBill Fenner return -1; 549b0453382SBill Fenner } 550b0453382SBill Fenner 551b0453382SBill Fenner static void 552b0453382SBill Fenner pimv2_print(register const u_char *bp, register u_int len) 553b0453382SBill Fenner { 554b0453382SBill Fenner register const u_char *ep; 555b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 556b0453382SBill Fenner int advance; 557b0453382SBill Fenner 558b0453382SBill Fenner ep = (const u_char *)snapend; 559b0453382SBill Fenner if (bp >= ep) 560b0453382SBill Fenner return; 5619537d84eSBill Fenner if (ep > bp + len) 5629537d84eSBill Fenner ep = bp + len; 563b0453382SBill Fenner TCHECK(pim->pim_rsv); 564b0453382SBill Fenner pimv2_addr_len = pim->pim_rsv; 565b0453382SBill Fenner if (pimv2_addr_len != 0) 566b0453382SBill Fenner (void)printf("[RFC2117-encoding] "); 567b0453382SBill Fenner 568b0453382SBill Fenner switch (PIM_TYPE(pim->pim_typever)) { 569b0453382SBill Fenner case 0: 570b0453382SBill Fenner { 571b0453382SBill Fenner u_int16_t otype, olen; 572b0453382SBill Fenner (void)printf(" Hello"); 573b0453382SBill Fenner bp += 4; 574b0453382SBill Fenner while (bp < ep) { 575b0453382SBill Fenner TCHECK2(bp[0], 4); 576b0453382SBill Fenner otype = EXTRACT_16BITS(&bp[0]); 577b0453382SBill Fenner olen = EXTRACT_16BITS(&bp[2]); 578b0453382SBill Fenner TCHECK2(bp[0], 4 + olen); 579b0453382SBill Fenner switch (otype) { 580b0453382SBill Fenner case 1: /* Hold time */ 581b0453382SBill Fenner (void)printf(" (Hold-time "); 582b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[4])); 583b0453382SBill Fenner (void)printf(")"); 584b0453382SBill Fenner break; 585b0453382SBill Fenner 586cc391cceSBruce M Simpson case 2: /* LAN Prune Delay */ 587cc391cceSBruce M Simpson (void)printf(" (LAN-Prune-Delay: "); 588cc391cceSBruce M Simpson if (olen != 4) { 589cc391cceSBruce M Simpson (void)printf("!olen=%d!)", olen); 590cc391cceSBruce M Simpson } else { 591cc391cceSBruce M Simpson char t_bit; 592cc391cceSBruce M Simpson u_int16_t lan_delay, override_interval; 593cc391cceSBruce M Simpson lan_delay = EXTRACT_16BITS(&bp[4]); 594cc391cceSBruce M Simpson override_interval = EXTRACT_16BITS(&bp[6]); 595cc391cceSBruce M Simpson t_bit = (lan_delay & 0x8000)? 1 : 0; 596cc391cceSBruce M Simpson lan_delay &= ~0x8000; 597cc391cceSBruce M Simpson (void)printf("T-bit=%d lan-delay=%dms override-interval=%dms)", 598cc391cceSBruce M Simpson t_bit, lan_delay, override_interval); 599cc391cceSBruce M Simpson } 600cc391cceSBruce M Simpson break; 601cc391cceSBruce M Simpson 6020e0def19SBill Fenner case 18: /* Old DR-Priority */ 6030e0def19SBill Fenner if (olen == 4) 6040e0def19SBill Fenner (void)printf(" (OLD-DR-Priority: %d)", 6050e0def19SBill Fenner EXTRACT_32BITS(&bp[4])); 6060e0def19SBill Fenner else 6070e0def19SBill Fenner goto unknown; 6080e0def19SBill Fenner break; 6090e0def19SBill Fenner 6100e0def19SBill Fenner 611a1c2090eSBill Fenner case 19: /* DR-Priority */ 6120e0def19SBill Fenner if (olen == 0) { 6130e0def19SBill Fenner (void)printf(" (OLD-bidir-capable)"); 6140e0def19SBill Fenner break; 6150e0def19SBill Fenner } 616a1c2090eSBill Fenner (void)printf(" (DR-Priority: "); 617a1c2090eSBill Fenner if (olen != 4) { 618a1c2090eSBill Fenner (void)printf("!olen=%d!)", olen); 619a1c2090eSBill Fenner } else { 620a1c2090eSBill Fenner (void)printf("%d)", EXTRACT_32BITS(&bp[4])); 621a1c2090eSBill Fenner } 622b0453382SBill Fenner break; 623b0453382SBill Fenner 624b0453382SBill Fenner case 20: 625b0453382SBill Fenner (void)printf(" (Genid: 0x%08x)", EXTRACT_32BITS(&bp[4])); 626b0453382SBill Fenner break; 627b0453382SBill Fenner 628b0453382SBill Fenner case 21: 629a1c2090eSBill Fenner (void)printf(" (State Refresh Capable; v%d", bp[4]); 630a1c2090eSBill Fenner if (bp[5] != 0) { 631a1c2090eSBill Fenner (void)printf(" interval "); 632a1c2090eSBill Fenner relts_print(bp[5]); 633a1c2090eSBill Fenner } 634a1c2090eSBill Fenner if (EXTRACT_16BITS(&bp[6]) != 0) { 635a1c2090eSBill Fenner (void)printf(" ?0x%04x?", EXTRACT_16BITS(&bp[6])); 636b0453382SBill Fenner } 637b0453382SBill Fenner (void)printf(")"); 638b0453382SBill Fenner break; 639b0453382SBill Fenner 640a1c2090eSBill Fenner case 22: /* Bidir-Capable */ 641a1c2090eSBill Fenner (void)printf(" (bidir-capable)"); 642a1c2090eSBill Fenner break; 643a1c2090eSBill Fenner 644cc391cceSBruce M Simpson case 24: /* Address List */ 645cc391cceSBruce M Simpson case 65001: /* Address List (old implementations) */ 646cc391cceSBruce M Simpson (void)printf(" (%saddr-list", 647cc391cceSBruce M Simpson otype == 65001 ? "old" : ""); 648cc391cceSBruce M Simpson if (vflag > 1) { 649cc391cceSBruce M Simpson const u_char *ptr = &bp[4]; 650cc391cceSBruce M Simpson while (ptr < &bp[4 + olen]) { 651cc391cceSBruce M Simpson int advance; 652cc391cceSBruce M Simpson 653cc391cceSBruce M Simpson printf(" "); 654cc391cceSBruce M Simpson advance = pimv2_addr_print(ptr, pimv2_unicast, 0); 655cc391cceSBruce M Simpson if (advance < 0) { 656cc391cceSBruce M Simpson printf("..."); 657cc391cceSBruce M Simpson break; 658cc391cceSBruce M Simpson } 659cc391cceSBruce M Simpson ptr += advance; 660cc391cceSBruce M Simpson } 661cc391cceSBruce M Simpson } 662cc391cceSBruce M Simpson (void)printf(")"); 663cc391cceSBruce M Simpson break; 664b0453382SBill Fenner default: 6650e0def19SBill Fenner unknown: 666b0453382SBill Fenner if (vflag) 667b0453382SBill Fenner (void)printf(" [Hello option %d]", otype); 668b0453382SBill Fenner } 669b0453382SBill Fenner bp += 4 + olen; 670b0453382SBill Fenner } 671b0453382SBill Fenner break; 672b0453382SBill Fenner } 673b0453382SBill Fenner 674b0453382SBill Fenner case 1: 675b0453382SBill Fenner { 676b0453382SBill Fenner struct ip *ip; 677b0453382SBill Fenner 678b0453382SBill Fenner (void)printf(" Register"); 679b0453382SBill Fenner if (vflag && bp + 8 <= ep) { 680b0453382SBill Fenner (void)printf(" %s%s", bp[4] & 0x80 ? "B" : "", 681b0453382SBill Fenner bp[4] & 0x40 ? "N" : ""); 682b0453382SBill Fenner } 683b0453382SBill Fenner bp += 8; len -= 8; 684b0453382SBill Fenner 685b0453382SBill Fenner /* encapsulated multicast packet */ 686b0453382SBill Fenner if (bp >= ep) 687b0453382SBill Fenner break; 688b0453382SBill Fenner ip = (struct ip *)bp; 689943ee2b1SBill Fenner switch (IP_V(ip)) { 690b0453382SBill Fenner case 4: /* IPv4 */ 691b0453382SBill Fenner printf(" "); 692b0453382SBill Fenner ip_print(bp, len); 693b0453382SBill Fenner break; 694b0453382SBill Fenner #ifdef INET6 695b0453382SBill Fenner case 6: /* IPv6 */ 696b0453382SBill Fenner printf(" "); 697b0453382SBill Fenner ip6_print(bp, len); 698b0453382SBill Fenner break; 699b0453382SBill Fenner #endif 700b0453382SBill Fenner default: 701943ee2b1SBill Fenner (void)printf(" IP ver %d", IP_V(ip)); 702b0453382SBill Fenner break; 703b0453382SBill Fenner } 704b0453382SBill Fenner break; 705b0453382SBill Fenner } 706b0453382SBill Fenner 707b0453382SBill Fenner case 2: 708b0453382SBill Fenner (void)printf(" Register-Stop"); 709b0453382SBill Fenner bp += 4; len -= 4; 710b0453382SBill Fenner if (bp >= ep) 711b0453382SBill Fenner break; 712b0453382SBill Fenner (void)printf(" group="); 713b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 714b0453382SBill Fenner (void)printf("..."); 715b0453382SBill Fenner break; 716b0453382SBill Fenner } 717b0453382SBill Fenner bp += advance; len -= advance; 718b0453382SBill Fenner if (bp >= ep) 719b0453382SBill Fenner break; 720b0453382SBill Fenner (void)printf(" source="); 721b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 722b0453382SBill Fenner (void)printf("..."); 723b0453382SBill Fenner break; 724b0453382SBill Fenner } 725b0453382SBill Fenner bp += advance; len -= advance; 726b0453382SBill Fenner break; 727b0453382SBill Fenner 728b0453382SBill Fenner case 3: 729b0453382SBill Fenner case 6: 730b0453382SBill Fenner case 7: 731b0453382SBill Fenner { 732b0453382SBill Fenner u_int8_t ngroup; 733b0453382SBill Fenner u_int16_t holdtime; 734b0453382SBill Fenner u_int16_t njoin; 735b0453382SBill Fenner u_int16_t nprune; 736b0453382SBill Fenner int i, j; 737b0453382SBill Fenner 738b0453382SBill Fenner switch (PIM_TYPE(pim->pim_typever)) { 739b0453382SBill Fenner case 3: 740b0453382SBill Fenner (void)printf(" Join/Prune"); 741b0453382SBill Fenner break; 742b0453382SBill Fenner case 6: 743b0453382SBill Fenner (void)printf(" Graft"); 744b0453382SBill Fenner break; 745b0453382SBill Fenner case 7: 746b0453382SBill Fenner (void)printf(" Graft-ACK"); 747b0453382SBill Fenner break; 748b0453382SBill Fenner } 749b0453382SBill Fenner bp += 4; len -= 4; 750b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 751b0453382SBill Fenner if (bp >= ep) 752b0453382SBill Fenner break; 753b0453382SBill Fenner (void)printf(" upstream-neighbor="); 754b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 755b0453382SBill Fenner (void)printf("..."); 756b0453382SBill Fenner break; 757b0453382SBill Fenner } 758b0453382SBill Fenner bp += advance; len -= advance; 759b0453382SBill Fenner } 760b0453382SBill Fenner if (bp + 4 > ep) 761b0453382SBill Fenner break; 762b0453382SBill Fenner ngroup = bp[1]; 763b0453382SBill Fenner holdtime = EXTRACT_16BITS(&bp[2]); 764b0453382SBill Fenner (void)printf(" groups=%u", ngroup); 765b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 766b0453382SBill Fenner (void)printf(" holdtime="); 767b0453382SBill Fenner if (holdtime == 0xffff) 768b0453382SBill Fenner (void)printf("infty"); 769b0453382SBill Fenner else 770b0453382SBill Fenner relts_print(holdtime); 771b0453382SBill Fenner } 772b0453382SBill Fenner bp += 4; len -= 4; 773b0453382SBill Fenner for (i = 0; i < ngroup; i++) { 774b0453382SBill Fenner if (bp >= ep) 775b0453382SBill Fenner goto jp_done; 776b0453382SBill Fenner (void)printf(" (group%d: ", i); 777b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 778b0453382SBill Fenner (void)printf("...)"); 779b0453382SBill Fenner goto jp_done; 780b0453382SBill Fenner } 781b0453382SBill Fenner bp += advance; len -= advance; 782b0453382SBill Fenner if (bp + 4 > ep) { 783b0453382SBill Fenner (void)printf("...)"); 784b0453382SBill Fenner goto jp_done; 785b0453382SBill Fenner } 786b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[0]); 787b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[2]); 788b0453382SBill Fenner (void)printf(" join=%u", njoin); 789b0453382SBill Fenner bp += 4; len -= 4; 790b0453382SBill Fenner for (j = 0; j < njoin; j++) { 791b0453382SBill Fenner (void)printf(" "); 792b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { 793b0453382SBill Fenner (void)printf("...)"); 794b0453382SBill Fenner goto jp_done; 795b0453382SBill Fenner } 796b0453382SBill Fenner bp += advance; len -= advance; 797b0453382SBill Fenner } 798b0453382SBill Fenner (void)printf(" prune=%u", nprune); 799b0453382SBill Fenner for (j = 0; j < nprune; j++) { 800b0453382SBill Fenner (void)printf(" "); 801b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { 802b0453382SBill Fenner (void)printf("...)"); 803b0453382SBill Fenner goto jp_done; 804b0453382SBill Fenner } 805b0453382SBill Fenner bp += advance; len -= advance; 806b0453382SBill Fenner } 807b0453382SBill Fenner (void)printf(")"); 808b0453382SBill Fenner } 809b0453382SBill Fenner jp_done: 810b0453382SBill Fenner break; 811b0453382SBill Fenner } 812b0453382SBill Fenner 813b0453382SBill Fenner case 4: 814b0453382SBill Fenner { 815b0453382SBill Fenner int i, j, frpcnt; 816b0453382SBill Fenner 817b0453382SBill Fenner (void)printf(" Bootstrap"); 818b0453382SBill Fenner bp += 4; 819b0453382SBill Fenner 820b0453382SBill Fenner /* Fragment Tag, Hash Mask len, and BSR-priority */ 821b0453382SBill Fenner if (bp + sizeof(u_int16_t) >= ep) break; 822b0453382SBill Fenner (void)printf(" tag=%x", EXTRACT_16BITS(bp)); 823b0453382SBill Fenner bp += sizeof(u_int16_t); 824b0453382SBill Fenner if (bp >= ep) break; 825b0453382SBill Fenner (void)printf(" hashmlen=%d", bp[0]); 826b0453382SBill Fenner if (bp + 1 >= ep) break; 827b0453382SBill Fenner (void)printf(" BSRprio=%d", bp[1]); 828b0453382SBill Fenner bp += 2; 829b0453382SBill Fenner 830b0453382SBill Fenner /* Encoded-Unicast-BSR-Address */ 831b0453382SBill Fenner if (bp >= ep) break; 832b0453382SBill Fenner (void)printf(" BSR="); 833b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 834b0453382SBill Fenner (void)printf("..."); 835b0453382SBill Fenner break; 836b0453382SBill Fenner } 837b0453382SBill Fenner bp += advance; 838b0453382SBill Fenner 839b0453382SBill Fenner for (i = 0; bp < ep; i++) { 840b0453382SBill Fenner /* Encoded-Group Address */ 841b0453382SBill Fenner (void)printf(" (group%d: ", i); 842b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) 843b0453382SBill Fenner < 0) { 844b0453382SBill Fenner (void)printf("...)"); 845b0453382SBill Fenner goto bs_done; 846b0453382SBill Fenner } 847b0453382SBill Fenner bp += advance; 848b0453382SBill Fenner 849b0453382SBill Fenner /* RP-Count, Frag RP-Cnt, and rsvd */ 850b0453382SBill Fenner if (bp >= ep) { 851b0453382SBill Fenner (void)printf("...)"); 852b0453382SBill Fenner goto bs_done; 853b0453382SBill Fenner } 854943ee2b1SBill Fenner (void)printf(" RPcnt=%d", bp[0]); 855b0453382SBill Fenner if (bp + 1 >= ep) { 856b0453382SBill Fenner (void)printf("...)"); 857b0453382SBill Fenner goto bs_done; 858b0453382SBill Fenner } 859943ee2b1SBill Fenner (void)printf(" FRPcnt=%d", frpcnt = bp[1]); 860b0453382SBill Fenner bp += 4; 861b0453382SBill Fenner 862b0453382SBill Fenner for (j = 0; j < frpcnt && bp < ep; j++) { 863b0453382SBill Fenner /* each RP info */ 864b0453382SBill Fenner (void)printf(" RP%d=", j); 865b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, 866b0453382SBill Fenner pimv2_unicast, 867b0453382SBill Fenner 0)) < 0) { 868b0453382SBill Fenner (void)printf("...)"); 869b0453382SBill Fenner goto bs_done; 870b0453382SBill Fenner } 871b0453382SBill Fenner bp += advance; 872b0453382SBill Fenner 873b0453382SBill Fenner if (bp + 1 >= ep) { 874b0453382SBill Fenner (void)printf("...)"); 875b0453382SBill Fenner goto bs_done; 876b0453382SBill Fenner } 877b0453382SBill Fenner (void)printf(",holdtime="); 878b0453382SBill Fenner relts_print(EXTRACT_16BITS(bp)); 879b0453382SBill Fenner if (bp + 2 >= ep) { 880b0453382SBill Fenner (void)printf("...)"); 881b0453382SBill Fenner goto bs_done; 882b0453382SBill Fenner } 883b0453382SBill Fenner (void)printf(",prio=%d", bp[2]); 884b0453382SBill Fenner bp += 4; 885b0453382SBill Fenner } 886b0453382SBill Fenner (void)printf(")"); 887b0453382SBill Fenner } 888b0453382SBill Fenner bs_done: 889b0453382SBill Fenner break; 890b0453382SBill Fenner } 891b0453382SBill Fenner case 5: 892b0453382SBill Fenner (void)printf(" Assert"); 893b0453382SBill Fenner bp += 4; len -= 4; 894b0453382SBill Fenner if (bp >= ep) 895b0453382SBill Fenner break; 896b0453382SBill Fenner (void)printf(" group="); 897b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 898b0453382SBill Fenner (void)printf("..."); 899b0453382SBill Fenner break; 900b0453382SBill Fenner } 901b0453382SBill Fenner bp += advance; len -= advance; 902b0453382SBill Fenner if (bp >= ep) 903b0453382SBill Fenner break; 904b0453382SBill Fenner (void)printf(" src="); 905b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 906b0453382SBill Fenner (void)printf("..."); 907b0453382SBill Fenner break; 908b0453382SBill Fenner } 909b0453382SBill Fenner bp += advance; len -= advance; 910b0453382SBill Fenner if (bp + 8 > ep) 911b0453382SBill Fenner break; 912b0453382SBill Fenner if (bp[0] & 0x80) 913b0453382SBill Fenner (void)printf(" RPT"); 914b0453382SBill Fenner (void)printf(" pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff); 915b0453382SBill Fenner (void)printf(" metric=%u", EXTRACT_32BITS(&bp[4])); 916b0453382SBill Fenner break; 917b0453382SBill Fenner 918b0453382SBill Fenner case 8: 919b0453382SBill Fenner { 920b0453382SBill Fenner int i, pfxcnt; 921b0453382SBill Fenner 922b0453382SBill Fenner (void)printf(" Candidate-RP-Advertisement"); 923b0453382SBill Fenner bp += 4; 924b0453382SBill Fenner 925b0453382SBill Fenner /* Prefix-Cnt, Priority, and Holdtime */ 926b0453382SBill Fenner if (bp >= ep) break; 927b0453382SBill Fenner (void)printf(" prefix-cnt=%d", bp[0]); 928b0453382SBill Fenner pfxcnt = bp[0]; 929b0453382SBill Fenner if (bp + 1 >= ep) break; 930b0453382SBill Fenner (void)printf(" prio=%d", bp[1]); 931b0453382SBill Fenner if (bp + 3 >= ep) break; 932b0453382SBill Fenner (void)printf(" holdtime="); 933b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[2])); 934b0453382SBill Fenner bp += 4; 935b0453382SBill Fenner 936b0453382SBill Fenner /* Encoded-Unicast-RP-Address */ 937b0453382SBill Fenner if (bp >= ep) break; 938b0453382SBill Fenner (void)printf(" RP="); 939b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 940b0453382SBill Fenner (void)printf("..."); 941b0453382SBill Fenner break; 942b0453382SBill Fenner } 943b0453382SBill Fenner bp += advance; 944b0453382SBill Fenner 945b0453382SBill Fenner /* Encoded-Group Addresses */ 946b0453382SBill Fenner for (i = 0; i < pfxcnt && bp < ep; i++) { 947b0453382SBill Fenner (void)printf(" Group%d=", i); 948b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) 949b0453382SBill Fenner < 0) { 950b0453382SBill Fenner (void)printf("..."); 951b0453382SBill Fenner break; 952b0453382SBill Fenner } 953b0453382SBill Fenner bp += advance; 954b0453382SBill Fenner } 955b0453382SBill Fenner break; 956b0453382SBill Fenner } 957b0453382SBill Fenner 958b0453382SBill Fenner case 9: 959b0453382SBill Fenner (void)printf(" Prune-Refresh"); 960b0453382SBill Fenner (void)printf(" src="); 961b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 962b0453382SBill Fenner (void)printf("..."); 963b0453382SBill Fenner break; 964b0453382SBill Fenner } 965b0453382SBill Fenner bp += advance; 966b0453382SBill Fenner (void)printf(" grp="); 967b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 968b0453382SBill Fenner (void)printf("..."); 969b0453382SBill Fenner break; 970b0453382SBill Fenner } 971b0453382SBill Fenner bp += advance; 972b0453382SBill Fenner (void)printf(" forwarder="); 973b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 974b0453382SBill Fenner (void)printf("..."); 975b0453382SBill Fenner break; 976b0453382SBill Fenner } 977b0453382SBill Fenner bp += advance; 978b0453382SBill Fenner TCHECK2(bp[0], 2); 979b0453382SBill Fenner (void)printf(" TUNR "); 980b0453382SBill Fenner relts_print(EXTRACT_16BITS(bp)); 981b0453382SBill Fenner break; 982b0453382SBill Fenner 983b0453382SBill Fenner 984b0453382SBill Fenner default: 985b0453382SBill Fenner (void)printf(" [type %d]", PIM_TYPE(pim->pim_typever)); 986b0453382SBill Fenner break; 987b0453382SBill Fenner } 988b0453382SBill Fenner 989b0453382SBill Fenner return; 990b0453382SBill Fenner 991b0453382SBill Fenner trunc: 992b0453382SBill Fenner (void)printf("[|pim]"); 9934edb46e9SPaul Traina } 994