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 243c602fabSXin LI #define NETDISSECT_REWORKED 25b0453382SBill Fenner #ifdef HAVE_CONFIG_H 26b0453382SBill Fenner #include "config.h" 274edb46e9SPaul Traina #endif 284edb46e9SPaul Traina 29cc391cceSBruce M Simpson #include <tcpdump-stdinc.h> 30cac3dcd5SXin LI 31c1ad1296SSam Leffler #include "interface.h" 32cac3dcd5SXin LI #include "addrtoname.h" 33cac3dcd5SXin LI #include "extract.h" 34cac3dcd5SXin LI 35cac3dcd5SXin LI #include "ip.h" 36c1ad1296SSam Leffler 373c602fabSXin LI #define PIMV1_TYPE_QUERY 0 383c602fabSXin LI #define PIMV1_TYPE_REGISTER 1 393c602fabSXin LI #define PIMV1_TYPE_REGISTER_STOP 2 403c602fabSXin LI #define PIMV1_TYPE_JOIN_PRUNE 3 413c602fabSXin LI #define PIMV1_TYPE_RP_REACHABILITY 4 423c602fabSXin LI #define PIMV1_TYPE_ASSERT 5 433c602fabSXin LI #define PIMV1_TYPE_GRAFT 6 443c602fabSXin LI #define PIMV1_TYPE_GRAFT_ACK 7 453c602fabSXin LI 463c602fabSXin LI static const struct tok pimv1_type_str[] = { 473c602fabSXin LI { PIMV1_TYPE_QUERY, "Query" }, 483c602fabSXin LI { PIMV1_TYPE_REGISTER, "Register" }, 493c602fabSXin LI { PIMV1_TYPE_REGISTER_STOP, "Register-Stop" }, 503c602fabSXin LI { PIMV1_TYPE_JOIN_PRUNE, "Join/Prune" }, 513c602fabSXin LI { PIMV1_TYPE_RP_REACHABILITY, "RP-reachable" }, 523c602fabSXin LI { PIMV1_TYPE_ASSERT, "Assert" }, 533c602fabSXin LI { PIMV1_TYPE_GRAFT, "Graft" }, 543c602fabSXin LI { PIMV1_TYPE_GRAFT_ACK, "Graft-ACK" }, 553c602fabSXin LI { 0, NULL } 563c602fabSXin LI }; 573c602fabSXin LI 58c1ad1296SSam Leffler #define PIMV2_TYPE_HELLO 0 59c1ad1296SSam Leffler #define PIMV2_TYPE_REGISTER 1 60c1ad1296SSam Leffler #define PIMV2_TYPE_REGISTER_STOP 2 61c1ad1296SSam Leffler #define PIMV2_TYPE_JOIN_PRUNE 3 62c1ad1296SSam Leffler #define PIMV2_TYPE_BOOTSTRAP 4 63c1ad1296SSam Leffler #define PIMV2_TYPE_ASSERT 5 64c1ad1296SSam Leffler #define PIMV2_TYPE_GRAFT 6 65c1ad1296SSam Leffler #define PIMV2_TYPE_GRAFT_ACK 7 66c1ad1296SSam Leffler #define PIMV2_TYPE_CANDIDATE_RP 8 67c1ad1296SSam Leffler #define PIMV2_TYPE_PRUNE_REFRESH 9 683c602fabSXin LI #define PIMV2_TYPE_DF_ELECTION 10 693c602fabSXin LI #define PIMV2_TYPE_ECMP_REDIRECT 11 70c1ad1296SSam Leffler 713c602fabSXin LI static const struct tok pimv2_type_values[] = { 72c1ad1296SSam Leffler { PIMV2_TYPE_HELLO, "Hello" }, 73c1ad1296SSam Leffler { PIMV2_TYPE_REGISTER, "Register" }, 74c1ad1296SSam Leffler { PIMV2_TYPE_REGISTER_STOP, "Register Stop" }, 75c1ad1296SSam Leffler { PIMV2_TYPE_JOIN_PRUNE, "Join / Prune" }, 76c1ad1296SSam Leffler { PIMV2_TYPE_BOOTSTRAP, "Bootstrap" }, 77c1ad1296SSam Leffler { PIMV2_TYPE_ASSERT, "Assert" }, 78c1ad1296SSam Leffler { PIMV2_TYPE_GRAFT, "Graft" }, 79c1ad1296SSam Leffler { PIMV2_TYPE_GRAFT_ACK, "Graft Acknowledgement" }, 80c1ad1296SSam Leffler { PIMV2_TYPE_CANDIDATE_RP, "Candidate RP Advertisement" }, 81c1ad1296SSam Leffler { PIMV2_TYPE_PRUNE_REFRESH, "Prune Refresh" }, 823c602fabSXin LI { PIMV2_TYPE_DF_ELECTION, "DF Election" }, 833c602fabSXin LI { PIMV2_TYPE_ECMP_REDIRECT, "ECMP Redirect" }, 84c1ad1296SSam Leffler { 0, NULL} 85c1ad1296SSam Leffler }; 86c1ad1296SSam Leffler 87c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_HOLDTIME 1 88c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_LANPRUNEDELAY 2 89c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_DR_PRIORITY_OLD 18 90c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_DR_PRIORITY 19 91c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_GENID 20 92c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_REFRESH_CAP 21 93c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_BIDIR_CAP 22 94c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_ADDRESS_LIST 24 95c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD 65001 96c1ad1296SSam Leffler 973c602fabSXin LI static const struct tok pimv2_hello_option_values[] = { 98c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_HOLDTIME, "Hold Time" }, 99c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_LANPRUNEDELAY, "LAN Prune Delay" }, 100c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_DR_PRIORITY_OLD, "DR Priority (Old)" }, 101c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_DR_PRIORITY, "DR Priority" }, 102c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_GENID, "Generation ID" }, 103c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_REFRESH_CAP, "State Refresh Capability" }, 104c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_BIDIR_CAP, "Bi-Directional Capability" }, 105c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_ADDRESS_LIST, "Address List" }, 106c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD, "Address List (Old)" }, 107c1ad1296SSam Leffler { 0, NULL} 108c1ad1296SSam Leffler }; 109c1ad1296SSam Leffler 110abf25193SMax Laier #define PIMV2_REGISTER_FLAG_LEN 4 111abf25193SMax Laier #define PIMV2_REGISTER_FLAG_BORDER 0x80000000 112abf25193SMax Laier #define PIMV2_REGISTER_FLAG_NULL 0x40000000 113abf25193SMax Laier 1143c602fabSXin LI static const struct tok pimv2_register_flag_values[] = { 115abf25193SMax Laier { PIMV2_REGISTER_FLAG_BORDER, "Border" }, 116abf25193SMax Laier { PIMV2_REGISTER_FLAG_NULL, "Null" }, 117abf25193SMax Laier { 0, NULL} 118abf25193SMax Laier }; 119b0453382SBill Fenner 120b0453382SBill Fenner /* 121b0453382SBill Fenner * XXX: We consider a case where IPv6 is not ready yet for portability, 122b0453382SBill Fenner * but PIM dependent defintions should be independent of IPv6... 123b0453382SBill Fenner */ 124b0453382SBill Fenner 125b0453382SBill Fenner struct pim { 1263c602fabSXin LI uint8_t pim_typever; 1279537d84eSBill Fenner /* upper 4bit: PIM version number; 2 for PIMv2 */ 1289537d84eSBill Fenner /* lower 4bit: the PIM message type, currently they are: 129b0453382SBill Fenner * Hello, Register, Register-Stop, Join/Prune, 130b0453382SBill Fenner * Bootstrap, Assert, Graft (PIM-DM only), 131b0453382SBill Fenner * Graft-Ack (PIM-DM only), C-RP-Adv 132b0453382SBill Fenner */ 1339537d84eSBill Fenner #define PIM_VER(x) (((x) & 0xf0) >> 4) 1349537d84eSBill Fenner #define PIM_TYPE(x) ((x) & 0x0f) 135b0453382SBill Fenner u_char pim_rsv; /* Reserved */ 136b0453382SBill Fenner u_short pim_cksum; /* IP style check sum */ 137b0453382SBill Fenner }; 138b0453382SBill Fenner 1393c602fabSXin LI static void pimv2_print(netdissect_options *, register const u_char *bp, register u_int len, u_int cksum); 140b0453382SBill Fenner 141b0453382SBill Fenner static void 1423c602fabSXin LI pimv1_join_prune_print(netdissect_options *ndo, 1433c602fabSXin LI register const u_char *bp, register u_int len) 144b0453382SBill Fenner { 1453c602fabSXin LI int ngroups, njoin, nprune; 146b0453382SBill Fenner int njp; 147b0453382SBill Fenner 148b0453382SBill Fenner /* If it's a single group and a single source, use 1-line output. */ 1493c602fabSXin LI if (ND_TTEST2(bp[0], 30) && bp[11] == 1 && 150b0453382SBill Fenner ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { 151b0453382SBill Fenner int hold; 152b0453382SBill Fenner 1533c602fabSXin LI ND_PRINT((ndo, " RPF %s ", ipaddr_string(ndo, bp))); 154b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[6]); 155b0453382SBill Fenner if (hold != 180) { 1563c602fabSXin LI ND_PRINT((ndo, "Hold ")); 1573c602fabSXin LI relts_print(ndo, hold); 158b0453382SBill Fenner } 1593c602fabSXin LI ND_PRINT((ndo, "%s (%s/%d, %s", njoin ? "Join" : "Prune", 1603c602fabSXin LI ipaddr_string(ndo, &bp[26]), bp[25] & 0x3f, 1613c602fabSXin LI ipaddr_string(ndo, &bp[12]))); 162b0453382SBill Fenner if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) 1633c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[16]))); 1643c602fabSXin LI ND_PRINT((ndo, ") %s%s %s", 165b0453382SBill Fenner (bp[24] & 0x01) ? "Sparse" : "Dense", 166b0453382SBill Fenner (bp[25] & 0x80) ? " WC" : "", 1673c602fabSXin LI (bp[25] & 0x40) ? "RP" : "SPT")); 168b0453382SBill Fenner return; 169b0453382SBill Fenner } 170b0453382SBill Fenner 1713c602fabSXin LI ND_TCHECK2(bp[0], sizeof(struct in_addr)); 1723c602fabSXin LI if (ndo->ndo_vflag > 1) 1733c602fabSXin LI ND_PRINT((ndo, "\n")); 1743c602fabSXin LI ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp))); 1753c602fabSXin LI ND_TCHECK2(bp[6], 2); 1763c602fabSXin LI if (ndo->ndo_vflag > 1) 1773c602fabSXin LI ND_PRINT((ndo, "\n")); 1783c602fabSXin LI ND_PRINT((ndo, " Hold time: ")); 1793c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[6])); 1803c602fabSXin LI if (ndo->ndo_vflag < 2) 181a1c2090eSBill Fenner return; 182a1c2090eSBill Fenner bp += 8; 183a1c2090eSBill Fenner len -= 8; 184b0453382SBill Fenner 1853c602fabSXin LI ND_TCHECK2(bp[0], 4); 186b0453382SBill Fenner ngroups = bp[3]; 187a1c2090eSBill Fenner bp += 4; 188a1c2090eSBill Fenner len -= 4; 189b0453382SBill Fenner while (ngroups--) { 19029292c17SSam Leffler /* 19129292c17SSam Leffler * XXX - does the address have length "addrlen" and the 19229292c17SSam Leffler * mask length "maddrlen"? 19329292c17SSam Leffler */ 1943c602fabSXin LI ND_TCHECK2(bp[0], sizeof(struct in_addr)); 1953c602fabSXin LI ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp))); 1963c602fabSXin LI ND_TCHECK2(bp[4], sizeof(struct in_addr)); 197b0453382SBill Fenner if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) 1983c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[4]))); 1993c602fabSXin LI ND_TCHECK2(bp[8], 4); 200b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[8]); 201b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[10]); 2023c602fabSXin LI ND_PRINT((ndo, " joined: %d pruned: %d", njoin, nprune)); 203a1c2090eSBill Fenner bp += 12; 204a1c2090eSBill Fenner len -= 12; 205b0453382SBill Fenner for (njp = 0; njp < (njoin + nprune); njp++) { 206cc391cceSBruce M Simpson const char *type; 207b0453382SBill Fenner 208a1c2090eSBill Fenner if (njp < njoin) 209b0453382SBill Fenner type = "Join "; 210a1c2090eSBill Fenner else 211b0453382SBill Fenner type = "Prune"; 2123c602fabSXin LI ND_TCHECK2(bp[0], 6); 2133c602fabSXin LI ND_PRINT((ndo, "\n\t%s %s%s%s%s/%d", type, 214b0453382SBill Fenner (bp[0] & 0x01) ? "Sparse " : "Dense ", 215b0453382SBill Fenner (bp[1] & 0x80) ? "WC " : "", 216b0453382SBill Fenner (bp[1] & 0x40) ? "RP " : "SPT ", 2173c602fabSXin LI ipaddr_string(ndo, &bp[2]), bp[1] & 0x3f)); 218a1c2090eSBill Fenner bp += 6; 219a1c2090eSBill Fenner len -= 6; 220b0453382SBill Fenner } 221b0453382SBill Fenner } 222b0453382SBill Fenner return; 223b0453382SBill Fenner trunc: 2243c602fabSXin LI ND_PRINT((ndo, "[|pim]")); 225b0453382SBill Fenner return; 226b0453382SBill Fenner } 2274edb46e9SPaul Traina 2284edb46e9SPaul Traina void 2293c602fabSXin LI pimv1_print(netdissect_options *ndo, 2303c602fabSXin LI register const u_char *bp, register u_int len) 2314edb46e9SPaul Traina { 2324edb46e9SPaul Traina register const u_char *ep; 2334edb46e9SPaul Traina register u_char type; 2344edb46e9SPaul Traina 2353c602fabSXin LI ep = (const u_char *)ndo->ndo_snapend; 2364edb46e9SPaul Traina if (bp >= ep) 2374edb46e9SPaul Traina return; 2384edb46e9SPaul Traina 2393c602fabSXin LI ND_TCHECK(bp[1]); 2404edb46e9SPaul Traina type = bp[1]; 2414edb46e9SPaul Traina 2423c602fabSXin LI ND_PRINT((ndo, " %s", tok2str(pimv1_type_str, "[type %u]", type))); 2434edb46e9SPaul Traina switch (type) { 2443c602fabSXin LI case PIMV1_TYPE_QUERY: 2453c602fabSXin LI if (ND_TTEST(bp[8])) { 246b0453382SBill Fenner switch (bp[8] >> 4) { 247a1c2090eSBill Fenner case 0: 2483c602fabSXin LI ND_PRINT((ndo, " Dense-mode")); 249b0453382SBill Fenner break; 250a1c2090eSBill Fenner case 1: 2513c602fabSXin LI ND_PRINT((ndo, " Sparse-mode")); 252b0453382SBill Fenner break; 253a1c2090eSBill Fenner case 2: 2543c602fabSXin LI ND_PRINT((ndo, " Sparse-Dense-mode")); 255b0453382SBill Fenner break; 256a1c2090eSBill Fenner default: 2573c602fabSXin LI ND_PRINT((ndo, " mode-%d", bp[8] >> 4)); 258b0453382SBill Fenner break; 259b0453382SBill Fenner } 260b0453382SBill Fenner } 2613c602fabSXin LI if (ndo->ndo_vflag) { 2623c602fabSXin LI ND_TCHECK2(bp[10],2); 2633c602fabSXin LI ND_PRINT((ndo, " (Hold-time ")); 2643c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[10])); 2653c602fabSXin LI ND_PRINT((ndo, ")")); 266b0453382SBill Fenner } 2674edb46e9SPaul Traina break; 2684edb46e9SPaul Traina 2693c602fabSXin LI case PIMV1_TYPE_REGISTER: 2703c602fabSXin LI ND_TCHECK2(bp[8], 20); /* ip header */ 2713c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[20]), 2723c602fabSXin LI ipaddr_string(ndo, &bp[24]))); 2734edb46e9SPaul Traina break; 2743c602fabSXin LI case PIMV1_TYPE_REGISTER_STOP: 2753c602fabSXin LI ND_TCHECK2(bp[12], sizeof(struct in_addr)); 2763c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[8]), 2773c602fabSXin LI ipaddr_string(ndo, &bp[12]))); 2784edb46e9SPaul Traina break; 2793c602fabSXin LI case PIMV1_TYPE_RP_REACHABILITY: 2803c602fabSXin LI if (ndo->ndo_vflag) { 2813c602fabSXin LI ND_TCHECK2(bp[22], 2); 2823c602fabSXin LI ND_PRINT((ndo, " group %s", ipaddr_string(ndo, &bp[8]))); 283b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 2843c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); 2853c602fabSXin LI ND_PRINT((ndo, " RP %s hold ", ipaddr_string(ndo, &bp[16]))); 2863c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[22])); 287b0453382SBill Fenner } 2884edb46e9SPaul Traina break; 2893c602fabSXin LI case PIMV1_TYPE_ASSERT: 2903c602fabSXin LI ND_TCHECK2(bp[16], sizeof(struct in_addr)); 2913c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[16]), 2923c602fabSXin LI ipaddr_string(ndo, &bp[8]))); 293b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 2943c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); 2953c602fabSXin LI ND_TCHECK2(bp[24], 4); 2963c602fabSXin LI ND_PRINT((ndo, " %s pref %d metric %d", 297b0453382SBill Fenner (bp[20] & 0x80) ? "RP-tree" : "SPT", 298b0453382SBill Fenner EXTRACT_32BITS(&bp[20]) & 0x7fffffff, 2993c602fabSXin LI EXTRACT_32BITS(&bp[24]))); 3004edb46e9SPaul Traina break; 3013c602fabSXin LI case PIMV1_TYPE_JOIN_PRUNE: 3023c602fabSXin LI case PIMV1_TYPE_GRAFT: 3033c602fabSXin LI case PIMV1_TYPE_GRAFT_ACK: 3043c602fabSXin LI if (ndo->ndo_vflag) 3053c602fabSXin LI pimv1_join_prune_print(ndo, &bp[8], len - 8); 3064edb46e9SPaul Traina break; 3074edb46e9SPaul Traina } 308b0453382SBill Fenner if ((bp[4] >> 4) != 1) 3093c602fabSXin LI ND_PRINT((ndo, " [v%d]", bp[4] >> 4)); 310b0453382SBill Fenner return; 311b0453382SBill Fenner 312b0453382SBill Fenner trunc: 3133c602fabSXin LI ND_PRINT((ndo, "[|pim]")); 314b0453382SBill Fenner return; 315b0453382SBill Fenner } 316b0453382SBill Fenner 317b0453382SBill Fenner /* 318b0453382SBill Fenner * auto-RP is a cisco protocol, documented at 319a1c2090eSBill Fenner * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt 320a1c2090eSBill Fenner * 321a1c2090eSBill Fenner * This implements version 1+, dated Sept 9, 1998. 322b0453382SBill Fenner */ 323b0453382SBill Fenner void 3243c602fabSXin LI cisco_autorp_print(netdissect_options *ndo, 3253c602fabSXin LI register const u_char *bp, register u_int len) 326b0453382SBill Fenner { 327b0453382SBill Fenner int type; 328b0453382SBill Fenner int numrps; 329b0453382SBill Fenner int hold; 330b0453382SBill Fenner 3313c602fabSXin LI ND_TCHECK(bp[0]); 3323c602fabSXin LI ND_PRINT((ndo, " auto-rp ")); 333b0453382SBill Fenner type = bp[0]; 334b0453382SBill Fenner switch (type) { 335b0453382SBill Fenner case 0x11: 3363c602fabSXin LI ND_PRINT((ndo, "candidate-advert")); 337b0453382SBill Fenner break; 338b0453382SBill Fenner case 0x12: 3393c602fabSXin LI ND_PRINT((ndo, "mapping")); 340b0453382SBill Fenner break; 341b0453382SBill Fenner default: 3423c602fabSXin LI ND_PRINT((ndo, "type-0x%02x", type)); 343b0453382SBill Fenner break; 344b0453382SBill Fenner } 345b0453382SBill Fenner 3463c602fabSXin LI ND_TCHECK(bp[1]); 347b0453382SBill Fenner numrps = bp[1]; 348b0453382SBill Fenner 3493c602fabSXin LI ND_TCHECK2(bp[2], 2); 3503c602fabSXin LI ND_PRINT((ndo, " Hold ")); 351b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[2]); 352b0453382SBill Fenner if (hold) 3533c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[2])); 354b0453382SBill Fenner else 3553c602fabSXin LI ND_PRINT((ndo, "FOREVER")); 356b0453382SBill Fenner 357b0453382SBill Fenner /* Next 4 bytes are reserved. */ 358b0453382SBill Fenner 359b0453382SBill Fenner bp += 8; len -= 8; 360b0453382SBill Fenner 361b0453382SBill Fenner /*XXX skip unless -v? */ 362b0453382SBill Fenner 363b0453382SBill Fenner /* 364b0453382SBill Fenner * Rest of packet: 365b0453382SBill Fenner * numrps entries of the form: 366b0453382SBill Fenner * 32 bits: RP 367b0453382SBill Fenner * 6 bits: reserved 368b0453382SBill Fenner * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2". 369b0453382SBill Fenner * 8 bits: # of entries for this RP 370b0453382SBill Fenner * each entry: 7 bits: reserved, 1 bit: negative, 371b0453382SBill Fenner * 8 bits: mask 32 bits: source 372b0453382SBill Fenner * lather, rinse, repeat. 373b0453382SBill Fenner */ 374b0453382SBill Fenner while (numrps--) { 375b0453382SBill Fenner int nentries; 376b0453382SBill Fenner char s; 377b0453382SBill Fenner 3783c602fabSXin LI ND_TCHECK2(bp[0], 4); 3793c602fabSXin LI ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp))); 3803c602fabSXin LI ND_TCHECK(bp[4]); 381b0453382SBill Fenner switch (bp[4] & 0x3) { 3823c602fabSXin LI case 0: ND_PRINT((ndo, " PIMv?")); 383b0453382SBill Fenner break; 3843c602fabSXin LI case 1: ND_PRINT((ndo, " PIMv1")); 385b0453382SBill Fenner break; 3863c602fabSXin LI case 2: ND_PRINT((ndo, " PIMv2")); 387b0453382SBill Fenner break; 3883c602fabSXin LI case 3: ND_PRINT((ndo, " PIMv1+2")); 389b0453382SBill Fenner break; 390b0453382SBill Fenner } 391a1c2090eSBill Fenner if (bp[4] & 0xfc) 3923c602fabSXin LI ND_PRINT((ndo, " [rsvd=0x%02x]", bp[4] & 0xfc)); 3933c602fabSXin LI ND_TCHECK(bp[5]); 394b0453382SBill Fenner nentries = bp[5]; 395b0453382SBill Fenner bp += 6; len -= 6; 396b0453382SBill Fenner s = ' '; 397b0453382SBill Fenner for (; nentries; nentries--) { 3983c602fabSXin LI ND_TCHECK2(bp[0], 6); 3993c602fabSXin LI ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "", 4003c602fabSXin LI ipaddr_string(ndo, &bp[2]), bp[1])); 401cac3dcd5SXin LI if (bp[0] & 0x02) { 4023c602fabSXin LI ND_PRINT((ndo, " bidir")); 403cac3dcd5SXin LI } 404cac3dcd5SXin LI if (bp[0] & 0xfc) { 4053c602fabSXin LI ND_PRINT((ndo, "[rsvd=0x%02x]", bp[0] & 0xfc)); 406cac3dcd5SXin LI } 407b0453382SBill Fenner s = ','; 408b0453382SBill Fenner bp += 6; len -= 6; 409b0453382SBill Fenner } 410b0453382SBill Fenner } 411b0453382SBill Fenner return; 412b0453382SBill Fenner 413b0453382SBill Fenner trunc: 4143c602fabSXin LI ND_PRINT((ndo, "[|autorp]")); 415b0453382SBill Fenner return; 416b0453382SBill Fenner } 417b0453382SBill Fenner 418b0453382SBill Fenner void 4193c602fabSXin LI pim_print(netdissect_options *ndo, 4203c602fabSXin LI register const u_char *bp, register u_int len, u_int cksum) 421b0453382SBill Fenner { 422b0453382SBill Fenner register const u_char *ep; 423b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 424b0453382SBill Fenner 4253c602fabSXin LI ep = (const u_char *)ndo->ndo_snapend; 426b0453382SBill Fenner if (bp >= ep) 427b0453382SBill Fenner return; 428b0453382SBill Fenner #ifdef notyet /* currently we see only version and type */ 4293c602fabSXin LI ND_TCHECK(pim->pim_rsv); 430b0453382SBill Fenner #endif 431b0453382SBill Fenner 432b0453382SBill Fenner switch (PIM_VER(pim->pim_typever)) { 433c1ad1296SSam Leffler case 2: 4343c602fabSXin LI if (!ndo->ndo_vflag) { 4353c602fabSXin LI ND_PRINT((ndo, "PIMv%u, %s, length %u", 436c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 437c1ad1296SSam Leffler tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)), 4383c602fabSXin LI len)); 439c1ad1296SSam Leffler return; 440c1ad1296SSam Leffler } else { 4413c602fabSXin LI ND_PRINT((ndo, "PIMv%u, length %u\n\t%s", 442c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 443c1ad1296SSam Leffler len, 4443c602fabSXin LI tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)))); 4453c602fabSXin LI pimv2_print(ndo, bp, len, cksum); 446c1ad1296SSam Leffler } 447b0453382SBill Fenner break; 448b0453382SBill Fenner default: 4493c602fabSXin LI ND_PRINT((ndo, "PIMv%u, length %u", 450c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 4513c602fabSXin LI len)); 452b0453382SBill Fenner break; 453b0453382SBill Fenner } 454b0453382SBill Fenner return; 455b0453382SBill Fenner } 456b0453382SBill Fenner 457b0453382SBill Fenner /* 458b0453382SBill Fenner * PIMv2 uses encoded address representations. 459b0453382SBill Fenner * 460b0453382SBill Fenner * The last PIM-SM I-D before RFC2117 was published specified the 461b0453382SBill Fenner * following representation for unicast addresses. However, RFC2117 462b0453382SBill Fenner * specified no encoding for unicast addresses with the unicast 463b0453382SBill Fenner * address length specified in the header. Therefore, we have to 464b0453382SBill Fenner * guess which encoding is being used (Cisco's PIMv2 implementation 465b0453382SBill Fenner * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" 466b0453382SBill Fenner * field into a 'unicast-address-length-in-bytes' field. We guess 467b0453382SBill Fenner * that it's the draft encoding if this reserved field is zero. 468b0453382SBill Fenner * 469b0453382SBill Fenner * RFC2362 goes back to the encoded format, and calls the addr length 470b0453382SBill Fenner * field "reserved" again. 471b0453382SBill Fenner * 472b0453382SBill Fenner * The first byte is the address family, from: 473b0453382SBill Fenner * 474b0453382SBill Fenner * 0 Reserved 475b0453382SBill Fenner * 1 IP (IP version 4) 476b0453382SBill Fenner * 2 IP6 (IP version 6) 477b0453382SBill Fenner * 3 NSAP 478b0453382SBill Fenner * 4 HDLC (8-bit multidrop) 479b0453382SBill Fenner * 5 BBN 1822 480b0453382SBill Fenner * 6 802 (includes all 802 media plus Ethernet "canonical format") 481b0453382SBill Fenner * 7 E.163 482b0453382SBill Fenner * 8 E.164 (SMDS, Frame Relay, ATM) 483b0453382SBill Fenner * 9 F.69 (Telex) 484b0453382SBill Fenner * 10 X.121 (X.25, Frame Relay) 485b0453382SBill Fenner * 11 IPX 486b0453382SBill Fenner * 12 Appletalk 487b0453382SBill Fenner * 13 Decnet IV 488b0453382SBill Fenner * 14 Banyan Vines 489b0453382SBill Fenner * 15 E.164 with NSAP format subaddress 490b0453382SBill Fenner * 491b0453382SBill Fenner * In addition, the second byte is an "Encoding". 0 is the default 492b0453382SBill Fenner * encoding for the address family, and no other encodings are currently 493b0453382SBill Fenner * specified. 494b0453382SBill Fenner * 495b0453382SBill Fenner */ 496b0453382SBill Fenner 497b0453382SBill Fenner static int pimv2_addr_len; 498b0453382SBill Fenner 499b0453382SBill Fenner enum pimv2_addrtype { 500b0453382SBill Fenner pimv2_unicast, pimv2_group, pimv2_source 501b0453382SBill Fenner }; 502b0453382SBill Fenner 503b0453382SBill Fenner /* 0 1 2 3 504b0453382SBill 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 505b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 506b0453382SBill Fenner * | Addr Family | Encoding Type | Unicast Address | 507b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ 508b0453382SBill Fenner * 0 1 2 3 509b0453382SBill 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 510b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 511b0453382SBill Fenner * | Addr Family | Encoding Type | Reserved | Mask Len | 512b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 513b0453382SBill Fenner * | Group multicast Address | 514b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 515b0453382SBill Fenner * 0 1 2 3 516b0453382SBill 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 517b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 518b0453382SBill Fenner * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | 519b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 520b0453382SBill Fenner * | Source Address | 521b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 522b0453382SBill Fenner */ 523b0453382SBill Fenner static int 5243c602fabSXin LI pimv2_addr_print(netdissect_options *ndo, 5253c602fabSXin LI const u_char *bp, enum pimv2_addrtype at, int silent) 526b0453382SBill Fenner { 527b0453382SBill Fenner int af; 528b0453382SBill Fenner int len, hdrlen; 529b0453382SBill Fenner 5303c602fabSXin LI ND_TCHECK(bp[0]); 531b0453382SBill Fenner 532b0453382SBill Fenner if (pimv2_addr_len == 0) { 5333c602fabSXin LI ND_TCHECK(bp[1]); 534b0453382SBill Fenner switch (bp[0]) { 535b0453382SBill Fenner case 1: 536b0453382SBill Fenner af = AF_INET; 53717cb103cSSam Leffler len = sizeof(struct in_addr); 538b0453382SBill Fenner break; 539b0453382SBill Fenner #ifdef INET6 540b0453382SBill Fenner case 2: 541b0453382SBill Fenner af = AF_INET6; 54217cb103cSSam Leffler len = sizeof(struct in6_addr); 543b0453382SBill Fenner break; 544b0453382SBill Fenner #endif 545b0453382SBill Fenner default: 546b0453382SBill Fenner return -1; 547b0453382SBill Fenner } 548b0453382SBill Fenner if (bp[1] != 0) 549b0453382SBill Fenner return -1; 550b0453382SBill Fenner hdrlen = 2; 551b0453382SBill Fenner } else { 552b0453382SBill Fenner switch (pimv2_addr_len) { 55317cb103cSSam Leffler case sizeof(struct in_addr): 554b0453382SBill Fenner af = AF_INET; 555b0453382SBill Fenner break; 556b0453382SBill Fenner #ifdef INET6 55717cb103cSSam Leffler case sizeof(struct in6_addr): 558b0453382SBill Fenner af = AF_INET6; 559b0453382SBill Fenner break; 560b0453382SBill Fenner #endif 561b0453382SBill Fenner default: 562b0453382SBill Fenner return -1; 563b0453382SBill Fenner break; 564b0453382SBill Fenner } 565b0453382SBill Fenner len = pimv2_addr_len; 566b0453382SBill Fenner hdrlen = 0; 567b0453382SBill Fenner } 568b0453382SBill Fenner 569b0453382SBill Fenner bp += hdrlen; 570b0453382SBill Fenner switch (at) { 571b0453382SBill Fenner case pimv2_unicast: 5723c602fabSXin LI ND_TCHECK2(bp[0], len); 573b0453382SBill Fenner if (af == AF_INET) { 574b0453382SBill Fenner if (!silent) 5753c602fabSXin LI ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp))); 576b0453382SBill Fenner } 577b0453382SBill Fenner #ifdef INET6 578b0453382SBill Fenner else if (af == AF_INET6) { 579b0453382SBill Fenner if (!silent) 5803c602fabSXin LI ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp))); 581b0453382SBill Fenner } 582b0453382SBill Fenner #endif 583b0453382SBill Fenner return hdrlen + len; 584b0453382SBill Fenner case pimv2_group: 585b0453382SBill Fenner case pimv2_source: 5863c602fabSXin LI ND_TCHECK2(bp[0], len + 2); 587b0453382SBill Fenner if (af == AF_INET) { 588b0453382SBill Fenner if (!silent) { 5893c602fabSXin LI ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2))); 590b0453382SBill Fenner if (bp[1] != 32) 5913c602fabSXin LI ND_PRINT((ndo, "/%u", bp[1])); 592b0453382SBill Fenner } 593b0453382SBill Fenner } 594b0453382SBill Fenner #ifdef INET6 595b0453382SBill Fenner else if (af == AF_INET6) { 596b0453382SBill Fenner if (!silent) { 5973c602fabSXin LI ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp + 2))); 598b0453382SBill Fenner if (bp[1] != 128) 5993c602fabSXin LI ND_PRINT((ndo, "/%u", bp[1])); 600b0453382SBill Fenner } 601b0453382SBill Fenner } 602b0453382SBill Fenner #endif 603b0453382SBill Fenner if (bp[0] && !silent) { 604b0453382SBill Fenner if (at == pimv2_group) { 6053c602fabSXin LI ND_PRINT((ndo, "(0x%02x)", bp[0])); 606b0453382SBill Fenner } else { 6073c602fabSXin LI ND_PRINT((ndo, "(%s%s%s", 608b0453382SBill Fenner bp[0] & 0x04 ? "S" : "", 609b0453382SBill Fenner bp[0] & 0x02 ? "W" : "", 6103c602fabSXin LI bp[0] & 0x01 ? "R" : "")); 611b0453382SBill Fenner if (bp[0] & 0xf8) { 6123c602fabSXin LI ND_PRINT((ndo, "+0x%02x", bp[0] & 0xf8)); 613b0453382SBill Fenner } 6143c602fabSXin LI ND_PRINT((ndo, ")")); 615b0453382SBill Fenner } 616b0453382SBill Fenner } 617b0453382SBill Fenner return hdrlen + 2 + len; 618b0453382SBill Fenner default: 619b0453382SBill Fenner return -1; 620b0453382SBill Fenner } 621b0453382SBill Fenner trunc: 622b0453382SBill Fenner return -1; 623b0453382SBill Fenner } 624b0453382SBill Fenner 625b0453382SBill Fenner static void 6263c602fabSXin LI pimv2_print(netdissect_options *ndo, 6273c602fabSXin LI register const u_char *bp, register u_int len, u_int cksum) 628b0453382SBill Fenner { 629b0453382SBill Fenner register const u_char *ep; 630b0453382SBill Fenner register struct pim *pim = (struct pim *)bp; 631b0453382SBill Fenner int advance; 632b0453382SBill Fenner 6333c602fabSXin LI ep = (const u_char *)ndo->ndo_snapend; 634b0453382SBill Fenner if (bp >= ep) 635b0453382SBill Fenner return; 6369537d84eSBill Fenner if (ep > bp + len) 6379537d84eSBill Fenner ep = bp + len; 6383c602fabSXin LI ND_TCHECK(pim->pim_rsv); 639b0453382SBill Fenner pimv2_addr_len = pim->pim_rsv; 640b0453382SBill Fenner if (pimv2_addr_len != 0) 6413c602fabSXin LI ND_PRINT((ndo, ", RFC2117-encoding")); 642b0453382SBill Fenner 6433c602fabSXin LI ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum))); 644abf25193SMax Laier if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { 6453c602fabSXin LI ND_PRINT((ndo, "(unverified)")); 646abf25193SMax Laier } else { 6473c602fabSXin LI ND_PRINT((ndo, "(%scorrect)", ND_TTEST2(bp[0], len) && cksum ? "in" : "" )); 648abf25193SMax Laier } 649abf25193SMax Laier 650b0453382SBill Fenner switch (PIM_TYPE(pim->pim_typever)) { 651c1ad1296SSam Leffler case PIMV2_TYPE_HELLO: 652b0453382SBill Fenner { 6533c602fabSXin LI uint16_t otype, olen; 654b0453382SBill Fenner bp += 4; 655b0453382SBill Fenner while (bp < ep) { 6563c602fabSXin LI ND_TCHECK2(bp[0], 4); 657b0453382SBill Fenner otype = EXTRACT_16BITS(&bp[0]); 658b0453382SBill Fenner olen = EXTRACT_16BITS(&bp[2]); 6593c602fabSXin LI ND_TCHECK2(bp[0], 4 + olen); 6603c602fabSXin LI ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ", 661c1ad1296SSam Leffler tok2str(pimv2_hello_option_values, "Unknown", otype), 662c1ad1296SSam Leffler otype, 6633c602fabSXin LI olen)); 664c1ad1296SSam Leffler bp += 4; 665c1ad1296SSam Leffler 666b0453382SBill Fenner switch (otype) { 667c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_HOLDTIME: 6683c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(bp)); 669b0453382SBill Fenner break; 670b0453382SBill Fenner 671c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_LANPRUNEDELAY: 672cc391cceSBruce M Simpson if (olen != 4) { 6733c602fabSXin LI ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); 674cc391cceSBruce M Simpson } else { 675cc391cceSBruce M Simpson char t_bit; 6763c602fabSXin LI uint16_t lan_delay, override_interval; 677c1ad1296SSam Leffler lan_delay = EXTRACT_16BITS(bp); 678c1ad1296SSam Leffler override_interval = EXTRACT_16BITS(bp+2); 679cc391cceSBruce M Simpson t_bit = (lan_delay & 0x8000)? 1 : 0; 680cc391cceSBruce M Simpson lan_delay &= ~0x8000; 6813c602fabSXin LI ND_PRINT((ndo, "\n\t T-bit=%d, LAN delay %dms, Override interval %dms", 6823c602fabSXin LI t_bit, lan_delay, override_interval)); 683cc391cceSBruce M Simpson } 684cc391cceSBruce M Simpson break; 685cc391cceSBruce M Simpson 686c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_DR_PRIORITY_OLD: 687c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_DR_PRIORITY: 688c1ad1296SSam Leffler switch (olen) { 689c1ad1296SSam Leffler case 0: 6903c602fabSXin LI ND_PRINT((ndo, "Bi-Directional Capability (Old)")); 6910e0def19SBill Fenner break; 692c1ad1296SSam Leffler case 4: 6933c602fabSXin LI ND_PRINT((ndo, "%u", EXTRACT_32BITS(bp))); 694c1ad1296SSam Leffler break; 695c1ad1296SSam Leffler default: 6963c602fabSXin LI ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); 6970e0def19SBill Fenner break; 6980e0def19SBill Fenner } 699c1ad1296SSam Leffler break; 700c1ad1296SSam Leffler 701c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_GENID: 7023c602fabSXin LI ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp))); 703c1ad1296SSam Leffler break; 704c1ad1296SSam Leffler 705c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_REFRESH_CAP: 7063c602fabSXin LI ND_PRINT((ndo, "v%d", *bp)); 707c1ad1296SSam Leffler if (*(bp+1) != 0) { 7083c602fabSXin LI ND_PRINT((ndo, ", interval ")); 7093c602fabSXin LI relts_print(ndo, *(bp+1)); 710c1ad1296SSam Leffler } 711c1ad1296SSam Leffler if (EXTRACT_16BITS(bp+2) != 0) { 7123c602fabSXin LI ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2))); 713a1c2090eSBill Fenner } 714b0453382SBill Fenner break; 715b0453382SBill Fenner 716c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_BIDIR_CAP: 717b0453382SBill Fenner break; 718b0453382SBill Fenner 719c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD: 720c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_ADDRESS_LIST: 7213c602fabSXin LI if (ndo->ndo_vflag > 1) { 722c1ad1296SSam Leffler const u_char *ptr = bp; 723c1ad1296SSam Leffler while (ptr < (bp+olen)) { 724cc391cceSBruce M Simpson int advance; 725cc391cceSBruce M Simpson 7263c602fabSXin LI ND_PRINT((ndo, "\n\t ")); 7273c602fabSXin LI advance = pimv2_addr_print(ndo, ptr, pimv2_unicast, 0); 728cc391cceSBruce M Simpson if (advance < 0) { 7293c602fabSXin LI ND_PRINT((ndo, "...")); 730cc391cceSBruce M Simpson break; 731cc391cceSBruce M Simpson } 732cc391cceSBruce M Simpson ptr += advance; 733cc391cceSBruce M Simpson } 734cc391cceSBruce M Simpson } 735cc391cceSBruce M Simpson break; 736b0453382SBill Fenner default: 7373c602fabSXin LI if (ndo->ndo_vflag <= 1) 7383c602fabSXin LI print_unknown_data(ndo, bp, "\n\t ", olen); 739c1ad1296SSam Leffler break; 740b0453382SBill Fenner } 741c1ad1296SSam Leffler /* do we want to see an additionally hexdump ? */ 7423c602fabSXin LI if (ndo->ndo_vflag> 1) 7433c602fabSXin LI print_unknown_data(ndo, bp, "\n\t ", olen); 744c1ad1296SSam Leffler bp += olen; 745b0453382SBill Fenner } 746b0453382SBill Fenner break; 747b0453382SBill Fenner } 748b0453382SBill Fenner 749c1ad1296SSam Leffler case PIMV2_TYPE_REGISTER: 750b0453382SBill Fenner { 751b0453382SBill Fenner struct ip *ip; 752b0453382SBill Fenner 7533c602fabSXin LI ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN); 754b0453382SBill Fenner 7553c602fabSXin LI ND_PRINT((ndo, ", Flags [ %s ]\n\t", 756abf25193SMax Laier tok2str(pimv2_register_flag_values, 757abf25193SMax Laier "none", 7583c602fabSXin LI EXTRACT_32BITS(bp+4)))); 759abf25193SMax Laier 760abf25193SMax Laier bp += 8; len -= 8; 761b0453382SBill Fenner /* encapsulated multicast packet */ 762b0453382SBill Fenner ip = (struct ip *)bp; 763943ee2b1SBill Fenner switch (IP_V(ip)) { 764abf25193SMax Laier case 0: /* Null header */ 7653c602fabSXin LI ND_PRINT((ndo, "IP-Null-header %s > %s", 7663c602fabSXin LI ipaddr_string(ndo, &ip->ip_src), 7673c602fabSXin LI ipaddr_string(ndo, &ip->ip_dst))); 768abf25193SMax Laier break; 769abf25193SMax Laier 770b0453382SBill Fenner case 4: /* IPv4 */ 7713c602fabSXin LI ip_print(ndo, bp, len); 772b0453382SBill Fenner break; 773*8bdc5a62SPatrick Kelsey 774b0453382SBill Fenner case 6: /* IPv6 */ 7753c602fabSXin LI ip6_print(ndo, bp, len); 776b0453382SBill Fenner break; 777*8bdc5a62SPatrick Kelsey 778b0453382SBill Fenner default: 7793c602fabSXin LI ND_PRINT((ndo, "IP ver %d", IP_V(ip))); 780b0453382SBill Fenner break; 781b0453382SBill Fenner } 782b0453382SBill Fenner break; 783b0453382SBill Fenner } 784b0453382SBill Fenner 785c1ad1296SSam Leffler case PIMV2_TYPE_REGISTER_STOP: 786b0453382SBill Fenner bp += 4; len -= 4; 787b0453382SBill Fenner if (bp >= ep) 788b0453382SBill Fenner break; 7893c602fabSXin LI ND_PRINT((ndo, " group=")); 7903c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 7913c602fabSXin LI ND_PRINT((ndo, "...")); 792b0453382SBill Fenner break; 793b0453382SBill Fenner } 794b0453382SBill Fenner bp += advance; len -= advance; 795b0453382SBill Fenner if (bp >= ep) 796b0453382SBill Fenner break; 7973c602fabSXin LI ND_PRINT((ndo, " source=")); 7983c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 7993c602fabSXin LI ND_PRINT((ndo, "...")); 800b0453382SBill Fenner break; 801b0453382SBill Fenner } 802b0453382SBill Fenner bp += advance; len -= advance; 803b0453382SBill Fenner break; 804b0453382SBill Fenner 805c1ad1296SSam Leffler case PIMV2_TYPE_JOIN_PRUNE: 806c1ad1296SSam Leffler case PIMV2_TYPE_GRAFT: 807c1ad1296SSam Leffler case PIMV2_TYPE_GRAFT_ACK: 808c1ad1296SSam Leffler 809c1ad1296SSam Leffler 810c1ad1296SSam Leffler /* 811c1ad1296SSam Leffler * 0 1 2 3 812c1ad1296SSam Leffler * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 813c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 814c1ad1296SSam Leffler * |PIM Ver| Type | Addr length | Checksum | 815c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 816c1ad1296SSam Leffler * | Unicast-Upstream Neighbor Address | 817c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 818c1ad1296SSam Leffler * | Reserved | Num groups | Holdtime | 819c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 820c1ad1296SSam Leffler * | Encoded-Multicast Group Address-1 | 821c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 822c1ad1296SSam Leffler * | Number of Joined Sources | Number of Pruned Sources | 823c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 824c1ad1296SSam Leffler * | Encoded-Joined Source Address-1 | 825c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 826c1ad1296SSam Leffler * | . | 827c1ad1296SSam Leffler * | . | 828c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 829c1ad1296SSam Leffler * | Encoded-Joined Source Address-n | 830c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 831c1ad1296SSam Leffler * | Encoded-Pruned Source Address-1 | 832c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 833c1ad1296SSam Leffler * | . | 834c1ad1296SSam Leffler * | . | 835c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 836c1ad1296SSam Leffler * | Encoded-Pruned Source Address-n | 837c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 838c1ad1296SSam Leffler * | . | 839c1ad1296SSam Leffler * | . | 840c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 841c1ad1296SSam Leffler * | Encoded-Multicast Group Address-n | 842c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 843c1ad1296SSam Leffler */ 844c1ad1296SSam Leffler 845b0453382SBill Fenner { 8463c602fabSXin LI uint8_t ngroup; 8473c602fabSXin LI uint16_t holdtime; 8483c602fabSXin LI uint16_t njoin; 8493c602fabSXin LI uint16_t nprune; 850b0453382SBill Fenner int i, j; 851b0453382SBill Fenner 852b0453382SBill Fenner bp += 4; len -= 4; 853b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 854b0453382SBill Fenner if (bp >= ep) 855b0453382SBill Fenner break; 8563c602fabSXin LI ND_PRINT((ndo, ", upstream-neighbor: ")); 8573c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 8583c602fabSXin LI ND_PRINT((ndo, "...")); 859b0453382SBill Fenner break; 860b0453382SBill Fenner } 861b0453382SBill Fenner bp += advance; len -= advance; 862b0453382SBill Fenner } 863b0453382SBill Fenner if (bp + 4 > ep) 864b0453382SBill Fenner break; 865b0453382SBill Fenner ngroup = bp[1]; 866b0453382SBill Fenner holdtime = EXTRACT_16BITS(&bp[2]); 8673c602fabSXin LI ND_PRINT((ndo, "\n\t %u group(s)", ngroup)); 868b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 8693c602fabSXin LI ND_PRINT((ndo, ", holdtime: ")); 870b0453382SBill Fenner if (holdtime == 0xffff) 8713c602fabSXin LI ND_PRINT((ndo, "infinite")); 872b0453382SBill Fenner else 8733c602fabSXin LI relts_print(ndo, holdtime); 874b0453382SBill Fenner } 875b0453382SBill Fenner bp += 4; len -= 4; 876b0453382SBill Fenner for (i = 0; i < ngroup; i++) { 877b0453382SBill Fenner if (bp >= ep) 878b0453382SBill Fenner goto jp_done; 8793c602fabSXin LI ND_PRINT((ndo, "\n\t group #%u: ", i+1)); 8803c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 8813c602fabSXin LI ND_PRINT((ndo, "...)")); 882b0453382SBill Fenner goto jp_done; 883b0453382SBill Fenner } 884b0453382SBill Fenner bp += advance; len -= advance; 885b0453382SBill Fenner if (bp + 4 > ep) { 8863c602fabSXin LI ND_PRINT((ndo, "...)")); 887b0453382SBill Fenner goto jp_done; 888b0453382SBill Fenner } 889b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[0]); 890b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[2]); 8913c602fabSXin LI ND_PRINT((ndo, ", joined sources: %u, pruned sources: %u", njoin, nprune)); 892b0453382SBill Fenner bp += 4; len -= 4; 893b0453382SBill Fenner for (j = 0; j < njoin; j++) { 8943c602fabSXin LI ND_PRINT((ndo, "\n\t joined source #%u: ", j+1)); 8953c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) { 8963c602fabSXin LI ND_PRINT((ndo, "...)")); 897b0453382SBill Fenner goto jp_done; 898b0453382SBill Fenner } 899b0453382SBill Fenner bp += advance; len -= advance; 900b0453382SBill Fenner } 901b0453382SBill Fenner for (j = 0; j < nprune; j++) { 9023c602fabSXin LI ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1)); 9033c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) { 9043c602fabSXin LI ND_PRINT((ndo, "...)")); 905b0453382SBill Fenner goto jp_done; 906b0453382SBill Fenner } 907b0453382SBill Fenner bp += advance; len -= advance; 908b0453382SBill Fenner } 909b0453382SBill Fenner } 910b0453382SBill Fenner jp_done: 911b0453382SBill Fenner break; 912b0453382SBill Fenner } 913b0453382SBill Fenner 914c1ad1296SSam Leffler case PIMV2_TYPE_BOOTSTRAP: 915b0453382SBill Fenner { 916b0453382SBill Fenner int i, j, frpcnt; 917b0453382SBill Fenner bp += 4; 918b0453382SBill Fenner 919b0453382SBill Fenner /* Fragment Tag, Hash Mask len, and BSR-priority */ 9203c602fabSXin LI if (bp + sizeof(uint16_t) >= ep) break; 9213c602fabSXin LI ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp))); 9223c602fabSXin LI bp += sizeof(uint16_t); 923b0453382SBill Fenner if (bp >= ep) break; 9243c602fabSXin LI ND_PRINT((ndo, " hashmlen=%d", bp[0])); 925b0453382SBill Fenner if (bp + 1 >= ep) break; 9263c602fabSXin LI ND_PRINT((ndo, " BSRprio=%d", bp[1])); 927b0453382SBill Fenner bp += 2; 928b0453382SBill Fenner 929b0453382SBill Fenner /* Encoded-Unicast-BSR-Address */ 930b0453382SBill Fenner if (bp >= ep) break; 9313c602fabSXin LI ND_PRINT((ndo, " BSR=")); 9323c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 9333c602fabSXin LI ND_PRINT((ndo, "...")); 934b0453382SBill Fenner break; 935b0453382SBill Fenner } 936b0453382SBill Fenner bp += advance; 937b0453382SBill Fenner 938b0453382SBill Fenner for (i = 0; bp < ep; i++) { 939b0453382SBill Fenner /* Encoded-Group Address */ 9403c602fabSXin LI ND_PRINT((ndo, " (group%d: ", i)); 9413c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) 942b0453382SBill Fenner < 0) { 9433c602fabSXin LI ND_PRINT((ndo, "...)")); 944b0453382SBill Fenner goto bs_done; 945b0453382SBill Fenner } 946b0453382SBill Fenner bp += advance; 947b0453382SBill Fenner 948b0453382SBill Fenner /* RP-Count, Frag RP-Cnt, and rsvd */ 949b0453382SBill Fenner if (bp >= ep) { 9503c602fabSXin LI ND_PRINT((ndo, "...)")); 951b0453382SBill Fenner goto bs_done; 952b0453382SBill Fenner } 9533c602fabSXin LI ND_PRINT((ndo, " RPcnt=%d", bp[0])); 954b0453382SBill Fenner if (bp + 1 >= ep) { 9553c602fabSXin LI ND_PRINT((ndo, "...)")); 956b0453382SBill Fenner goto bs_done; 957b0453382SBill Fenner } 9583c602fabSXin LI ND_PRINT((ndo, " FRPcnt=%d", frpcnt = bp[1])); 959b0453382SBill Fenner bp += 4; 960b0453382SBill Fenner 961b0453382SBill Fenner for (j = 0; j < frpcnt && bp < ep; j++) { 962b0453382SBill Fenner /* each RP info */ 9633c602fabSXin LI ND_PRINT((ndo, " RP%d=", j)); 9643c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, 965b0453382SBill Fenner pimv2_unicast, 966b0453382SBill Fenner 0)) < 0) { 9673c602fabSXin LI ND_PRINT((ndo, "...)")); 968b0453382SBill Fenner goto bs_done; 969b0453382SBill Fenner } 970b0453382SBill Fenner bp += advance; 971b0453382SBill Fenner 972b0453382SBill Fenner if (bp + 1 >= ep) { 9733c602fabSXin LI ND_PRINT((ndo, "...)")); 974b0453382SBill Fenner goto bs_done; 975b0453382SBill Fenner } 9763c602fabSXin LI ND_PRINT((ndo, ",holdtime=")); 9773c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(bp)); 978b0453382SBill Fenner if (bp + 2 >= ep) { 9793c602fabSXin LI ND_PRINT((ndo, "...)")); 980b0453382SBill Fenner goto bs_done; 981b0453382SBill Fenner } 9823c602fabSXin LI ND_PRINT((ndo, ",prio=%d", bp[2])); 983b0453382SBill Fenner bp += 4; 984b0453382SBill Fenner } 9853c602fabSXin LI ND_PRINT((ndo, ")")); 986b0453382SBill Fenner } 987b0453382SBill Fenner bs_done: 988b0453382SBill Fenner break; 989b0453382SBill Fenner } 990c1ad1296SSam Leffler case PIMV2_TYPE_ASSERT: 991b0453382SBill Fenner bp += 4; len -= 4; 992b0453382SBill Fenner if (bp >= ep) 993b0453382SBill Fenner break; 9943c602fabSXin LI ND_PRINT((ndo, " group=")); 9953c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 9963c602fabSXin LI ND_PRINT((ndo, "...")); 997b0453382SBill Fenner break; 998b0453382SBill Fenner } 999b0453382SBill Fenner bp += advance; len -= advance; 1000b0453382SBill Fenner if (bp >= ep) 1001b0453382SBill Fenner break; 10023c602fabSXin LI ND_PRINT((ndo, " src=")); 10033c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 10043c602fabSXin LI ND_PRINT((ndo, "...")); 1005b0453382SBill Fenner break; 1006b0453382SBill Fenner } 1007b0453382SBill Fenner bp += advance; len -= advance; 1008b0453382SBill Fenner if (bp + 8 > ep) 1009b0453382SBill Fenner break; 1010b0453382SBill Fenner if (bp[0] & 0x80) 10113c602fabSXin LI ND_PRINT((ndo, " RPT")); 10123c602fabSXin LI ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff)); 10133c602fabSXin LI ND_PRINT((ndo, " metric=%u", EXTRACT_32BITS(&bp[4]))); 1014b0453382SBill Fenner break; 1015b0453382SBill Fenner 1016c1ad1296SSam Leffler case PIMV2_TYPE_CANDIDATE_RP: 1017b0453382SBill Fenner { 1018b0453382SBill Fenner int i, pfxcnt; 1019b0453382SBill Fenner bp += 4; 1020b0453382SBill Fenner 1021b0453382SBill Fenner /* Prefix-Cnt, Priority, and Holdtime */ 1022b0453382SBill Fenner if (bp >= ep) break; 10233c602fabSXin LI ND_PRINT((ndo, " prefix-cnt=%d", bp[0])); 1024b0453382SBill Fenner pfxcnt = bp[0]; 1025b0453382SBill Fenner if (bp + 1 >= ep) break; 10263c602fabSXin LI ND_PRINT((ndo, " prio=%d", bp[1])); 1027b0453382SBill Fenner if (bp + 3 >= ep) break; 10283c602fabSXin LI ND_PRINT((ndo, " holdtime=")); 10293c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[2])); 1030b0453382SBill Fenner bp += 4; 1031b0453382SBill Fenner 1032b0453382SBill Fenner /* Encoded-Unicast-RP-Address */ 1033b0453382SBill Fenner if (bp >= ep) break; 10343c602fabSXin LI ND_PRINT((ndo, " RP=")); 10353c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 10363c602fabSXin LI ND_PRINT((ndo, "...")); 1037b0453382SBill Fenner break; 1038b0453382SBill Fenner } 1039b0453382SBill Fenner bp += advance; 1040b0453382SBill Fenner 1041b0453382SBill Fenner /* Encoded-Group Addresses */ 1042b0453382SBill Fenner for (i = 0; i < pfxcnt && bp < ep; i++) { 10433c602fabSXin LI ND_PRINT((ndo, " Group%d=", i)); 10443c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) 1045b0453382SBill Fenner < 0) { 10463c602fabSXin LI ND_PRINT((ndo, "...")); 1047b0453382SBill Fenner break; 1048b0453382SBill Fenner } 1049b0453382SBill Fenner bp += advance; 1050b0453382SBill Fenner } 1051b0453382SBill Fenner break; 1052b0453382SBill Fenner } 1053b0453382SBill Fenner 1054c1ad1296SSam Leffler case PIMV2_TYPE_PRUNE_REFRESH: 10553c602fabSXin LI ND_PRINT((ndo, " src=")); 10563c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 10573c602fabSXin LI ND_PRINT((ndo, "...")); 1058b0453382SBill Fenner break; 1059b0453382SBill Fenner } 1060b0453382SBill Fenner bp += advance; 10613c602fabSXin LI ND_PRINT((ndo, " grp=")); 10623c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 10633c602fabSXin LI ND_PRINT((ndo, "...")); 1064b0453382SBill Fenner break; 1065b0453382SBill Fenner } 1066b0453382SBill Fenner bp += advance; 10673c602fabSXin LI ND_PRINT((ndo, " forwarder=")); 10683c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 10693c602fabSXin LI ND_PRINT((ndo, "...")); 1070b0453382SBill Fenner break; 1071b0453382SBill Fenner } 1072b0453382SBill Fenner bp += advance; 10733c602fabSXin LI ND_TCHECK2(bp[0], 2); 10743c602fabSXin LI ND_PRINT((ndo, " TUNR ")); 10753c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(bp)); 1076b0453382SBill Fenner break; 1077b0453382SBill Fenner 1078b0453382SBill Fenner 1079b0453382SBill Fenner default: 10803c602fabSXin LI ND_PRINT((ndo, " [type %d]", PIM_TYPE(pim->pim_typever))); 1081b0453382SBill Fenner break; 1082b0453382SBill Fenner } 1083b0453382SBill Fenner 1084b0453382SBill Fenner return; 1085b0453382SBill Fenner 1086b0453382SBill Fenner trunc: 10873c602fabSXin LI ND_PRINT((ndo, "[|pim]")); 10884edb46e9SPaul Traina } 1089c1ad1296SSam Leffler 1090c1ad1296SSam Leffler /* 1091c1ad1296SSam Leffler * Local Variables: 1092c1ad1296SSam Leffler * c-style: whitesmith 1093c1ad1296SSam Leffler * c-basic-offset: 8 1094c1ad1296SSam Leffler * End: 1095c1ad1296SSam Leffler */ 1096