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