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_ = 26abf25193SMax Laier "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.45.2.4 2006/02/13 01:32:34 hannes 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> 34c1ad1296SSam Leffler #include "interface.h" 35c1ad1296SSam Leffler 36c1ad1296SSam Leffler #define PIMV2_TYPE_HELLO 0 37c1ad1296SSam Leffler #define PIMV2_TYPE_REGISTER 1 38c1ad1296SSam Leffler #define PIMV2_TYPE_REGISTER_STOP 2 39c1ad1296SSam Leffler #define PIMV2_TYPE_JOIN_PRUNE 3 40c1ad1296SSam Leffler #define PIMV2_TYPE_BOOTSTRAP 4 41c1ad1296SSam Leffler #define PIMV2_TYPE_ASSERT 5 42c1ad1296SSam Leffler #define PIMV2_TYPE_GRAFT 6 43c1ad1296SSam Leffler #define PIMV2_TYPE_GRAFT_ACK 7 44c1ad1296SSam Leffler #define PIMV2_TYPE_CANDIDATE_RP 8 45c1ad1296SSam Leffler #define PIMV2_TYPE_PRUNE_REFRESH 9 46c1ad1296SSam Leffler 47c1ad1296SSam Leffler static struct tok pimv2_type_values[] = { 48c1ad1296SSam Leffler { PIMV2_TYPE_HELLO, "Hello" }, 49c1ad1296SSam Leffler { PIMV2_TYPE_REGISTER, "Register" }, 50c1ad1296SSam Leffler { PIMV2_TYPE_REGISTER_STOP, "Register Stop" }, 51c1ad1296SSam Leffler { PIMV2_TYPE_JOIN_PRUNE, "Join / Prune" }, 52c1ad1296SSam Leffler { PIMV2_TYPE_BOOTSTRAP, "Bootstrap" }, 53c1ad1296SSam Leffler { PIMV2_TYPE_ASSERT, "Assert" }, 54c1ad1296SSam Leffler { PIMV2_TYPE_GRAFT, "Graft" }, 55c1ad1296SSam Leffler { PIMV2_TYPE_GRAFT_ACK, "Graft Acknowledgement" }, 56c1ad1296SSam Leffler { PIMV2_TYPE_CANDIDATE_RP, "Candidate RP Advertisement" }, 57c1ad1296SSam Leffler { PIMV2_TYPE_PRUNE_REFRESH, "Prune Refresh" }, 58c1ad1296SSam Leffler { 0, NULL} 59c1ad1296SSam Leffler }; 60c1ad1296SSam Leffler 61c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_HOLDTIME 1 62c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_LANPRUNEDELAY 2 63c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_DR_PRIORITY_OLD 18 64c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_DR_PRIORITY 19 65c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_GENID 20 66c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_REFRESH_CAP 21 67c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_BIDIR_CAP 22 68c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_ADDRESS_LIST 24 69c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD 65001 70c1ad1296SSam Leffler 71c1ad1296SSam Leffler static struct tok pimv2_hello_option_values[] = { 72c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_HOLDTIME, "Hold Time" }, 73c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_LANPRUNEDELAY, "LAN Prune Delay" }, 74c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_DR_PRIORITY_OLD, "DR Priority (Old)" }, 75c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_DR_PRIORITY, "DR Priority" }, 76c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_GENID, "Generation ID" }, 77c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_REFRESH_CAP, "State Refresh Capability" }, 78c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_BIDIR_CAP, "Bi-Directional Capability" }, 79c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_ADDRESS_LIST, "Address List" }, 80c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD, "Address List (Old)" }, 81c1ad1296SSam Leffler { 0, NULL} 82c1ad1296SSam Leffler }; 83c1ad1296SSam Leffler 84abf25193SMax Laier #define PIMV2_REGISTER_FLAG_LEN 4 85abf25193SMax Laier #define PIMV2_REGISTER_FLAG_BORDER 0x80000000 86abf25193SMax Laier #define PIMV2_REGISTER_FLAG_NULL 0x40000000 87abf25193SMax Laier 88abf25193SMax Laier static struct tok pimv2_register_flag_values[] = { 89abf25193SMax Laier { PIMV2_REGISTER_FLAG_BORDER, "Border" }, 90abf25193SMax Laier { PIMV2_REGISTER_FLAG_NULL, "Null" }, 91abf25193SMax Laier { 0, NULL} 92abf25193SMax Laier }; 93b0453382SBill Fenner 94b0453382SBill Fenner /* 95b0453382SBill Fenner * XXX: We consider a case where IPv6 is not ready yet for portability, 96b0453382SBill Fenner * but PIM dependent defintions should be independent of IPv6... 97b0453382SBill Fenner */ 98b0453382SBill Fenner 99b0453382SBill Fenner struct pim { 100b0453382SBill Fenner u_int8_t pim_typever; 1019537d84eSBill Fenner /* upper 4bit: PIM version number; 2 for PIMv2 */ 1029537d84eSBill Fenner /* lower 4bit: the PIM message type, currently they are: 103b0453382SBill Fenner * Hello, Register, Register-Stop, Join/Prune, 104b0453382SBill Fenner * Bootstrap, Assert, Graft (PIM-DM only), 105b0453382SBill Fenner * Graft-Ack (PIM-DM only), C-RP-Adv 106b0453382SBill Fenner */ 1079537d84eSBill Fenner #define PIM_VER(x) (((x) & 0xf0) >> 4) 1089537d84eSBill Fenner #define PIM_TYPE(x) ((x) & 0x0f) 109b0453382SBill Fenner u_char pim_rsv; /* Reserved */ 110b0453382SBill Fenner u_short pim_cksum; /* IP style check sum */ 111b0453382SBill Fenner }; 112b0453382SBill Fenner 1134edb46e9SPaul Traina 1144edb46e9SPaul Traina #include <stdio.h> 1154edb46e9SPaul Traina #include <stdlib.h> 1164edb46e9SPaul Traina 1174edb46e9SPaul Traina #include "interface.h" 1184edb46e9SPaul Traina #include "addrtoname.h" 119b0453382SBill Fenner #include "extract.h" 120b0453382SBill Fenner 121943ee2b1SBill Fenner #include "ip.h" 122943ee2b1SBill Fenner 123b0453382SBill Fenner static void pimv2_print(register const u_char *bp, register u_int len); 124b0453382SBill Fenner 125b0453382SBill Fenner static void 126b0453382SBill Fenner pimv1_join_prune_print(register const u_char *bp, register u_int len) 127b0453382SBill Fenner { 128b0453382SBill Fenner int maddrlen, addrlen, ngroups, njoin, nprune; 129b0453382SBill Fenner int njp; 130b0453382SBill Fenner 131b0453382SBill Fenner /* If it's a single group and a single source, use 1-line output. */ 132b0453382SBill Fenner if (TTEST2(bp[0], 30) && bp[11] == 1 && 133b0453382SBill Fenner ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { 134b0453382SBill Fenner int hold; 135b0453382SBill Fenner 136b0453382SBill Fenner (void)printf(" RPF %s ", ipaddr_string(bp)); 137b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[6]); 138b0453382SBill Fenner if (hold != 180) { 139b0453382SBill Fenner (void)printf("Hold "); 140b0453382SBill Fenner relts_print(hold); 141b0453382SBill Fenner } 142b0453382SBill Fenner (void)printf("%s (%s/%d, %s", njoin ? "Join" : "Prune", 143b0453382SBill Fenner ipaddr_string(&bp[26]), bp[25] & 0x3f, 144b0453382SBill Fenner ipaddr_string(&bp[12])); 145b0453382SBill Fenner if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) 146b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[16])); 147b0453382SBill Fenner (void)printf(") %s%s %s", 148b0453382SBill Fenner (bp[24] & 0x01) ? "Sparse" : "Dense", 149b0453382SBill Fenner (bp[25] & 0x80) ? " WC" : "", 150b0453382SBill Fenner (bp[25] & 0x40) ? "RP" : "SPT"); 151b0453382SBill Fenner return; 152b0453382SBill Fenner } 153b0453382SBill Fenner 15417cb103cSSam Leffler TCHECK2(bp[0], sizeof(struct in_addr)); 155a1c2090eSBill Fenner if (vflag > 1) 156a1c2090eSBill Fenner (void)printf("\n"); 157a1c2090eSBill Fenner (void)printf(" Upstream Nbr: %s", ipaddr_string(bp)); 158b0453382SBill Fenner TCHECK2(bp[6], 2); 159a1c2090eSBill Fenner if (vflag > 1) 160a1c2090eSBill Fenner (void)printf("\n"); 161a1c2090eSBill Fenner (void)printf(" Hold time: "); 162b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[6])); 163a1c2090eSBill Fenner if (vflag < 2) 164a1c2090eSBill Fenner return; 165a1c2090eSBill Fenner bp += 8; 166a1c2090eSBill Fenner len -= 8; 167b0453382SBill Fenner 168b0453382SBill Fenner TCHECK2(bp[0], 4); 169b0453382SBill Fenner maddrlen = bp[1]; 170b0453382SBill Fenner addrlen = bp[2]; 171b0453382SBill Fenner ngroups = bp[3]; 172a1c2090eSBill Fenner bp += 4; 173a1c2090eSBill Fenner len -= 4; 174b0453382SBill Fenner while (ngroups--) { 17529292c17SSam Leffler /* 17629292c17SSam Leffler * XXX - does the address have length "addrlen" and the 17729292c17SSam Leffler * mask length "maddrlen"? 17829292c17SSam Leffler */ 17917cb103cSSam Leffler TCHECK2(bp[0], sizeof(struct in_addr)); 180b0453382SBill Fenner (void)printf("\n\tGroup: %s", ipaddr_string(bp)); 18117cb103cSSam Leffler TCHECK2(bp[4], sizeof(struct in_addr)); 182b0453382SBill Fenner if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) 183b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[4])); 184b0453382SBill Fenner TCHECK2(bp[8], 4); 185b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[8]); 186b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[10]); 187b0453382SBill Fenner (void)printf(" joined: %d pruned: %d", njoin, nprune); 188a1c2090eSBill Fenner bp += 12; 189a1c2090eSBill Fenner len -= 12; 190b0453382SBill Fenner for (njp = 0; njp < (njoin + nprune); njp++) { 191cc391cceSBruce M Simpson const char *type; 192b0453382SBill Fenner 193a1c2090eSBill Fenner if (njp < njoin) 194b0453382SBill Fenner type = "Join "; 195a1c2090eSBill Fenner else 196b0453382SBill Fenner type = "Prune"; 197b0453382SBill Fenner TCHECK2(bp[0], 6); 198b0453382SBill Fenner (void)printf("\n\t%s %s%s%s%s/%d", type, 199b0453382SBill Fenner (bp[0] & 0x01) ? "Sparse " : "Dense ", 200b0453382SBill Fenner (bp[1] & 0x80) ? "WC " : "", 201b0453382SBill Fenner (bp[1] & 0x40) ? "RP " : "SPT ", 202b0453382SBill Fenner ipaddr_string(&bp[2]), bp[1] & 0x3f); 203a1c2090eSBill Fenner bp += 6; 204a1c2090eSBill Fenner len -= 6; 205b0453382SBill Fenner } 206b0453382SBill Fenner } 207b0453382SBill Fenner return; 208b0453382SBill Fenner trunc: 209b0453382SBill Fenner (void)printf("[|pim]"); 210b0453382SBill Fenner return; 211b0453382SBill Fenner } 2124edb46e9SPaul Traina 2134edb46e9SPaul Traina void 214b0453382SBill Fenner pimv1_print(register const u_char *bp, register u_int len) 2154edb46e9SPaul Traina { 2164edb46e9SPaul Traina register const u_char *ep; 2174edb46e9SPaul Traina register u_char type; 2184edb46e9SPaul Traina 2194edb46e9SPaul Traina ep = (const u_char *)snapend; 2204edb46e9SPaul Traina if (bp >= ep) 2214edb46e9SPaul Traina return; 2224edb46e9SPaul Traina 223cc391cceSBruce M Simpson TCHECK(bp[1]); 2244edb46e9SPaul Traina type = bp[1]; 2254edb46e9SPaul Traina 2264edb46e9SPaul Traina switch (type) { 2274edb46e9SPaul Traina case 0: 2284edb46e9SPaul Traina (void)printf(" Query"); 229b0453382SBill Fenner if (TTEST(bp[8])) { 230b0453382SBill Fenner switch (bp[8] >> 4) { 231a1c2090eSBill Fenner case 0: 232a1c2090eSBill Fenner (void)printf(" Dense-mode"); 233b0453382SBill Fenner break; 234a1c2090eSBill Fenner case 1: 235a1c2090eSBill Fenner (void)printf(" Sparse-mode"); 236b0453382SBill Fenner break; 237a1c2090eSBill Fenner case 2: 238a1c2090eSBill Fenner (void)printf(" Sparse-Dense-mode"); 239b0453382SBill Fenner break; 240a1c2090eSBill Fenner default: 241a1c2090eSBill Fenner (void)printf(" mode-%d", bp[8] >> 4); 242b0453382SBill Fenner break; 243b0453382SBill Fenner } 244b0453382SBill Fenner } 245b0453382SBill Fenner if (vflag) { 246b0453382SBill Fenner TCHECK2(bp[10],2); 247b0453382SBill Fenner (void)printf(" (Hold-time "); 248b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[10])); 249b0453382SBill Fenner (void)printf(")"); 250b0453382SBill Fenner } 2514edb46e9SPaul Traina break; 2524edb46e9SPaul Traina 2534edb46e9SPaul Traina case 1: 2544edb46e9SPaul Traina (void)printf(" Register"); 255b0453382SBill Fenner TCHECK2(bp[8], 20); /* ip header */ 256b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[20]), 257b0453382SBill Fenner ipaddr_string(&bp[24])); 2584edb46e9SPaul Traina break; 2594edb46e9SPaul Traina case 2: 2604edb46e9SPaul Traina (void)printf(" Register-Stop"); 26117cb103cSSam Leffler TCHECK2(bp[12], sizeof(struct in_addr)); 262b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[8]), 263b0453382SBill Fenner ipaddr_string(&bp[12])); 2644edb46e9SPaul Traina break; 2654edb46e9SPaul Traina case 3: 2664edb46e9SPaul Traina (void)printf(" Join/Prune"); 267a1c2090eSBill Fenner if (vflag) 268b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2694edb46e9SPaul Traina break; 2704edb46e9SPaul Traina case 4: 2714edb46e9SPaul Traina (void)printf(" RP-reachable"); 272b0453382SBill Fenner if (vflag) { 273b0453382SBill Fenner TCHECK2(bp[22], 2); 274b0453382SBill Fenner (void)printf(" group %s", 275b0453382SBill Fenner ipaddr_string(&bp[8])); 276b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 277b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[12])); 278a1c2090eSBill Fenner (void)printf(" RP %s hold ", ipaddr_string(&bp[16])); 279b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[22])); 280b0453382SBill Fenner } 2814edb46e9SPaul Traina break; 2824edb46e9SPaul Traina case 5: 2834edb46e9SPaul Traina (void)printf(" Assert"); 28417cb103cSSam Leffler TCHECK2(bp[16], sizeof(struct in_addr)); 285b0453382SBill Fenner (void)printf(" for %s > %s", ipaddr_string(&bp[16]), 286b0453382SBill Fenner ipaddr_string(&bp[8])); 287b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 288b0453382SBill Fenner (void)printf("/%s", ipaddr_string(&bp[12])); 289b0453382SBill Fenner TCHECK2(bp[24], 4); 290b0453382SBill Fenner (void)printf(" %s pref %d metric %d", 291b0453382SBill Fenner (bp[20] & 0x80) ? "RP-tree" : "SPT", 292b0453382SBill Fenner EXTRACT_32BITS(&bp[20]) & 0x7fffffff, 293b0453382SBill Fenner EXTRACT_32BITS(&bp[24])); 2944edb46e9SPaul Traina break; 2954edb46e9SPaul Traina case 6: 2964edb46e9SPaul Traina (void)printf(" Graft"); 297a1c2090eSBill Fenner if (vflag) 298b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 2994edb46e9SPaul Traina break; 3004edb46e9SPaul Traina case 7: 3014edb46e9SPaul Traina (void)printf(" Graft-ACK"); 302a1c2090eSBill Fenner if (vflag) 303b0453382SBill Fenner pimv1_join_prune_print(&bp[8], len - 8); 3044edb46e9SPaul Traina break; 3054edb46e9SPaul Traina case 8: 3064edb46e9SPaul Traina (void)printf(" Mode"); 3074edb46e9SPaul Traina break; 3084edb46e9SPaul Traina default: 3094edb46e9SPaul Traina (void)printf(" [type %d]", type); 3104edb46e9SPaul Traina break; 3114edb46e9SPaul Traina } 312b0453382SBill Fenner if ((bp[4] >> 4) != 1) 313b0453382SBill Fenner (void)printf(" [v%d]", bp[4] >> 4); 314b0453382SBill Fenner return; 315b0453382SBill Fenner 316b0453382SBill Fenner trunc: 317b0453382SBill Fenner (void)printf("[|pim]"); 318b0453382SBill Fenner return; 319b0453382SBill Fenner } 320b0453382SBill Fenner 321b0453382SBill Fenner /* 322b0453382SBill Fenner * auto-RP is a cisco protocol, documented at 323a1c2090eSBill Fenner * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt 324a1c2090eSBill Fenner * 325a1c2090eSBill Fenner * This implements version 1+, dated Sept 9, 1998. 326b0453382SBill Fenner */ 327b0453382SBill Fenner void 328b0453382SBill Fenner cisco_autorp_print(register const u_char *bp, register u_int len) 329b0453382SBill Fenner { 330b0453382SBill Fenner int type; 331b0453382SBill Fenner int numrps; 332b0453382SBill Fenner int hold; 333b0453382SBill Fenner 334b0453382SBill Fenner TCHECK(bp[0]); 335b0453382SBill Fenner (void)printf(" auto-rp "); 336b0453382SBill Fenner type = bp[0]; 337b0453382SBill Fenner switch (type) { 338b0453382SBill Fenner case 0x11: 339b0453382SBill Fenner (void)printf("candidate-advert"); 340b0453382SBill Fenner break; 341b0453382SBill Fenner case 0x12: 342b0453382SBill Fenner (void)printf("mapping"); 343b0453382SBill Fenner break; 344b0453382SBill Fenner default: 345b0453382SBill Fenner (void)printf("type-0x%02x", type); 346b0453382SBill Fenner break; 347b0453382SBill Fenner } 348b0453382SBill Fenner 349b0453382SBill Fenner TCHECK(bp[1]); 350b0453382SBill Fenner numrps = bp[1]; 351b0453382SBill Fenner 352b0453382SBill Fenner TCHECK2(bp[2], 2); 353b0453382SBill Fenner (void)printf(" Hold "); 354b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[2]); 355b0453382SBill Fenner if (hold) 356b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[2])); 357b0453382SBill Fenner else 358b0453382SBill Fenner printf("FOREVER"); 359b0453382SBill Fenner 360b0453382SBill Fenner /* Next 4 bytes are reserved. */ 361b0453382SBill Fenner 362b0453382SBill Fenner bp += 8; len -= 8; 363b0453382SBill Fenner 364b0453382SBill Fenner /*XXX skip unless -v? */ 365b0453382SBill Fenner 366b0453382SBill Fenner /* 367b0453382SBill Fenner * Rest of packet: 368b0453382SBill Fenner * numrps entries of the form: 369b0453382SBill Fenner * 32 bits: RP 370b0453382SBill Fenner * 6 bits: reserved 371b0453382SBill Fenner * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2". 372b0453382SBill Fenner * 8 bits: # of entries for this RP 373b0453382SBill Fenner * each entry: 7 bits: reserved, 1 bit: negative, 374b0453382SBill Fenner * 8 bits: mask 32 bits: source 375b0453382SBill Fenner * lather, rinse, repeat. 376b0453382SBill Fenner */ 377b0453382SBill Fenner while (numrps--) { 378b0453382SBill Fenner int nentries; 379b0453382SBill Fenner char s; 380b0453382SBill Fenner 381b0453382SBill Fenner TCHECK2(bp[0], 4); 382b0453382SBill Fenner (void)printf(" RP %s", ipaddr_string(bp)); 383b0453382SBill Fenner TCHECK(bp[4]); 384b0453382SBill Fenner switch (bp[4] & 0x3) { 385b0453382SBill Fenner case 0: printf(" PIMv?"); 386b0453382SBill Fenner break; 387b0453382SBill Fenner case 1: printf(" PIMv1"); 388b0453382SBill Fenner break; 389b0453382SBill Fenner case 2: printf(" PIMv2"); 390b0453382SBill Fenner break; 391b0453382SBill Fenner case 3: printf(" PIMv1+2"); 392b0453382SBill Fenner break; 393b0453382SBill Fenner } 394a1c2090eSBill Fenner if (bp[4] & 0xfc) 395a1c2090eSBill Fenner (void)printf(" [rsvd=0x%02x]", bp[4] & 0xfc); 396b0453382SBill Fenner TCHECK(bp[5]); 397b0453382SBill Fenner nentries = bp[5]; 398b0453382SBill Fenner bp += 6; len -= 6; 399b0453382SBill Fenner s = ' '; 400b0453382SBill Fenner for (; nentries; nentries--) { 401b0453382SBill Fenner TCHECK2(bp[0], 6); 402b0453382SBill Fenner (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "", 403b0453382SBill Fenner ipaddr_string(&bp[2]), bp[1]); 404a1c2090eSBill Fenner if (bp[0] & 0xfe) 405a1c2090eSBill Fenner (void)printf("[rsvd=0x%02x]", bp[0] & 0xfe); 406b0453382SBill Fenner s = ','; 407b0453382SBill Fenner bp += 6; len -= 6; 408b0453382SBill Fenner } 409b0453382SBill Fenner } 410b0453382SBill Fenner return; 411b0453382SBill Fenner 412b0453382SBill Fenner trunc: 413b0453382SBill Fenner (void)printf("[|autorp]"); 414b0453382SBill Fenner return; 415b0453382SBill Fenner } 416b0453382SBill Fenner 417b0453382SBill Fenner void 418b0453382SBill Fenner pim_print(register const u_char *bp, register u_int len) 419b0453382SBill Fenner { 420b0453382SBill Fenner register const u_char *ep; 421b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 422b0453382SBill Fenner 423b0453382SBill Fenner ep = (const u_char *)snapend; 424b0453382SBill Fenner if (bp >= ep) 425b0453382SBill Fenner return; 426b0453382SBill Fenner #ifdef notyet /* currently we see only version and type */ 427b0453382SBill Fenner TCHECK(pim->pim_rsv); 428b0453382SBill Fenner #endif 429b0453382SBill Fenner 430b0453382SBill Fenner switch (PIM_VER(pim->pim_typever)) { 431c1ad1296SSam Leffler case 2: 432c1ad1296SSam Leffler if (!vflag) { 433abf25193SMax Laier printf("PIMv%u, %s, length %u", 434c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 435c1ad1296SSam Leffler tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)), 436c1ad1296SSam Leffler len); 437c1ad1296SSam Leffler return; 438c1ad1296SSam Leffler } else { 439abf25193SMax Laier printf("PIMv%u, length %u\n\t%s", 440c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 441c1ad1296SSam Leffler len, 442c1ad1296SSam Leffler tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever))); 443b0453382SBill Fenner pimv2_print(bp, len); 444c1ad1296SSam Leffler } 445b0453382SBill Fenner break; 446b0453382SBill Fenner default: 447abf25193SMax Laier printf("PIMv%u, length %u", 448c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 449c1ad1296SSam Leffler len); 450b0453382SBill Fenner break; 451b0453382SBill Fenner } 452b0453382SBill Fenner return; 453b0453382SBill Fenner } 454b0453382SBill Fenner 455b0453382SBill Fenner /* 456b0453382SBill Fenner * PIMv2 uses encoded address representations. 457b0453382SBill Fenner * 458b0453382SBill Fenner * The last PIM-SM I-D before RFC2117 was published specified the 459b0453382SBill Fenner * following representation for unicast addresses. However, RFC2117 460b0453382SBill Fenner * specified no encoding for unicast addresses with the unicast 461b0453382SBill Fenner * address length specified in the header. Therefore, we have to 462b0453382SBill Fenner * guess which encoding is being used (Cisco's PIMv2 implementation 463b0453382SBill Fenner * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" 464b0453382SBill Fenner * field into a 'unicast-address-length-in-bytes' field. We guess 465b0453382SBill Fenner * that it's the draft encoding if this reserved field is zero. 466b0453382SBill Fenner * 467b0453382SBill Fenner * RFC2362 goes back to the encoded format, and calls the addr length 468b0453382SBill Fenner * field "reserved" again. 469b0453382SBill Fenner * 470b0453382SBill Fenner * The first byte is the address family, from: 471b0453382SBill Fenner * 472b0453382SBill Fenner * 0 Reserved 473b0453382SBill Fenner * 1 IP (IP version 4) 474b0453382SBill Fenner * 2 IP6 (IP version 6) 475b0453382SBill Fenner * 3 NSAP 476b0453382SBill Fenner * 4 HDLC (8-bit multidrop) 477b0453382SBill Fenner * 5 BBN 1822 478b0453382SBill Fenner * 6 802 (includes all 802 media plus Ethernet "canonical format") 479b0453382SBill Fenner * 7 E.163 480b0453382SBill Fenner * 8 E.164 (SMDS, Frame Relay, ATM) 481b0453382SBill Fenner * 9 F.69 (Telex) 482b0453382SBill Fenner * 10 X.121 (X.25, Frame Relay) 483b0453382SBill Fenner * 11 IPX 484b0453382SBill Fenner * 12 Appletalk 485b0453382SBill Fenner * 13 Decnet IV 486b0453382SBill Fenner * 14 Banyan Vines 487b0453382SBill Fenner * 15 E.164 with NSAP format subaddress 488b0453382SBill Fenner * 489b0453382SBill Fenner * In addition, the second byte is an "Encoding". 0 is the default 490b0453382SBill Fenner * encoding for the address family, and no other encodings are currently 491b0453382SBill Fenner * specified. 492b0453382SBill Fenner * 493b0453382SBill Fenner */ 494b0453382SBill Fenner 495b0453382SBill Fenner static int pimv2_addr_len; 496b0453382SBill Fenner 497b0453382SBill Fenner enum pimv2_addrtype { 498b0453382SBill Fenner pimv2_unicast, pimv2_group, pimv2_source 499b0453382SBill Fenner }; 500b0453382SBill Fenner 501b0453382SBill Fenner /* 0 1 2 3 502b0453382SBill 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 503b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 504b0453382SBill Fenner * | Addr Family | Encoding Type | Unicast Address | 505b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ 506b0453382SBill Fenner * 0 1 2 3 507b0453382SBill 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 508b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 509b0453382SBill Fenner * | Addr Family | Encoding Type | Reserved | Mask Len | 510b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 511b0453382SBill Fenner * | Group multicast Address | 512b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 513b0453382SBill Fenner * 0 1 2 3 514b0453382SBill 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 515b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 516b0453382SBill Fenner * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | 517b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 518b0453382SBill Fenner * | Source Address | 519b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 520b0453382SBill Fenner */ 521b0453382SBill Fenner static int 522b0453382SBill Fenner pimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent) 523b0453382SBill Fenner { 524b0453382SBill Fenner int af; 525b0453382SBill Fenner int len, hdrlen; 526b0453382SBill Fenner 527b0453382SBill Fenner TCHECK(bp[0]); 528b0453382SBill Fenner 529b0453382SBill Fenner if (pimv2_addr_len == 0) { 530b0453382SBill Fenner TCHECK(bp[1]); 531b0453382SBill Fenner switch (bp[0]) { 532b0453382SBill Fenner case 1: 533b0453382SBill Fenner af = AF_INET; 53417cb103cSSam Leffler len = sizeof(struct in_addr); 535b0453382SBill Fenner break; 536b0453382SBill Fenner #ifdef INET6 537b0453382SBill Fenner case 2: 538b0453382SBill Fenner af = AF_INET6; 53917cb103cSSam Leffler len = sizeof(struct in6_addr); 540b0453382SBill Fenner break; 541b0453382SBill Fenner #endif 542b0453382SBill Fenner default: 543b0453382SBill Fenner return -1; 544b0453382SBill Fenner } 545b0453382SBill Fenner if (bp[1] != 0) 546b0453382SBill Fenner return -1; 547b0453382SBill Fenner hdrlen = 2; 548b0453382SBill Fenner } else { 549b0453382SBill Fenner switch (pimv2_addr_len) { 55017cb103cSSam Leffler case sizeof(struct in_addr): 551b0453382SBill Fenner af = AF_INET; 552b0453382SBill Fenner break; 553b0453382SBill Fenner #ifdef INET6 55417cb103cSSam Leffler case sizeof(struct in6_addr): 555b0453382SBill Fenner af = AF_INET6; 556b0453382SBill Fenner break; 557b0453382SBill Fenner #endif 558b0453382SBill Fenner default: 559b0453382SBill Fenner return -1; 560b0453382SBill Fenner break; 561b0453382SBill Fenner } 562b0453382SBill Fenner len = pimv2_addr_len; 563b0453382SBill Fenner hdrlen = 0; 564b0453382SBill Fenner } 565b0453382SBill Fenner 566b0453382SBill Fenner bp += hdrlen; 567b0453382SBill Fenner switch (at) { 568b0453382SBill Fenner case pimv2_unicast: 569b0453382SBill Fenner TCHECK2(bp[0], len); 570b0453382SBill Fenner if (af == AF_INET) { 571b0453382SBill Fenner if (!silent) 572b0453382SBill Fenner (void)printf("%s", ipaddr_string(bp)); 573b0453382SBill Fenner } 574b0453382SBill Fenner #ifdef INET6 575b0453382SBill Fenner else if (af == AF_INET6) { 576b0453382SBill Fenner if (!silent) 577b0453382SBill Fenner (void)printf("%s", ip6addr_string(bp)); 578b0453382SBill Fenner } 579b0453382SBill Fenner #endif 580b0453382SBill Fenner return hdrlen + len; 581b0453382SBill Fenner case pimv2_group: 582b0453382SBill Fenner case pimv2_source: 583b0453382SBill Fenner TCHECK2(bp[0], len + 2); 584b0453382SBill Fenner if (af == AF_INET) { 585b0453382SBill Fenner if (!silent) { 586b0453382SBill Fenner (void)printf("%s", ipaddr_string(bp + 2)); 587b0453382SBill Fenner if (bp[1] != 32) 588b0453382SBill Fenner (void)printf("/%u", bp[1]); 589b0453382SBill Fenner } 590b0453382SBill Fenner } 591b0453382SBill Fenner #ifdef INET6 592b0453382SBill Fenner else if (af == AF_INET6) { 593b0453382SBill Fenner if (!silent) { 594b0453382SBill Fenner (void)printf("%s", ip6addr_string(bp + 2)); 595b0453382SBill Fenner if (bp[1] != 128) 596b0453382SBill Fenner (void)printf("/%u", bp[1]); 597b0453382SBill Fenner } 598b0453382SBill Fenner } 599b0453382SBill Fenner #endif 600b0453382SBill Fenner if (bp[0] && !silent) { 601b0453382SBill Fenner if (at == pimv2_group) { 602b0453382SBill Fenner (void)printf("(0x%02x)", bp[0]); 603b0453382SBill Fenner } else { 604b0453382SBill Fenner (void)printf("(%s%s%s", 605b0453382SBill Fenner bp[0] & 0x04 ? "S" : "", 606b0453382SBill Fenner bp[0] & 0x02 ? "W" : "", 607b0453382SBill Fenner bp[0] & 0x01 ? "R" : ""); 608b0453382SBill Fenner if (bp[0] & 0xf8) { 609b0453382SBill Fenner (void) printf("+0x%02x", bp[0] & 0xf8); 610b0453382SBill Fenner } 611b0453382SBill Fenner (void)printf(")"); 612b0453382SBill Fenner } 613b0453382SBill Fenner } 614b0453382SBill Fenner return hdrlen + 2 + len; 615b0453382SBill Fenner default: 616b0453382SBill Fenner return -1; 617b0453382SBill Fenner } 618b0453382SBill Fenner trunc: 619b0453382SBill Fenner return -1; 620b0453382SBill Fenner } 621b0453382SBill Fenner 622b0453382SBill Fenner static void 623b0453382SBill Fenner pimv2_print(register const u_char *bp, register u_int len) 624b0453382SBill Fenner { 625b0453382SBill Fenner register const u_char *ep; 626b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 627b0453382SBill Fenner int advance; 628b0453382SBill Fenner 629b0453382SBill Fenner ep = (const u_char *)snapend; 630b0453382SBill Fenner if (bp >= ep) 631b0453382SBill Fenner return; 6329537d84eSBill Fenner if (ep > bp + len) 6339537d84eSBill Fenner ep = bp + len; 634b0453382SBill Fenner TCHECK(pim->pim_rsv); 635b0453382SBill Fenner pimv2_addr_len = pim->pim_rsv; 636b0453382SBill Fenner if (pimv2_addr_len != 0) 637c1ad1296SSam Leffler (void)printf(", RFC2117-encoding"); 638b0453382SBill Fenner 639abf25193SMax Laier printf(", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum)); 640abf25193SMax Laier if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { 641abf25193SMax Laier printf("(unverified)"); 642abf25193SMax Laier } else { 643abf25193SMax Laier printf("(%scorrect)", 644abf25193SMax Laier TTEST2(bp[0], len) && 645abf25193SMax Laier in_cksum((const u_short*)bp, len, 0) ? "in" : "" ); 646abf25193SMax Laier } 647abf25193SMax Laier 648b0453382SBill Fenner switch (PIM_TYPE(pim->pim_typever)) { 649c1ad1296SSam Leffler case PIMV2_TYPE_HELLO: 650b0453382SBill Fenner { 651b0453382SBill Fenner u_int16_t otype, olen; 652b0453382SBill Fenner bp += 4; 653b0453382SBill Fenner while (bp < ep) { 654b0453382SBill Fenner TCHECK2(bp[0], 4); 655b0453382SBill Fenner otype = EXTRACT_16BITS(&bp[0]); 656b0453382SBill Fenner olen = EXTRACT_16BITS(&bp[2]); 657b0453382SBill Fenner TCHECK2(bp[0], 4 + olen); 658c1ad1296SSam Leffler 659abf25193SMax Laier printf("\n\t %s Option (%u), length %u, Value: ", 660c1ad1296SSam Leffler tok2str( pimv2_hello_option_values,"Unknown",otype), 661c1ad1296SSam Leffler otype, 662c1ad1296SSam Leffler olen); 663c1ad1296SSam Leffler bp += 4; 664c1ad1296SSam Leffler 665b0453382SBill Fenner switch (otype) { 666c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_HOLDTIME: 667c1ad1296SSam Leffler relts_print(EXTRACT_16BITS(bp)); 668b0453382SBill Fenner break; 669b0453382SBill Fenner 670c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_LANPRUNEDELAY: 671cc391cceSBruce M Simpson if (olen != 4) { 672c1ad1296SSam Leffler (void)printf("ERROR: Option Lenght != 4 Bytes (%u)", olen); 673cc391cceSBruce M Simpson } else { 674cc391cceSBruce M Simpson char t_bit; 675cc391cceSBruce M Simpson u_int16_t lan_delay, override_interval; 676c1ad1296SSam Leffler lan_delay = EXTRACT_16BITS(bp); 677c1ad1296SSam Leffler override_interval = EXTRACT_16BITS(bp+2); 678cc391cceSBruce M Simpson t_bit = (lan_delay & 0x8000)? 1 : 0; 679cc391cceSBruce M Simpson lan_delay &= ~0x8000; 680c1ad1296SSam Leffler (void)printf("\n\t T-bit=%d, LAN delay %dms, Override interval %dms", 681cc391cceSBruce M Simpson t_bit, lan_delay, override_interval); 682cc391cceSBruce M Simpson } 683cc391cceSBruce M Simpson break; 684cc391cceSBruce M Simpson 685c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_DR_PRIORITY_OLD: 686c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_DR_PRIORITY: 687c1ad1296SSam Leffler switch (olen) { 688c1ad1296SSam Leffler case 0: 689c1ad1296SSam Leffler printf("Bi-Directional Capability (Old)"); 6900e0def19SBill Fenner break; 691c1ad1296SSam Leffler case 4: 692c1ad1296SSam Leffler printf("%u", EXTRACT_32BITS(bp)); 693c1ad1296SSam Leffler break; 694c1ad1296SSam Leffler default: 695c1ad1296SSam Leffler printf("ERROR: Option Lenght != 4 Bytes (%u)", olen); 6960e0def19SBill Fenner break; 6970e0def19SBill Fenner } 698c1ad1296SSam Leffler break; 699c1ad1296SSam Leffler 700c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_GENID: 701c1ad1296SSam Leffler (void)printf("0x%08x", EXTRACT_32BITS(bp)); 702c1ad1296SSam Leffler break; 703c1ad1296SSam Leffler 704c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_REFRESH_CAP: 705c1ad1296SSam Leffler (void)printf("v%d", *bp); 706c1ad1296SSam Leffler if (*(bp+1) != 0) { 707c1ad1296SSam Leffler (void)printf(", interval "); 708c1ad1296SSam Leffler relts_print(*(bp+1)); 709c1ad1296SSam Leffler } 710c1ad1296SSam Leffler if (EXTRACT_16BITS(bp+2) != 0) { 711c1ad1296SSam Leffler (void)printf(" ?0x%04x?", EXTRACT_16BITS(bp+2)); 712a1c2090eSBill Fenner } 713b0453382SBill Fenner break; 714b0453382SBill Fenner 715c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_BIDIR_CAP: 716b0453382SBill Fenner break; 717b0453382SBill Fenner 718c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD: 719c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_ADDRESS_LIST: 720cc391cceSBruce M Simpson if (vflag > 1) { 721c1ad1296SSam Leffler const u_char *ptr = bp; 722c1ad1296SSam Leffler while (ptr < (bp+olen)) { 723cc391cceSBruce M Simpson int advance; 724cc391cceSBruce M Simpson 725c1ad1296SSam Leffler printf("\n\t "); 726cc391cceSBruce M Simpson advance = pimv2_addr_print(ptr, pimv2_unicast, 0); 727cc391cceSBruce M Simpson if (advance < 0) { 728cc391cceSBruce M Simpson printf("..."); 729cc391cceSBruce M Simpson break; 730cc391cceSBruce M Simpson } 731cc391cceSBruce M Simpson ptr += advance; 732cc391cceSBruce M Simpson } 733cc391cceSBruce M Simpson } 734cc391cceSBruce M Simpson break; 735b0453382SBill Fenner default: 736c1ad1296SSam Leffler if (vflag <= 1) 737c1ad1296SSam Leffler print_unknown_data(bp,"\n\t ",olen); 738c1ad1296SSam Leffler break; 739b0453382SBill Fenner } 740c1ad1296SSam Leffler /* do we want to see an additionally hexdump ? */ 741c1ad1296SSam Leffler if (vflag> 1) 742c1ad1296SSam Leffler print_unknown_data(bp,"\n\t ",olen); 743c1ad1296SSam Leffler bp += olen; 744b0453382SBill Fenner } 745b0453382SBill Fenner break; 746b0453382SBill Fenner } 747b0453382SBill Fenner 748c1ad1296SSam Leffler case PIMV2_TYPE_REGISTER: 749b0453382SBill Fenner { 750b0453382SBill Fenner struct ip *ip; 751b0453382SBill Fenner 752abf25193SMax Laier if (!TTEST2(*(bp+4), PIMV2_REGISTER_FLAG_LEN)) 753abf25193SMax Laier goto trunc; 754b0453382SBill Fenner 755abf25193SMax Laier printf(", Flags [ %s ]\n\t", 756abf25193SMax Laier tok2str(pimv2_register_flag_values, 757abf25193SMax Laier "none", 758abf25193SMax Laier EXTRACT_32BITS(bp+4))); 759abf25193SMax Laier 760abf25193SMax Laier bp += 8; len -= 8; 761b0453382SBill Fenner /* encapsulated multicast packet */ 762b0453382SBill Fenner ip = (struct ip *)bp; 763943ee2b1SBill Fenner switch (IP_V(ip)) { 764abf25193SMax Laier case 0: /* Null header */ 765abf25193SMax Laier (void)printf("IP-Null-header %s > %s", 766abf25193SMax Laier ipaddr_string(&ip->ip_src), 767abf25193SMax Laier ipaddr_string(&ip->ip_dst)); 768abf25193SMax Laier break; 769abf25193SMax Laier 770b0453382SBill Fenner case 4: /* IPv4 */ 771c1ad1296SSam Leffler ip_print(gndo, bp, len); 772b0453382SBill Fenner break; 773b0453382SBill Fenner #ifdef INET6 774b0453382SBill Fenner case 6: /* IPv6 */ 775b0453382SBill Fenner ip6_print(bp, len); 776b0453382SBill Fenner break; 777b0453382SBill Fenner #endif 778b0453382SBill Fenner default: 779943ee2b1SBill Fenner (void)printf("IP ver %d", IP_V(ip)); 780b0453382SBill Fenner break; 781b0453382SBill Fenner } 782b0453382SBill Fenner break; 783b0453382SBill Fenner } 784b0453382SBill Fenner 785c1ad1296SSam Leffler case PIMV2_TYPE_REGISTER_STOP: 786b0453382SBill Fenner bp += 4; len -= 4; 787b0453382SBill Fenner if (bp >= ep) 788b0453382SBill Fenner break; 789b0453382SBill Fenner (void)printf(" group="); 790b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 791b0453382SBill Fenner (void)printf("..."); 792b0453382SBill Fenner break; 793b0453382SBill Fenner } 794b0453382SBill Fenner bp += advance; len -= advance; 795b0453382SBill Fenner if (bp >= ep) 796b0453382SBill Fenner break; 797b0453382SBill Fenner (void)printf(" source="); 798b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 799b0453382SBill Fenner (void)printf("..."); 800b0453382SBill Fenner break; 801b0453382SBill Fenner } 802b0453382SBill Fenner bp += advance; len -= advance; 803b0453382SBill Fenner break; 804b0453382SBill Fenner 805c1ad1296SSam Leffler case PIMV2_TYPE_JOIN_PRUNE: 806c1ad1296SSam Leffler case PIMV2_TYPE_GRAFT: 807c1ad1296SSam Leffler case PIMV2_TYPE_GRAFT_ACK: 808c1ad1296SSam Leffler 809c1ad1296SSam Leffler 810c1ad1296SSam Leffler /* 811c1ad1296SSam Leffler * 0 1 2 3 812c1ad1296SSam Leffler * 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 813c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 814c1ad1296SSam Leffler * |PIM Ver| Type | Addr length | Checksum | 815c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 816c1ad1296SSam Leffler * | Unicast-Upstream Neighbor Address | 817c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 818c1ad1296SSam Leffler * | Reserved | Num groups | Holdtime | 819c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 820c1ad1296SSam Leffler * | Encoded-Multicast Group Address-1 | 821c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 822c1ad1296SSam Leffler * | Number of Joined Sources | Number of Pruned Sources | 823c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 824c1ad1296SSam Leffler * | Encoded-Joined Source Address-1 | 825c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 826c1ad1296SSam Leffler * | . | 827c1ad1296SSam Leffler * | . | 828c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 829c1ad1296SSam Leffler * | Encoded-Joined Source Address-n | 830c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 831c1ad1296SSam Leffler * | Encoded-Pruned Source Address-1 | 832c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 833c1ad1296SSam Leffler * | . | 834c1ad1296SSam Leffler * | . | 835c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 836c1ad1296SSam Leffler * | Encoded-Pruned Source Address-n | 837c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 838c1ad1296SSam Leffler * | . | 839c1ad1296SSam Leffler * | . | 840c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 841c1ad1296SSam Leffler * | Encoded-Multicast Group Address-n | 842c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 843c1ad1296SSam Leffler */ 844c1ad1296SSam Leffler 845b0453382SBill Fenner { 846b0453382SBill Fenner u_int8_t ngroup; 847b0453382SBill Fenner u_int16_t holdtime; 848b0453382SBill Fenner u_int16_t njoin; 849b0453382SBill Fenner u_int16_t nprune; 850b0453382SBill Fenner int i, j; 851b0453382SBill Fenner 852b0453382SBill Fenner bp += 4; len -= 4; 853b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 854b0453382SBill Fenner if (bp >= ep) 855b0453382SBill Fenner break; 856c1ad1296SSam Leffler (void)printf(", upstream-neighbor: "); 857b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 858b0453382SBill Fenner (void)printf("..."); 859b0453382SBill Fenner break; 860b0453382SBill Fenner } 861b0453382SBill Fenner bp += advance; len -= advance; 862b0453382SBill Fenner } 863b0453382SBill Fenner if (bp + 4 > ep) 864b0453382SBill Fenner break; 865b0453382SBill Fenner ngroup = bp[1]; 866b0453382SBill Fenner holdtime = EXTRACT_16BITS(&bp[2]); 867c1ad1296SSam Leffler (void)printf("\n\t %u group(s)", ngroup); 868b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 869c1ad1296SSam Leffler (void)printf(", holdtime: "); 870b0453382SBill Fenner if (holdtime == 0xffff) 871c1ad1296SSam Leffler (void)printf("infinite"); 872b0453382SBill Fenner else 873b0453382SBill Fenner relts_print(holdtime); 874b0453382SBill Fenner } 875b0453382SBill Fenner bp += 4; len -= 4; 876b0453382SBill Fenner for (i = 0; i < ngroup; i++) { 877b0453382SBill Fenner if (bp >= ep) 878b0453382SBill Fenner goto jp_done; 879c1ad1296SSam Leffler (void)printf("\n\t group #%u: ", i+1); 880b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 881b0453382SBill Fenner (void)printf("...)"); 882b0453382SBill Fenner goto jp_done; 883b0453382SBill Fenner } 884b0453382SBill Fenner bp += advance; len -= advance; 885b0453382SBill Fenner if (bp + 4 > ep) { 886b0453382SBill Fenner (void)printf("...)"); 887b0453382SBill Fenner goto jp_done; 888b0453382SBill Fenner } 889b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[0]); 890b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[2]); 891c1ad1296SSam Leffler (void)printf(", joined sources: %u, pruned sources: %u", njoin,nprune); 892b0453382SBill Fenner bp += 4; len -= 4; 893b0453382SBill Fenner for (j = 0; j < njoin; j++) { 894c1ad1296SSam Leffler (void)printf("\n\t joined source #%u: ",j+1); 895b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { 896b0453382SBill Fenner (void)printf("...)"); 897b0453382SBill Fenner goto jp_done; 898b0453382SBill Fenner } 899b0453382SBill Fenner bp += advance; len -= advance; 900b0453382SBill Fenner } 901b0453382SBill Fenner for (j = 0; j < nprune; j++) { 902c1ad1296SSam Leffler (void)printf("\n\t pruned source #%u: ",j+1); 903b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { 904b0453382SBill Fenner (void)printf("...)"); 905b0453382SBill Fenner goto jp_done; 906b0453382SBill Fenner } 907b0453382SBill Fenner bp += advance; len -= advance; 908b0453382SBill Fenner } 909b0453382SBill Fenner } 910b0453382SBill Fenner jp_done: 911b0453382SBill Fenner break; 912b0453382SBill Fenner } 913b0453382SBill Fenner 914c1ad1296SSam Leffler case PIMV2_TYPE_BOOTSTRAP: 915b0453382SBill Fenner { 916b0453382SBill Fenner int i, j, frpcnt; 917b0453382SBill Fenner bp += 4; 918b0453382SBill Fenner 919b0453382SBill Fenner /* Fragment Tag, Hash Mask len, and BSR-priority */ 920b0453382SBill Fenner if (bp + sizeof(u_int16_t) >= ep) break; 921b0453382SBill Fenner (void)printf(" tag=%x", EXTRACT_16BITS(bp)); 922b0453382SBill Fenner bp += sizeof(u_int16_t); 923b0453382SBill Fenner if (bp >= ep) break; 924b0453382SBill Fenner (void)printf(" hashmlen=%d", bp[0]); 925b0453382SBill Fenner if (bp + 1 >= ep) break; 926b0453382SBill Fenner (void)printf(" BSRprio=%d", bp[1]); 927b0453382SBill Fenner bp += 2; 928b0453382SBill Fenner 929b0453382SBill Fenner /* Encoded-Unicast-BSR-Address */ 930b0453382SBill Fenner if (bp >= ep) break; 931b0453382SBill Fenner (void)printf(" BSR="); 932b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 933b0453382SBill Fenner (void)printf("..."); 934b0453382SBill Fenner break; 935b0453382SBill Fenner } 936b0453382SBill Fenner bp += advance; 937b0453382SBill Fenner 938b0453382SBill Fenner for (i = 0; bp < ep; i++) { 939b0453382SBill Fenner /* Encoded-Group Address */ 940b0453382SBill Fenner (void)printf(" (group%d: ", i); 941b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) 942b0453382SBill Fenner < 0) { 943b0453382SBill Fenner (void)printf("...)"); 944b0453382SBill Fenner goto bs_done; 945b0453382SBill Fenner } 946b0453382SBill Fenner bp += advance; 947b0453382SBill Fenner 948b0453382SBill Fenner /* RP-Count, Frag RP-Cnt, and rsvd */ 949b0453382SBill Fenner if (bp >= ep) { 950b0453382SBill Fenner (void)printf("...)"); 951b0453382SBill Fenner goto bs_done; 952b0453382SBill Fenner } 953943ee2b1SBill Fenner (void)printf(" RPcnt=%d", bp[0]); 954b0453382SBill Fenner if (bp + 1 >= ep) { 955b0453382SBill Fenner (void)printf("...)"); 956b0453382SBill Fenner goto bs_done; 957b0453382SBill Fenner } 958943ee2b1SBill Fenner (void)printf(" FRPcnt=%d", frpcnt = bp[1]); 959b0453382SBill Fenner bp += 4; 960b0453382SBill Fenner 961b0453382SBill Fenner for (j = 0; j < frpcnt && bp < ep; j++) { 962b0453382SBill Fenner /* each RP info */ 963b0453382SBill Fenner (void)printf(" RP%d=", j); 964b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, 965b0453382SBill Fenner pimv2_unicast, 966b0453382SBill Fenner 0)) < 0) { 967b0453382SBill Fenner (void)printf("...)"); 968b0453382SBill Fenner goto bs_done; 969b0453382SBill Fenner } 970b0453382SBill Fenner bp += advance; 971b0453382SBill Fenner 972b0453382SBill Fenner if (bp + 1 >= ep) { 973b0453382SBill Fenner (void)printf("...)"); 974b0453382SBill Fenner goto bs_done; 975b0453382SBill Fenner } 976b0453382SBill Fenner (void)printf(",holdtime="); 977b0453382SBill Fenner relts_print(EXTRACT_16BITS(bp)); 978b0453382SBill Fenner if (bp + 2 >= ep) { 979b0453382SBill Fenner (void)printf("...)"); 980b0453382SBill Fenner goto bs_done; 981b0453382SBill Fenner } 982b0453382SBill Fenner (void)printf(",prio=%d", bp[2]); 983b0453382SBill Fenner bp += 4; 984b0453382SBill Fenner } 985b0453382SBill Fenner (void)printf(")"); 986b0453382SBill Fenner } 987b0453382SBill Fenner bs_done: 988b0453382SBill Fenner break; 989b0453382SBill Fenner } 990c1ad1296SSam Leffler case PIMV2_TYPE_ASSERT: 991b0453382SBill Fenner bp += 4; len -= 4; 992b0453382SBill Fenner if (bp >= ep) 993b0453382SBill Fenner break; 994b0453382SBill Fenner (void)printf(" group="); 995b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 996b0453382SBill Fenner (void)printf("..."); 997b0453382SBill Fenner break; 998b0453382SBill Fenner } 999b0453382SBill Fenner bp += advance; len -= advance; 1000b0453382SBill Fenner if (bp >= ep) 1001b0453382SBill Fenner break; 1002b0453382SBill Fenner (void)printf(" src="); 1003b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 1004b0453382SBill Fenner (void)printf("..."); 1005b0453382SBill Fenner break; 1006b0453382SBill Fenner } 1007b0453382SBill Fenner bp += advance; len -= advance; 1008b0453382SBill Fenner if (bp + 8 > ep) 1009b0453382SBill Fenner break; 1010b0453382SBill Fenner if (bp[0] & 0x80) 1011b0453382SBill Fenner (void)printf(" RPT"); 1012b0453382SBill Fenner (void)printf(" pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff); 1013b0453382SBill Fenner (void)printf(" metric=%u", EXTRACT_32BITS(&bp[4])); 1014b0453382SBill Fenner break; 1015b0453382SBill Fenner 1016c1ad1296SSam Leffler case PIMV2_TYPE_CANDIDATE_RP: 1017b0453382SBill Fenner { 1018b0453382SBill Fenner int i, pfxcnt; 1019b0453382SBill Fenner bp += 4; 1020b0453382SBill Fenner 1021b0453382SBill Fenner /* Prefix-Cnt, Priority, and Holdtime */ 1022b0453382SBill Fenner if (bp >= ep) break; 1023b0453382SBill Fenner (void)printf(" prefix-cnt=%d", bp[0]); 1024b0453382SBill Fenner pfxcnt = bp[0]; 1025b0453382SBill Fenner if (bp + 1 >= ep) break; 1026b0453382SBill Fenner (void)printf(" prio=%d", bp[1]); 1027b0453382SBill Fenner if (bp + 3 >= ep) break; 1028b0453382SBill Fenner (void)printf(" holdtime="); 1029b0453382SBill Fenner relts_print(EXTRACT_16BITS(&bp[2])); 1030b0453382SBill Fenner bp += 4; 1031b0453382SBill Fenner 1032b0453382SBill Fenner /* Encoded-Unicast-RP-Address */ 1033b0453382SBill Fenner if (bp >= ep) break; 1034b0453382SBill Fenner (void)printf(" RP="); 1035b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 1036b0453382SBill Fenner (void)printf("..."); 1037b0453382SBill Fenner break; 1038b0453382SBill Fenner } 1039b0453382SBill Fenner bp += advance; 1040b0453382SBill Fenner 1041b0453382SBill Fenner /* Encoded-Group Addresses */ 1042b0453382SBill Fenner for (i = 0; i < pfxcnt && bp < ep; i++) { 1043b0453382SBill Fenner (void)printf(" Group%d=", i); 1044b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) 1045b0453382SBill Fenner < 0) { 1046b0453382SBill Fenner (void)printf("..."); 1047b0453382SBill Fenner break; 1048b0453382SBill Fenner } 1049b0453382SBill Fenner bp += advance; 1050b0453382SBill Fenner } 1051b0453382SBill Fenner break; 1052b0453382SBill Fenner } 1053b0453382SBill Fenner 1054c1ad1296SSam Leffler case PIMV2_TYPE_PRUNE_REFRESH: 1055b0453382SBill Fenner (void)printf(" src="); 1056b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 1057b0453382SBill Fenner (void)printf("..."); 1058b0453382SBill Fenner break; 1059b0453382SBill Fenner } 1060b0453382SBill Fenner bp += advance; 1061b0453382SBill Fenner (void)printf(" grp="); 1062b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { 1063b0453382SBill Fenner (void)printf("..."); 1064b0453382SBill Fenner break; 1065b0453382SBill Fenner } 1066b0453382SBill Fenner bp += advance; 1067b0453382SBill Fenner (void)printf(" forwarder="); 1068b0453382SBill Fenner if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { 1069b0453382SBill Fenner (void)printf("..."); 1070b0453382SBill Fenner break; 1071b0453382SBill Fenner } 1072b0453382SBill Fenner bp += advance; 1073b0453382SBill Fenner TCHECK2(bp[0], 2); 1074b0453382SBill Fenner (void)printf(" TUNR "); 1075b0453382SBill Fenner relts_print(EXTRACT_16BITS(bp)); 1076b0453382SBill Fenner break; 1077b0453382SBill Fenner 1078b0453382SBill Fenner 1079b0453382SBill Fenner default: 1080b0453382SBill Fenner (void)printf(" [type %d]", PIM_TYPE(pim->pim_typever)); 1081b0453382SBill Fenner break; 1082b0453382SBill Fenner } 1083b0453382SBill Fenner 1084b0453382SBill Fenner return; 1085b0453382SBill Fenner 1086b0453382SBill Fenner trunc: 1087b0453382SBill Fenner (void)printf("[|pim]"); 10884edb46e9SPaul Traina } 1089c1ad1296SSam Leffler 1090c1ad1296SSam Leffler /* 1091c1ad1296SSam Leffler * Local Variables: 1092c1ad1296SSam Leffler * c-style: whitesmith 1093c1ad1296SSam Leffler * c-basic-offset: 8 1094c1ad1296SSam Leffler * End: 1095c1ad1296SSam Leffler */ 1096