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