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. 204edb46e9SPaul Traina */ 214edb46e9SPaul Traina 223340d773SGleb Smirnoff /* \summary: Protocol Independent Multicast (PIM) printer */ 233340d773SGleb Smirnoff 24b0453382SBill Fenner #ifdef HAVE_CONFIG_H 25b0453382SBill Fenner #include "config.h" 264edb46e9SPaul Traina #endif 274edb46e9SPaul Traina 283340d773SGleb Smirnoff #include <netdissect-stdinc.h> 29cac3dcd5SXin LI 303340d773SGleb Smirnoff #include "netdissect.h" 31cac3dcd5SXin LI #include "addrtoname.h" 32cac3dcd5SXin LI #include "extract.h" 33cac3dcd5SXin LI 34cac3dcd5SXin LI #include "ip.h" 353340d773SGleb Smirnoff #include "ip6.h" 363340d773SGleb Smirnoff #include "ipproto.h" 37c1ad1296SSam Leffler 383c602fabSXin LI #define PIMV1_TYPE_QUERY 0 393c602fabSXin LI #define PIMV1_TYPE_REGISTER 1 403c602fabSXin LI #define PIMV1_TYPE_REGISTER_STOP 2 413c602fabSXin LI #define PIMV1_TYPE_JOIN_PRUNE 3 423c602fabSXin LI #define PIMV1_TYPE_RP_REACHABILITY 4 433c602fabSXin LI #define PIMV1_TYPE_ASSERT 5 443c602fabSXin LI #define PIMV1_TYPE_GRAFT 6 453c602fabSXin LI #define PIMV1_TYPE_GRAFT_ACK 7 463c602fabSXin LI 473c602fabSXin LI static const struct tok pimv1_type_str[] = { 483c602fabSXin LI { PIMV1_TYPE_QUERY, "Query" }, 493c602fabSXin LI { PIMV1_TYPE_REGISTER, "Register" }, 503c602fabSXin LI { PIMV1_TYPE_REGISTER_STOP, "Register-Stop" }, 513c602fabSXin LI { PIMV1_TYPE_JOIN_PRUNE, "Join/Prune" }, 523c602fabSXin LI { PIMV1_TYPE_RP_REACHABILITY, "RP-reachable" }, 533c602fabSXin LI { PIMV1_TYPE_ASSERT, "Assert" }, 543c602fabSXin LI { PIMV1_TYPE_GRAFT, "Graft" }, 553c602fabSXin LI { PIMV1_TYPE_GRAFT_ACK, "Graft-ACK" }, 563c602fabSXin LI { 0, NULL } 573c602fabSXin LI }; 583c602fabSXin LI 59c1ad1296SSam Leffler #define PIMV2_TYPE_HELLO 0 60c1ad1296SSam Leffler #define PIMV2_TYPE_REGISTER 1 61c1ad1296SSam Leffler #define PIMV2_TYPE_REGISTER_STOP 2 62c1ad1296SSam Leffler #define PIMV2_TYPE_JOIN_PRUNE 3 63c1ad1296SSam Leffler #define PIMV2_TYPE_BOOTSTRAP 4 64c1ad1296SSam Leffler #define PIMV2_TYPE_ASSERT 5 65c1ad1296SSam Leffler #define PIMV2_TYPE_GRAFT 6 66c1ad1296SSam Leffler #define PIMV2_TYPE_GRAFT_ACK 7 67c1ad1296SSam Leffler #define PIMV2_TYPE_CANDIDATE_RP 8 68c1ad1296SSam Leffler #define PIMV2_TYPE_PRUNE_REFRESH 9 693c602fabSXin LI #define PIMV2_TYPE_DF_ELECTION 10 703c602fabSXin LI #define PIMV2_TYPE_ECMP_REDIRECT 11 71c1ad1296SSam Leffler 723c602fabSXin LI static const struct tok pimv2_type_values[] = { 73c1ad1296SSam Leffler { PIMV2_TYPE_HELLO, "Hello" }, 74c1ad1296SSam Leffler { PIMV2_TYPE_REGISTER, "Register" }, 75c1ad1296SSam Leffler { PIMV2_TYPE_REGISTER_STOP, "Register Stop" }, 76c1ad1296SSam Leffler { PIMV2_TYPE_JOIN_PRUNE, "Join / Prune" }, 77c1ad1296SSam Leffler { PIMV2_TYPE_BOOTSTRAP, "Bootstrap" }, 78c1ad1296SSam Leffler { PIMV2_TYPE_ASSERT, "Assert" }, 79c1ad1296SSam Leffler { PIMV2_TYPE_GRAFT, "Graft" }, 80c1ad1296SSam Leffler { PIMV2_TYPE_GRAFT_ACK, "Graft Acknowledgement" }, 81c1ad1296SSam Leffler { PIMV2_TYPE_CANDIDATE_RP, "Candidate RP Advertisement" }, 82c1ad1296SSam Leffler { PIMV2_TYPE_PRUNE_REFRESH, "Prune Refresh" }, 833c602fabSXin LI { PIMV2_TYPE_DF_ELECTION, "DF Election" }, 843c602fabSXin LI { PIMV2_TYPE_ECMP_REDIRECT, "ECMP Redirect" }, 85c1ad1296SSam Leffler { 0, NULL} 86c1ad1296SSam Leffler }; 87c1ad1296SSam Leffler 88c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_HOLDTIME 1 89c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_LANPRUNEDELAY 2 90c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_DR_PRIORITY_OLD 18 91c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_DR_PRIORITY 19 92c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_GENID 20 93c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_REFRESH_CAP 21 94c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_BIDIR_CAP 22 95c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_ADDRESS_LIST 24 96c1ad1296SSam Leffler #define PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD 65001 97c1ad1296SSam Leffler 983c602fabSXin LI static const struct tok pimv2_hello_option_values[] = { 99c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_HOLDTIME, "Hold Time" }, 100c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_LANPRUNEDELAY, "LAN Prune Delay" }, 101c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_DR_PRIORITY_OLD, "DR Priority (Old)" }, 102c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_DR_PRIORITY, "DR Priority" }, 103c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_GENID, "Generation ID" }, 104c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_REFRESH_CAP, "State Refresh Capability" }, 105c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_BIDIR_CAP, "Bi-Directional Capability" }, 106c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_ADDRESS_LIST, "Address List" }, 107c1ad1296SSam Leffler { PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD, "Address List (Old)" }, 108c1ad1296SSam Leffler { 0, NULL} 109c1ad1296SSam Leffler }; 110c1ad1296SSam Leffler 111abf25193SMax Laier #define PIMV2_REGISTER_FLAG_LEN 4 112abf25193SMax Laier #define PIMV2_REGISTER_FLAG_BORDER 0x80000000 113abf25193SMax Laier #define PIMV2_REGISTER_FLAG_NULL 0x40000000 114abf25193SMax Laier 1153c602fabSXin LI static const struct tok pimv2_register_flag_values[] = { 116abf25193SMax Laier { PIMV2_REGISTER_FLAG_BORDER, "Border" }, 117abf25193SMax Laier { PIMV2_REGISTER_FLAG_NULL, "Null" }, 118abf25193SMax Laier { 0, NULL} 119abf25193SMax Laier }; 120b0453382SBill Fenner 121b0453382SBill Fenner /* 122b0453382SBill Fenner * XXX: We consider a case where IPv6 is not ready yet for portability, 123b0453382SBill Fenner * but PIM dependent defintions should be independent of IPv6... 124b0453382SBill Fenner */ 125b0453382SBill Fenner 126b0453382SBill Fenner struct pim { 1273c602fabSXin LI uint8_t pim_typever; 1289537d84eSBill Fenner /* upper 4bit: PIM version number; 2 for PIMv2 */ 1299537d84eSBill Fenner /* lower 4bit: the PIM message type, currently they are: 130b0453382SBill Fenner * Hello, Register, Register-Stop, Join/Prune, 131b0453382SBill Fenner * Bootstrap, Assert, Graft (PIM-DM only), 132b0453382SBill Fenner * Graft-Ack (PIM-DM only), C-RP-Adv 133b0453382SBill Fenner */ 1349537d84eSBill Fenner #define PIM_VER(x) (((x) & 0xf0) >> 4) 1359537d84eSBill Fenner #define PIM_TYPE(x) ((x) & 0x0f) 136b0453382SBill Fenner u_char pim_rsv; /* Reserved */ 137b0453382SBill Fenner u_short pim_cksum; /* IP style check sum */ 138b0453382SBill Fenner }; 139b0453382SBill Fenner 1403340d773SGleb Smirnoff static void pimv2_print(netdissect_options *, register const u_char *bp, register u_int len, const u_char *); 141b0453382SBill Fenner 142b0453382SBill Fenner static void 1433c602fabSXin LI pimv1_join_prune_print(netdissect_options *ndo, 1443c602fabSXin LI register const u_char *bp, register u_int len) 145b0453382SBill Fenner { 1463c602fabSXin LI int ngroups, njoin, nprune; 147b0453382SBill Fenner int njp; 148b0453382SBill Fenner 149b0453382SBill Fenner /* If it's a single group and a single source, use 1-line output. */ 1503c602fabSXin LI if (ND_TTEST2(bp[0], 30) && bp[11] == 1 && 151b0453382SBill Fenner ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { 152b0453382SBill Fenner int hold; 153b0453382SBill Fenner 1543c602fabSXin LI ND_PRINT((ndo, " RPF %s ", ipaddr_string(ndo, bp))); 155b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[6]); 156b0453382SBill Fenner if (hold != 180) { 1573c602fabSXin LI ND_PRINT((ndo, "Hold ")); 1583340d773SGleb Smirnoff unsigned_relts_print(ndo, hold); 159b0453382SBill Fenner } 1603c602fabSXin LI ND_PRINT((ndo, "%s (%s/%d, %s", njoin ? "Join" : "Prune", 1613c602fabSXin LI ipaddr_string(ndo, &bp[26]), bp[25] & 0x3f, 1623c602fabSXin LI ipaddr_string(ndo, &bp[12]))); 163b0453382SBill Fenner if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) 1643c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[16]))); 1653c602fabSXin LI ND_PRINT((ndo, ") %s%s %s", 166b0453382SBill Fenner (bp[24] & 0x01) ? "Sparse" : "Dense", 167b0453382SBill Fenner (bp[25] & 0x80) ? " WC" : "", 1683c602fabSXin LI (bp[25] & 0x40) ? "RP" : "SPT")); 169b0453382SBill Fenner return; 170b0453382SBill Fenner } 171b0453382SBill Fenner 172*0bff6a5aSEd Maste if (len < sizeof(struct in_addr)) 173*0bff6a5aSEd Maste goto trunc; 1743c602fabSXin LI ND_TCHECK2(bp[0], sizeof(struct in_addr)); 1753c602fabSXin LI if (ndo->ndo_vflag > 1) 1763c602fabSXin LI ND_PRINT((ndo, "\n")); 1773c602fabSXin LI ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp))); 178*0bff6a5aSEd Maste bp += 4; 179*0bff6a5aSEd Maste len -= 4; 180*0bff6a5aSEd Maste if (len < 4) 181*0bff6a5aSEd Maste goto trunc; 182*0bff6a5aSEd Maste ND_TCHECK2(bp[2], 2); 1833c602fabSXin LI if (ndo->ndo_vflag > 1) 1843c602fabSXin LI ND_PRINT((ndo, "\n")); 1853c602fabSXin LI ND_PRINT((ndo, " Hold time: ")); 186*0bff6a5aSEd Maste unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); 1873c602fabSXin LI if (ndo->ndo_vflag < 2) 188a1c2090eSBill Fenner return; 189*0bff6a5aSEd Maste bp += 4; 190*0bff6a5aSEd Maste len -= 4; 191b0453382SBill Fenner 192*0bff6a5aSEd Maste if (len < 4) 193*0bff6a5aSEd Maste goto trunc; 1943c602fabSXin LI ND_TCHECK2(bp[0], 4); 195b0453382SBill Fenner ngroups = bp[3]; 196a1c2090eSBill Fenner bp += 4; 197a1c2090eSBill Fenner len -= 4; 198b0453382SBill Fenner while (ngroups--) { 19929292c17SSam Leffler /* 20029292c17SSam Leffler * XXX - does the address have length "addrlen" and the 20129292c17SSam Leffler * mask length "maddrlen"? 20229292c17SSam Leffler */ 203*0bff6a5aSEd Maste if (len < 4) 204*0bff6a5aSEd Maste goto trunc; 2053c602fabSXin LI ND_TCHECK2(bp[0], sizeof(struct in_addr)); 2063c602fabSXin LI ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp))); 207*0bff6a5aSEd Maste bp += 4; 208*0bff6a5aSEd Maste len -= 4; 209*0bff6a5aSEd Maste if (len < 4) 210*0bff6a5aSEd Maste goto trunc; 211*0bff6a5aSEd Maste ND_TCHECK2(bp[0], sizeof(struct in_addr)); 212*0bff6a5aSEd Maste if (EXTRACT_32BITS(&bp[0]) != 0xffffffff) 213*0bff6a5aSEd Maste ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[0]))); 214*0bff6a5aSEd Maste bp += 4; 215*0bff6a5aSEd Maste len -= 4; 216*0bff6a5aSEd Maste if (len < 4) 217*0bff6a5aSEd Maste goto trunc; 218*0bff6a5aSEd Maste ND_TCHECK2(bp[0], 4); 219*0bff6a5aSEd Maste njoin = EXTRACT_16BITS(&bp[0]); 220*0bff6a5aSEd Maste nprune = EXTRACT_16BITS(&bp[2]); 2213c602fabSXin LI ND_PRINT((ndo, " joined: %d pruned: %d", njoin, nprune)); 222*0bff6a5aSEd Maste bp += 4; 223*0bff6a5aSEd Maste len -= 4; 224b0453382SBill Fenner for (njp = 0; njp < (njoin + nprune); njp++) { 225cc391cceSBruce M Simpson const char *type; 226b0453382SBill Fenner 227a1c2090eSBill Fenner if (njp < njoin) 228b0453382SBill Fenner type = "Join "; 229a1c2090eSBill Fenner else 230b0453382SBill Fenner type = "Prune"; 231*0bff6a5aSEd Maste if (len < 6) 232*0bff6a5aSEd Maste goto trunc; 2333c602fabSXin LI ND_TCHECK2(bp[0], 6); 2343c602fabSXin LI ND_PRINT((ndo, "\n\t%s %s%s%s%s/%d", type, 235b0453382SBill Fenner (bp[0] & 0x01) ? "Sparse " : "Dense ", 236b0453382SBill Fenner (bp[1] & 0x80) ? "WC " : "", 237b0453382SBill Fenner (bp[1] & 0x40) ? "RP " : "SPT ", 238*0bff6a5aSEd Maste ipaddr_string(ndo, &bp[2]), 239*0bff6a5aSEd Maste bp[1] & 0x3f)); 240a1c2090eSBill Fenner bp += 6; 241a1c2090eSBill Fenner len -= 6; 242b0453382SBill Fenner } 243b0453382SBill Fenner } 244b0453382SBill Fenner return; 245b0453382SBill Fenner trunc: 2463c602fabSXin LI ND_PRINT((ndo, "[|pim]")); 247b0453382SBill Fenner return; 248b0453382SBill Fenner } 2494edb46e9SPaul Traina 2504edb46e9SPaul Traina void 2513c602fabSXin LI pimv1_print(netdissect_options *ndo, 2523c602fabSXin LI register const u_char *bp, register u_int len) 2534edb46e9SPaul Traina { 2544edb46e9SPaul Traina register u_char type; 2554edb46e9SPaul Traina 2563c602fabSXin LI ND_TCHECK(bp[1]); 2574edb46e9SPaul Traina type = bp[1]; 2584edb46e9SPaul Traina 2593c602fabSXin LI ND_PRINT((ndo, " %s", tok2str(pimv1_type_str, "[type %u]", type))); 2604edb46e9SPaul Traina switch (type) { 2613c602fabSXin LI case PIMV1_TYPE_QUERY: 2623c602fabSXin LI if (ND_TTEST(bp[8])) { 263b0453382SBill Fenner switch (bp[8] >> 4) { 264a1c2090eSBill Fenner case 0: 2653c602fabSXin LI ND_PRINT((ndo, " Dense-mode")); 266b0453382SBill Fenner break; 267a1c2090eSBill Fenner case 1: 2683c602fabSXin LI ND_PRINT((ndo, " Sparse-mode")); 269b0453382SBill Fenner break; 270a1c2090eSBill Fenner case 2: 2713c602fabSXin LI ND_PRINT((ndo, " Sparse-Dense-mode")); 272b0453382SBill Fenner break; 273a1c2090eSBill Fenner default: 2743c602fabSXin LI ND_PRINT((ndo, " mode-%d", bp[8] >> 4)); 275b0453382SBill Fenner break; 276b0453382SBill Fenner } 277b0453382SBill Fenner } 2783c602fabSXin LI if (ndo->ndo_vflag) { 2793c602fabSXin LI ND_TCHECK2(bp[10],2); 2803c602fabSXin LI ND_PRINT((ndo, " (Hold-time ")); 2813340d773SGleb Smirnoff unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[10])); 2823c602fabSXin LI ND_PRINT((ndo, ")")); 283b0453382SBill Fenner } 2844edb46e9SPaul Traina break; 2854edb46e9SPaul Traina 2863c602fabSXin LI case PIMV1_TYPE_REGISTER: 2873c602fabSXin LI ND_TCHECK2(bp[8], 20); /* ip header */ 2883c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[20]), 2893c602fabSXin LI ipaddr_string(ndo, &bp[24]))); 2904edb46e9SPaul Traina break; 2913c602fabSXin LI case PIMV1_TYPE_REGISTER_STOP: 2923c602fabSXin LI ND_TCHECK2(bp[12], sizeof(struct in_addr)); 2933c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[8]), 2943c602fabSXin LI ipaddr_string(ndo, &bp[12]))); 2954edb46e9SPaul Traina break; 2963c602fabSXin LI case PIMV1_TYPE_RP_REACHABILITY: 2973c602fabSXin LI if (ndo->ndo_vflag) { 2983c602fabSXin LI ND_TCHECK2(bp[22], 2); 2993c602fabSXin LI ND_PRINT((ndo, " group %s", ipaddr_string(ndo, &bp[8]))); 300b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 3013c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); 3023c602fabSXin LI ND_PRINT((ndo, " RP %s hold ", ipaddr_string(ndo, &bp[16]))); 3033340d773SGleb Smirnoff unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[22])); 304b0453382SBill Fenner } 3054edb46e9SPaul Traina break; 3063c602fabSXin LI case PIMV1_TYPE_ASSERT: 3073c602fabSXin LI ND_TCHECK2(bp[16], sizeof(struct in_addr)); 3083c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[16]), 3093c602fabSXin LI ipaddr_string(ndo, &bp[8]))); 310b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 3113c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); 3123c602fabSXin LI ND_TCHECK2(bp[24], 4); 3133c602fabSXin LI ND_PRINT((ndo, " %s pref %d metric %d", 314b0453382SBill Fenner (bp[20] & 0x80) ? "RP-tree" : "SPT", 315b0453382SBill Fenner EXTRACT_32BITS(&bp[20]) & 0x7fffffff, 3163c602fabSXin LI EXTRACT_32BITS(&bp[24]))); 3174edb46e9SPaul Traina break; 3183c602fabSXin LI case PIMV1_TYPE_JOIN_PRUNE: 3193c602fabSXin LI case PIMV1_TYPE_GRAFT: 3203c602fabSXin LI case PIMV1_TYPE_GRAFT_ACK: 321*0bff6a5aSEd Maste if (ndo->ndo_vflag) { 322*0bff6a5aSEd Maste if (len < 8) 323*0bff6a5aSEd Maste goto trunc; 3243c602fabSXin LI pimv1_join_prune_print(ndo, &bp[8], len - 8); 325*0bff6a5aSEd Maste } 3264edb46e9SPaul Traina break; 3274edb46e9SPaul Traina } 328*0bff6a5aSEd Maste ND_TCHECK(bp[4]); 329b0453382SBill Fenner if ((bp[4] >> 4) != 1) 3303c602fabSXin LI ND_PRINT((ndo, " [v%d]", bp[4] >> 4)); 331b0453382SBill Fenner return; 332b0453382SBill Fenner 333b0453382SBill Fenner trunc: 3343c602fabSXin LI ND_PRINT((ndo, "[|pim]")); 335b0453382SBill Fenner return; 336b0453382SBill Fenner } 337b0453382SBill Fenner 338b0453382SBill Fenner /* 339b0453382SBill Fenner * auto-RP is a cisco protocol, documented at 340a1c2090eSBill Fenner * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt 341a1c2090eSBill Fenner * 342a1c2090eSBill Fenner * This implements version 1+, dated Sept 9, 1998. 343b0453382SBill Fenner */ 344b0453382SBill Fenner void 3453c602fabSXin LI cisco_autorp_print(netdissect_options *ndo, 3463c602fabSXin LI register const u_char *bp, register u_int len) 347b0453382SBill Fenner { 348b0453382SBill Fenner int type; 349b0453382SBill Fenner int numrps; 350b0453382SBill Fenner int hold; 351b0453382SBill Fenner 352*0bff6a5aSEd Maste if (len < 8) 353*0bff6a5aSEd Maste goto trunc; 3543c602fabSXin LI ND_TCHECK(bp[0]); 3553c602fabSXin LI ND_PRINT((ndo, " auto-rp ")); 356b0453382SBill Fenner type = bp[0]; 357b0453382SBill Fenner switch (type) { 358b0453382SBill Fenner case 0x11: 3593c602fabSXin LI ND_PRINT((ndo, "candidate-advert")); 360b0453382SBill Fenner break; 361b0453382SBill Fenner case 0x12: 3623c602fabSXin LI ND_PRINT((ndo, "mapping")); 363b0453382SBill Fenner break; 364b0453382SBill Fenner default: 3653c602fabSXin LI ND_PRINT((ndo, "type-0x%02x", type)); 366b0453382SBill Fenner break; 367b0453382SBill Fenner } 368b0453382SBill Fenner 3693c602fabSXin LI ND_TCHECK(bp[1]); 370b0453382SBill Fenner numrps = bp[1]; 371b0453382SBill Fenner 3723c602fabSXin LI ND_TCHECK2(bp[2], 2); 3733c602fabSXin LI ND_PRINT((ndo, " Hold ")); 374b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[2]); 375b0453382SBill Fenner if (hold) 3763340d773SGleb Smirnoff unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); 377b0453382SBill Fenner else 3783c602fabSXin LI ND_PRINT((ndo, "FOREVER")); 379b0453382SBill Fenner 380b0453382SBill Fenner /* Next 4 bytes are reserved. */ 381b0453382SBill Fenner 382b0453382SBill Fenner bp += 8; len -= 8; 383b0453382SBill Fenner 384b0453382SBill Fenner /*XXX skip unless -v? */ 385b0453382SBill Fenner 386b0453382SBill Fenner /* 387b0453382SBill Fenner * Rest of packet: 388b0453382SBill Fenner * numrps entries of the form: 389b0453382SBill Fenner * 32 bits: RP 390b0453382SBill Fenner * 6 bits: reserved 391b0453382SBill Fenner * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2". 392b0453382SBill Fenner * 8 bits: # of entries for this RP 393b0453382SBill Fenner * each entry: 7 bits: reserved, 1 bit: negative, 394b0453382SBill Fenner * 8 bits: mask 32 bits: source 395b0453382SBill Fenner * lather, rinse, repeat. 396b0453382SBill Fenner */ 397b0453382SBill Fenner while (numrps--) { 398b0453382SBill Fenner int nentries; 399b0453382SBill Fenner char s; 400b0453382SBill Fenner 401*0bff6a5aSEd Maste if (len < 4) 402*0bff6a5aSEd Maste goto trunc; 4033c602fabSXin LI ND_TCHECK2(bp[0], 4); 4043c602fabSXin LI ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp))); 405*0bff6a5aSEd Maste bp += 4; 406*0bff6a5aSEd Maste len -= 4; 407*0bff6a5aSEd Maste if (len < 1) 408*0bff6a5aSEd Maste goto trunc; 409*0bff6a5aSEd Maste ND_TCHECK(bp[0]); 410*0bff6a5aSEd Maste switch (bp[0] & 0x3) { 4113c602fabSXin LI case 0: ND_PRINT((ndo, " PIMv?")); 412b0453382SBill Fenner break; 4133c602fabSXin LI case 1: ND_PRINT((ndo, " PIMv1")); 414b0453382SBill Fenner break; 4153c602fabSXin LI case 2: ND_PRINT((ndo, " PIMv2")); 416b0453382SBill Fenner break; 4173c602fabSXin LI case 3: ND_PRINT((ndo, " PIMv1+2")); 418b0453382SBill Fenner break; 419b0453382SBill Fenner } 420*0bff6a5aSEd Maste if (bp[0] & 0xfc) 421*0bff6a5aSEd Maste ND_PRINT((ndo, " [rsvd=0x%02x]", bp[0] & 0xfc)); 422*0bff6a5aSEd Maste bp += 1; 423*0bff6a5aSEd Maste len -= 1; 424*0bff6a5aSEd Maste if (len < 1) 425*0bff6a5aSEd Maste goto trunc; 426*0bff6a5aSEd Maste ND_TCHECK(bp[0]); 427*0bff6a5aSEd Maste nentries = bp[0]; 428*0bff6a5aSEd Maste bp += 1; 429*0bff6a5aSEd Maste len -= 1; 430b0453382SBill Fenner s = ' '; 431b0453382SBill Fenner for (; nentries; nentries--) { 432*0bff6a5aSEd Maste if (len < 6) 433*0bff6a5aSEd Maste goto trunc; 4343c602fabSXin LI ND_TCHECK2(bp[0], 6); 4353c602fabSXin LI ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "", 4363c602fabSXin LI ipaddr_string(ndo, &bp[2]), bp[1])); 437cac3dcd5SXin LI if (bp[0] & 0x02) { 4383c602fabSXin LI ND_PRINT((ndo, " bidir")); 439cac3dcd5SXin LI } 440cac3dcd5SXin LI if (bp[0] & 0xfc) { 4413c602fabSXin LI ND_PRINT((ndo, "[rsvd=0x%02x]", bp[0] & 0xfc)); 442cac3dcd5SXin LI } 443b0453382SBill Fenner s = ','; 444b0453382SBill Fenner bp += 6; len -= 6; 445b0453382SBill Fenner } 446b0453382SBill Fenner } 447b0453382SBill Fenner return; 448b0453382SBill Fenner 449b0453382SBill Fenner trunc: 4503c602fabSXin LI ND_PRINT((ndo, "[|autorp]")); 451b0453382SBill Fenner return; 452b0453382SBill Fenner } 453b0453382SBill Fenner 454b0453382SBill Fenner void 4553c602fabSXin LI pim_print(netdissect_options *ndo, 4563340d773SGleb Smirnoff register const u_char *bp, register u_int len, const u_char *bp2) 457b0453382SBill Fenner { 4583340d773SGleb Smirnoff register const struct pim *pim = (const struct pim *)bp; 459b0453382SBill Fenner 460b0453382SBill Fenner #ifdef notyet /* currently we see only version and type */ 4613c602fabSXin LI ND_TCHECK(pim->pim_rsv); 462b0453382SBill Fenner #endif 463b0453382SBill Fenner 464*0bff6a5aSEd Maste ND_TCHECK(pim->pim_typever); 465b0453382SBill Fenner switch (PIM_VER(pim->pim_typever)) { 466c1ad1296SSam Leffler case 2: 4673c602fabSXin LI if (!ndo->ndo_vflag) { 4683c602fabSXin LI ND_PRINT((ndo, "PIMv%u, %s, length %u", 469c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 470c1ad1296SSam Leffler tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)), 4713c602fabSXin LI len)); 472c1ad1296SSam Leffler return; 473c1ad1296SSam Leffler } else { 4743c602fabSXin LI ND_PRINT((ndo, "PIMv%u, length %u\n\t%s", 475c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 476c1ad1296SSam Leffler len, 4773c602fabSXin LI tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)))); 4783340d773SGleb Smirnoff pimv2_print(ndo, bp, len, bp2); 479c1ad1296SSam Leffler } 480b0453382SBill Fenner break; 481b0453382SBill Fenner default: 4823c602fabSXin LI ND_PRINT((ndo, "PIMv%u, length %u", 483c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 4843c602fabSXin LI len)); 485b0453382SBill Fenner break; 486b0453382SBill Fenner } 487b0453382SBill Fenner return; 488*0bff6a5aSEd Maste 489*0bff6a5aSEd Maste trunc: 490*0bff6a5aSEd Maste ND_PRINT((ndo, "[|pim]")); 491*0bff6a5aSEd Maste return; 492b0453382SBill Fenner } 493b0453382SBill Fenner 494b0453382SBill Fenner /* 495b0453382SBill Fenner * PIMv2 uses encoded address representations. 496b0453382SBill Fenner * 497b0453382SBill Fenner * The last PIM-SM I-D before RFC2117 was published specified the 498b0453382SBill Fenner * following representation for unicast addresses. However, RFC2117 499b0453382SBill Fenner * specified no encoding for unicast addresses with the unicast 500b0453382SBill Fenner * address length specified in the header. Therefore, we have to 501b0453382SBill Fenner * guess which encoding is being used (Cisco's PIMv2 implementation 502b0453382SBill Fenner * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" 503b0453382SBill Fenner * field into a 'unicast-address-length-in-bytes' field. We guess 504b0453382SBill Fenner * that it's the draft encoding if this reserved field is zero. 505b0453382SBill Fenner * 506b0453382SBill Fenner * RFC2362 goes back to the encoded format, and calls the addr length 507b0453382SBill Fenner * field "reserved" again. 508b0453382SBill Fenner * 509b0453382SBill Fenner * The first byte is the address family, from: 510b0453382SBill Fenner * 511b0453382SBill Fenner * 0 Reserved 512b0453382SBill Fenner * 1 IP (IP version 4) 513b0453382SBill Fenner * 2 IP6 (IP version 6) 514b0453382SBill Fenner * 3 NSAP 515b0453382SBill Fenner * 4 HDLC (8-bit multidrop) 516b0453382SBill Fenner * 5 BBN 1822 517b0453382SBill Fenner * 6 802 (includes all 802 media plus Ethernet "canonical format") 518b0453382SBill Fenner * 7 E.163 519b0453382SBill Fenner * 8 E.164 (SMDS, Frame Relay, ATM) 520b0453382SBill Fenner * 9 F.69 (Telex) 521b0453382SBill Fenner * 10 X.121 (X.25, Frame Relay) 522b0453382SBill Fenner * 11 IPX 523b0453382SBill Fenner * 12 Appletalk 524b0453382SBill Fenner * 13 Decnet IV 525b0453382SBill Fenner * 14 Banyan Vines 526b0453382SBill Fenner * 15 E.164 with NSAP format subaddress 527b0453382SBill Fenner * 528b0453382SBill Fenner * In addition, the second byte is an "Encoding". 0 is the default 529b0453382SBill Fenner * encoding for the address family, and no other encodings are currently 530b0453382SBill Fenner * specified. 531b0453382SBill Fenner * 532b0453382SBill Fenner */ 533b0453382SBill Fenner 534b0453382SBill Fenner enum pimv2_addrtype { 535b0453382SBill Fenner pimv2_unicast, pimv2_group, pimv2_source 536b0453382SBill Fenner }; 537b0453382SBill Fenner 538b0453382SBill Fenner /* 0 1 2 3 539b0453382SBill 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 540b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 541b0453382SBill Fenner * | Addr Family | Encoding Type | Unicast Address | 542b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ 543b0453382SBill Fenner * 0 1 2 3 544b0453382SBill 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 545b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 546b0453382SBill Fenner * | Addr Family | Encoding Type | Reserved | Mask Len | 547b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 548b0453382SBill Fenner * | Group multicast Address | 549b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 550b0453382SBill Fenner * 0 1 2 3 551b0453382SBill 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 552b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 553b0453382SBill Fenner * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | 554b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 555b0453382SBill Fenner * | Source Address | 556b0453382SBill Fenner * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 557b0453382SBill Fenner */ 558b0453382SBill Fenner static int 5593c602fabSXin LI pimv2_addr_print(netdissect_options *ndo, 560*0bff6a5aSEd Maste const u_char *bp, u_int len, enum pimv2_addrtype at, 561*0bff6a5aSEd Maste u_int addr_len, int silent) 562b0453382SBill Fenner { 563b0453382SBill Fenner int af; 564*0bff6a5aSEd Maste int hdrlen; 565b0453382SBill Fenner 566*0bff6a5aSEd Maste if (addr_len == 0) { 567*0bff6a5aSEd Maste if (len < 2) 568*0bff6a5aSEd Maste goto trunc; 5693c602fabSXin LI ND_TCHECK(bp[1]); 570b0453382SBill Fenner switch (bp[0]) { 571b0453382SBill Fenner case 1: 572b0453382SBill Fenner af = AF_INET; 573*0bff6a5aSEd Maste addr_len = (u_int)sizeof(struct in_addr); 574b0453382SBill Fenner break; 575b0453382SBill Fenner case 2: 576b0453382SBill Fenner af = AF_INET6; 577*0bff6a5aSEd Maste addr_len = (u_int)sizeof(struct in6_addr); 578b0453382SBill Fenner break; 579b0453382SBill Fenner default: 580b0453382SBill Fenner return -1; 581b0453382SBill Fenner } 582b0453382SBill Fenner if (bp[1] != 0) 583b0453382SBill Fenner return -1; 584b0453382SBill Fenner hdrlen = 2; 585b0453382SBill Fenner } else { 586*0bff6a5aSEd Maste switch (addr_len) { 58717cb103cSSam Leffler case sizeof(struct in_addr): 588b0453382SBill Fenner af = AF_INET; 589b0453382SBill Fenner break; 59017cb103cSSam Leffler case sizeof(struct in6_addr): 591b0453382SBill Fenner af = AF_INET6; 592b0453382SBill Fenner break; 593b0453382SBill Fenner default: 594b0453382SBill Fenner return -1; 595b0453382SBill Fenner break; 596b0453382SBill Fenner } 597b0453382SBill Fenner hdrlen = 0; 598b0453382SBill Fenner } 599b0453382SBill Fenner 600b0453382SBill Fenner bp += hdrlen; 601*0bff6a5aSEd Maste len -= hdrlen; 602b0453382SBill Fenner switch (at) { 603b0453382SBill Fenner case pimv2_unicast: 604*0bff6a5aSEd Maste if (len < addr_len) 605*0bff6a5aSEd Maste goto trunc; 606*0bff6a5aSEd Maste ND_TCHECK2(bp[0], addr_len); 607b0453382SBill Fenner if (af == AF_INET) { 608b0453382SBill Fenner if (!silent) 6093c602fabSXin LI ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp))); 610b0453382SBill Fenner } 611b0453382SBill Fenner else if (af == AF_INET6) { 612b0453382SBill Fenner if (!silent) 6133c602fabSXin LI ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp))); 614b0453382SBill Fenner } 615*0bff6a5aSEd Maste return hdrlen + addr_len; 616b0453382SBill Fenner case pimv2_group: 617b0453382SBill Fenner case pimv2_source: 618*0bff6a5aSEd Maste if (len < addr_len + 2) 619*0bff6a5aSEd Maste goto trunc; 620*0bff6a5aSEd Maste ND_TCHECK2(bp[0], addr_len + 2); 621b0453382SBill Fenner if (af == AF_INET) { 622b0453382SBill Fenner if (!silent) { 6233c602fabSXin LI ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2))); 624b0453382SBill Fenner if (bp[1] != 32) 6253c602fabSXin LI ND_PRINT((ndo, "/%u", bp[1])); 626b0453382SBill Fenner } 627b0453382SBill Fenner } 628b0453382SBill Fenner else if (af == AF_INET6) { 629b0453382SBill Fenner if (!silent) { 6303c602fabSXin LI ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp + 2))); 631b0453382SBill Fenner if (bp[1] != 128) 6323c602fabSXin LI ND_PRINT((ndo, "/%u", bp[1])); 633b0453382SBill Fenner } 634b0453382SBill Fenner } 635b0453382SBill Fenner if (bp[0] && !silent) { 636b0453382SBill Fenner if (at == pimv2_group) { 6373c602fabSXin LI ND_PRINT((ndo, "(0x%02x)", bp[0])); 638b0453382SBill Fenner } else { 6393c602fabSXin LI ND_PRINT((ndo, "(%s%s%s", 640b0453382SBill Fenner bp[0] & 0x04 ? "S" : "", 641b0453382SBill Fenner bp[0] & 0x02 ? "W" : "", 6423c602fabSXin LI bp[0] & 0x01 ? "R" : "")); 643b0453382SBill Fenner if (bp[0] & 0xf8) { 6443c602fabSXin LI ND_PRINT((ndo, "+0x%02x", bp[0] & 0xf8)); 645b0453382SBill Fenner } 6463c602fabSXin LI ND_PRINT((ndo, ")")); 647b0453382SBill Fenner } 648b0453382SBill Fenner } 649*0bff6a5aSEd Maste return hdrlen + 2 + addr_len; 650b0453382SBill Fenner default: 651b0453382SBill Fenner return -1; 652b0453382SBill Fenner } 653b0453382SBill Fenner trunc: 654b0453382SBill Fenner return -1; 655b0453382SBill Fenner } 656b0453382SBill Fenner 6573340d773SGleb Smirnoff enum checksum_status { 6583340d773SGleb Smirnoff CORRECT, 6593340d773SGleb Smirnoff INCORRECT, 6603340d773SGleb Smirnoff UNVERIFIED 6613340d773SGleb Smirnoff }; 6623340d773SGleb Smirnoff 6633340d773SGleb Smirnoff static enum checksum_status 6643340d773SGleb Smirnoff pimv2_check_checksum(netdissect_options *ndo, const u_char *bp, 6653340d773SGleb Smirnoff const u_char *bp2, u_int len) 6663340d773SGleb Smirnoff { 6673340d773SGleb Smirnoff const struct ip *ip; 6683340d773SGleb Smirnoff u_int cksum; 6693340d773SGleb Smirnoff 6703340d773SGleb Smirnoff if (!ND_TTEST2(bp[0], len)) { 6713340d773SGleb Smirnoff /* We don't have all the data. */ 6723340d773SGleb Smirnoff return (UNVERIFIED); 6733340d773SGleb Smirnoff } 6743340d773SGleb Smirnoff ip = (const struct ip *)bp2; 6753340d773SGleb Smirnoff if (IP_V(ip) == 4) { 6763340d773SGleb Smirnoff struct cksum_vec vec[1]; 6773340d773SGleb Smirnoff 6783340d773SGleb Smirnoff vec[0].ptr = bp; 6793340d773SGleb Smirnoff vec[0].len = len; 6803340d773SGleb Smirnoff cksum = in_cksum(vec, 1); 6813340d773SGleb Smirnoff return (cksum ? INCORRECT : CORRECT); 6823340d773SGleb Smirnoff } else if (IP_V(ip) == 6) { 6833340d773SGleb Smirnoff const struct ip6_hdr *ip6; 6843340d773SGleb Smirnoff 6853340d773SGleb Smirnoff ip6 = (const struct ip6_hdr *)bp2; 6863340d773SGleb Smirnoff cksum = nextproto6_cksum(ndo, ip6, bp, len, len, IPPROTO_PIM); 6873340d773SGleb Smirnoff return (cksum ? INCORRECT : CORRECT); 6883340d773SGleb Smirnoff } else { 6893340d773SGleb Smirnoff return (UNVERIFIED); 6903340d773SGleb Smirnoff } 6913340d773SGleb Smirnoff } 6923340d773SGleb Smirnoff 693b0453382SBill Fenner static void 6943c602fabSXin LI pimv2_print(netdissect_options *ndo, 6953340d773SGleb Smirnoff register const u_char *bp, register u_int len, const u_char *bp2) 696b0453382SBill Fenner { 6973340d773SGleb Smirnoff register const struct pim *pim = (const struct pim *)bp; 698b0453382SBill Fenner int advance; 6993340d773SGleb Smirnoff enum checksum_status cksum_status; 700*0bff6a5aSEd Maste int pimv2_addr_len; 701b0453382SBill Fenner 702*0bff6a5aSEd Maste if (len < 2) 703*0bff6a5aSEd Maste goto trunc; 7043c602fabSXin LI ND_TCHECK(pim->pim_rsv); 705b0453382SBill Fenner pimv2_addr_len = pim->pim_rsv; 706b0453382SBill Fenner if (pimv2_addr_len != 0) 7073c602fabSXin LI ND_PRINT((ndo, ", RFC2117-encoding")); 708b0453382SBill Fenner 709*0bff6a5aSEd Maste if (len < 4) 710*0bff6a5aSEd Maste goto trunc; 711*0bff6a5aSEd Maste ND_TCHECK(pim->pim_cksum); 7123c602fabSXin LI ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum))); 713abf25193SMax Laier if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { 7143c602fabSXin LI ND_PRINT((ndo, "(unverified)")); 715abf25193SMax Laier } else { 7163340d773SGleb Smirnoff if (PIM_TYPE(pim->pim_typever) == PIMV2_TYPE_REGISTER) { 7173340d773SGleb Smirnoff /* 7183340d773SGleb Smirnoff * The checksum only covers the packet header, 7193340d773SGleb Smirnoff * not the encapsulated packet. 7203340d773SGleb Smirnoff */ 7213340d773SGleb Smirnoff cksum_status = pimv2_check_checksum(ndo, bp, bp2, 8); 7223340d773SGleb Smirnoff if (cksum_status == INCORRECT) { 7233340d773SGleb Smirnoff /* 7243340d773SGleb Smirnoff * To quote RFC 4601, "For interoperability 7253340d773SGleb Smirnoff * reasons, a message carrying a checksum 7263340d773SGleb Smirnoff * calculated over the entire PIM Register 7273340d773SGleb Smirnoff * message should also be accepted." 7283340d773SGleb Smirnoff */ 7293340d773SGleb Smirnoff cksum_status = pimv2_check_checksum(ndo, bp, bp2, len); 7303340d773SGleb Smirnoff } 7313340d773SGleb Smirnoff } else { 7323340d773SGleb Smirnoff /* 7333340d773SGleb Smirnoff * The checksum covers the entire packet. 7343340d773SGleb Smirnoff */ 7353340d773SGleb Smirnoff cksum_status = pimv2_check_checksum(ndo, bp, bp2, len); 7363340d773SGleb Smirnoff } 7373340d773SGleb Smirnoff switch (cksum_status) { 7383340d773SGleb Smirnoff 7393340d773SGleb Smirnoff case CORRECT: 7403340d773SGleb Smirnoff ND_PRINT((ndo, "(correct)")); 7413340d773SGleb Smirnoff break; 7423340d773SGleb Smirnoff 7433340d773SGleb Smirnoff case INCORRECT: 7443340d773SGleb Smirnoff ND_PRINT((ndo, "(incorrect)")); 7453340d773SGleb Smirnoff break; 7463340d773SGleb Smirnoff 7473340d773SGleb Smirnoff case UNVERIFIED: 7483340d773SGleb Smirnoff ND_PRINT((ndo, "(unverified)")); 7493340d773SGleb Smirnoff break; 7503340d773SGleb Smirnoff } 751abf25193SMax Laier } 752*0bff6a5aSEd Maste bp += 4; 753*0bff6a5aSEd Maste len -= 4; 754abf25193SMax Laier 755b0453382SBill Fenner switch (PIM_TYPE(pim->pim_typever)) { 756c1ad1296SSam Leffler case PIMV2_TYPE_HELLO: 757b0453382SBill Fenner { 7583c602fabSXin LI uint16_t otype, olen; 759*0bff6a5aSEd Maste while (len > 0) { 760*0bff6a5aSEd Maste if (len < 4) 761*0bff6a5aSEd Maste goto trunc; 7623c602fabSXin LI ND_TCHECK2(bp[0], 4); 763b0453382SBill Fenner otype = EXTRACT_16BITS(&bp[0]); 764b0453382SBill Fenner olen = EXTRACT_16BITS(&bp[2]); 7653c602fabSXin LI ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ", 766c1ad1296SSam Leffler tok2str(pimv2_hello_option_values, "Unknown", otype), 767c1ad1296SSam Leffler otype, 7683c602fabSXin LI olen)); 769c1ad1296SSam Leffler bp += 4; 770*0bff6a5aSEd Maste len -= 4; 771c1ad1296SSam Leffler 772*0bff6a5aSEd Maste if (len < olen) 773*0bff6a5aSEd Maste goto trunc; 774*0bff6a5aSEd Maste ND_TCHECK2(bp[0], olen); 775b0453382SBill Fenner switch (otype) { 776c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_HOLDTIME: 777*0bff6a5aSEd Maste if (olen != 2) { 778*0bff6a5aSEd Maste ND_PRINT((ndo, "ERROR: Option Length != 2 Bytes (%u)", olen)); 779*0bff6a5aSEd Maste } else { 7803340d773SGleb Smirnoff unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); 781*0bff6a5aSEd Maste } 782b0453382SBill Fenner break; 783b0453382SBill Fenner 784c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_LANPRUNEDELAY: 785cc391cceSBruce M Simpson if (olen != 4) { 7863c602fabSXin LI ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); 787cc391cceSBruce M Simpson } else { 788cc391cceSBruce M Simpson char t_bit; 7893c602fabSXin LI uint16_t lan_delay, override_interval; 790c1ad1296SSam Leffler lan_delay = EXTRACT_16BITS(bp); 791c1ad1296SSam Leffler override_interval = EXTRACT_16BITS(bp+2); 792cc391cceSBruce M Simpson t_bit = (lan_delay & 0x8000)? 1 : 0; 793cc391cceSBruce M Simpson lan_delay &= ~0x8000; 7943c602fabSXin LI ND_PRINT((ndo, "\n\t T-bit=%d, LAN delay %dms, Override interval %dms", 7953c602fabSXin LI t_bit, lan_delay, override_interval)); 796cc391cceSBruce M Simpson } 797cc391cceSBruce M Simpson break; 798cc391cceSBruce M Simpson 799c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_DR_PRIORITY_OLD: 800c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_DR_PRIORITY: 801c1ad1296SSam Leffler switch (olen) { 802c1ad1296SSam Leffler case 0: 8033c602fabSXin LI ND_PRINT((ndo, "Bi-Directional Capability (Old)")); 8040e0def19SBill Fenner break; 805c1ad1296SSam Leffler case 4: 8063c602fabSXin LI ND_PRINT((ndo, "%u", EXTRACT_32BITS(bp))); 807c1ad1296SSam Leffler break; 808c1ad1296SSam Leffler default: 8093c602fabSXin LI ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); 8100e0def19SBill Fenner break; 8110e0def19SBill Fenner } 812c1ad1296SSam Leffler break; 813c1ad1296SSam Leffler 814c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_GENID: 815*0bff6a5aSEd Maste if (olen != 4) { 816*0bff6a5aSEd Maste ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); 817*0bff6a5aSEd Maste } else { 8183c602fabSXin LI ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp))); 819*0bff6a5aSEd Maste } 820c1ad1296SSam Leffler break; 821c1ad1296SSam Leffler 822c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_REFRESH_CAP: 823*0bff6a5aSEd Maste if (olen != 4) { 824*0bff6a5aSEd Maste ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); 825*0bff6a5aSEd Maste } else { 8263c602fabSXin LI ND_PRINT((ndo, "v%d", *bp)); 827c1ad1296SSam Leffler if (*(bp+1) != 0) { 8283c602fabSXin LI ND_PRINT((ndo, ", interval ")); 8293340d773SGleb Smirnoff unsigned_relts_print(ndo, *(bp+1)); 830c1ad1296SSam Leffler } 831c1ad1296SSam Leffler if (EXTRACT_16BITS(bp+2) != 0) { 8323c602fabSXin LI ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2))); 833a1c2090eSBill Fenner } 834*0bff6a5aSEd Maste } 835b0453382SBill Fenner break; 836b0453382SBill Fenner 837c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_BIDIR_CAP: 838b0453382SBill Fenner break; 839b0453382SBill Fenner 840c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD: 841c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_ADDRESS_LIST: 8423c602fabSXin LI if (ndo->ndo_vflag > 1) { 843c1ad1296SSam Leffler const u_char *ptr = bp; 844*0bff6a5aSEd Maste u_int plen = len; 845c1ad1296SSam Leffler while (ptr < (bp+olen)) { 8463c602fabSXin LI ND_PRINT((ndo, "\n\t ")); 847*0bff6a5aSEd Maste advance = pimv2_addr_print(ndo, ptr, plen, pimv2_unicast, pimv2_addr_len, 0); 848*0bff6a5aSEd Maste if (advance < 0) 849*0bff6a5aSEd Maste goto trunc; 850cc391cceSBruce M Simpson ptr += advance; 851*0bff6a5aSEd Maste plen -= advance; 852cc391cceSBruce M Simpson } 853cc391cceSBruce M Simpson } 854cc391cceSBruce M Simpson break; 855b0453382SBill Fenner default: 8563c602fabSXin LI if (ndo->ndo_vflag <= 1) 8573c602fabSXin LI print_unknown_data(ndo, bp, "\n\t ", olen); 858c1ad1296SSam Leffler break; 859b0453382SBill Fenner } 860c1ad1296SSam Leffler /* do we want to see an additionally hexdump ? */ 8613c602fabSXin LI if (ndo->ndo_vflag> 1) 8623c602fabSXin LI print_unknown_data(ndo, bp, "\n\t ", olen); 863c1ad1296SSam Leffler bp += olen; 864*0bff6a5aSEd Maste len -= olen; 865b0453382SBill Fenner } 866b0453382SBill Fenner break; 867b0453382SBill Fenner } 868b0453382SBill Fenner 869c1ad1296SSam Leffler case PIMV2_TYPE_REGISTER: 870b0453382SBill Fenner { 8713340d773SGleb Smirnoff const struct ip *ip; 872b0453382SBill Fenner 873*0bff6a5aSEd Maste if (len < 4) 874*0bff6a5aSEd Maste goto trunc; 875*0bff6a5aSEd Maste ND_TCHECK2(*bp, PIMV2_REGISTER_FLAG_LEN); 876b0453382SBill Fenner 8773c602fabSXin LI ND_PRINT((ndo, ", Flags [ %s ]\n\t", 878abf25193SMax Laier tok2str(pimv2_register_flag_values, 879abf25193SMax Laier "none", 880*0bff6a5aSEd Maste EXTRACT_32BITS(bp)))); 881abf25193SMax Laier 882*0bff6a5aSEd Maste bp += 4; len -= 4; 883b0453382SBill Fenner /* encapsulated multicast packet */ 884*0bff6a5aSEd Maste if (len == 0) 885*0bff6a5aSEd Maste goto trunc; 8863340d773SGleb Smirnoff ip = (const struct ip *)bp; 887*0bff6a5aSEd Maste ND_TCHECK(ip->ip_vhl); 888943ee2b1SBill Fenner switch (IP_V(ip)) { 889abf25193SMax Laier case 0: /* Null header */ 890*0bff6a5aSEd Maste ND_TCHECK(ip->ip_dst); 8913c602fabSXin LI ND_PRINT((ndo, "IP-Null-header %s > %s", 8923c602fabSXin LI ipaddr_string(ndo, &ip->ip_src), 8933c602fabSXin LI ipaddr_string(ndo, &ip->ip_dst))); 894abf25193SMax Laier break; 895abf25193SMax Laier 896b0453382SBill Fenner case 4: /* IPv4 */ 8973c602fabSXin LI ip_print(ndo, bp, len); 898b0453382SBill Fenner break; 8998bdc5a62SPatrick Kelsey 900b0453382SBill Fenner case 6: /* IPv6 */ 9013c602fabSXin LI ip6_print(ndo, bp, len); 902b0453382SBill Fenner break; 9038bdc5a62SPatrick Kelsey 904b0453382SBill Fenner default: 9053c602fabSXin LI ND_PRINT((ndo, "IP ver %d", IP_V(ip))); 906b0453382SBill Fenner break; 907b0453382SBill Fenner } 908b0453382SBill Fenner break; 909b0453382SBill Fenner } 910b0453382SBill Fenner 911c1ad1296SSam Leffler case PIMV2_TYPE_REGISTER_STOP: 9123c602fabSXin LI ND_PRINT((ndo, " group=")); 913*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) 914*0bff6a5aSEd Maste goto trunc; 915b0453382SBill Fenner bp += advance; len -= advance; 9163c602fabSXin LI ND_PRINT((ndo, " source=")); 917*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) 918*0bff6a5aSEd Maste goto trunc; 919b0453382SBill Fenner bp += advance; len -= advance; 920b0453382SBill Fenner break; 921b0453382SBill Fenner 922c1ad1296SSam Leffler case PIMV2_TYPE_JOIN_PRUNE: 923c1ad1296SSam Leffler case PIMV2_TYPE_GRAFT: 924c1ad1296SSam Leffler case PIMV2_TYPE_GRAFT_ACK: 925c1ad1296SSam Leffler 926c1ad1296SSam Leffler 927c1ad1296SSam Leffler /* 928c1ad1296SSam Leffler * 0 1 2 3 929c1ad1296SSam 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 930c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 931c1ad1296SSam Leffler * |PIM Ver| Type | Addr length | Checksum | 932c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 933c1ad1296SSam Leffler * | Unicast-Upstream Neighbor Address | 934c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 935c1ad1296SSam Leffler * | Reserved | Num groups | Holdtime | 936c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 937c1ad1296SSam Leffler * | Encoded-Multicast Group Address-1 | 938c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 939c1ad1296SSam Leffler * | Number of Joined Sources | Number of Pruned Sources | 940c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 941c1ad1296SSam Leffler * | Encoded-Joined Source Address-1 | 942c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 943c1ad1296SSam Leffler * | . | 944c1ad1296SSam Leffler * | . | 945c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 946c1ad1296SSam Leffler * | Encoded-Joined Source Address-n | 947c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 948c1ad1296SSam Leffler * | Encoded-Pruned Source Address-1 | 949c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 950c1ad1296SSam Leffler * | . | 951c1ad1296SSam Leffler * | . | 952c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 953c1ad1296SSam Leffler * | Encoded-Pruned Source Address-n | 954c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 955c1ad1296SSam Leffler * | . | 956c1ad1296SSam Leffler * | . | 957c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 958c1ad1296SSam Leffler * | Encoded-Multicast Group Address-n | 959c1ad1296SSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 960c1ad1296SSam Leffler */ 961c1ad1296SSam Leffler 962b0453382SBill Fenner { 9633c602fabSXin LI uint8_t ngroup; 9643c602fabSXin LI uint16_t holdtime; 9653c602fabSXin LI uint16_t njoin; 9663c602fabSXin LI uint16_t nprune; 967b0453382SBill Fenner int i, j; 968b0453382SBill Fenner 969b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 9703c602fabSXin LI ND_PRINT((ndo, ", upstream-neighbor: ")); 971*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) 972*0bff6a5aSEd Maste goto trunc; 973b0453382SBill Fenner bp += advance; len -= advance; 974b0453382SBill Fenner } 975*0bff6a5aSEd Maste if (len < 4) 976*0bff6a5aSEd Maste goto trunc; 977*0bff6a5aSEd Maste ND_TCHECK2(*bp, 4); 978b0453382SBill Fenner ngroup = bp[1]; 979b0453382SBill Fenner holdtime = EXTRACT_16BITS(&bp[2]); 9803c602fabSXin LI ND_PRINT((ndo, "\n\t %u group(s)", ngroup)); 981b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 9823c602fabSXin LI ND_PRINT((ndo, ", holdtime: ")); 983b0453382SBill Fenner if (holdtime == 0xffff) 9843c602fabSXin LI ND_PRINT((ndo, "infinite")); 985b0453382SBill Fenner else 9863340d773SGleb Smirnoff unsigned_relts_print(ndo, holdtime); 987b0453382SBill Fenner } 988b0453382SBill Fenner bp += 4; len -= 4; 989b0453382SBill Fenner for (i = 0; i < ngroup; i++) { 9903c602fabSXin LI ND_PRINT((ndo, "\n\t group #%u: ", i+1)); 991*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) 992*0bff6a5aSEd Maste goto trunc; 993b0453382SBill Fenner bp += advance; len -= advance; 994*0bff6a5aSEd Maste if (len < 4) 995*0bff6a5aSEd Maste goto trunc; 996*0bff6a5aSEd Maste ND_TCHECK2(*bp, 4); 997b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[0]); 998b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[2]); 9993c602fabSXin LI ND_PRINT((ndo, ", joined sources: %u, pruned sources: %u", njoin, nprune)); 1000b0453382SBill Fenner bp += 4; len -= 4; 1001b0453382SBill Fenner for (j = 0; j < njoin; j++) { 10023c602fabSXin LI ND_PRINT((ndo, "\n\t joined source #%u: ", j+1)); 1003*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0) 1004*0bff6a5aSEd Maste goto trunc; 1005b0453382SBill Fenner bp += advance; len -= advance; 1006b0453382SBill Fenner } 1007b0453382SBill Fenner for (j = 0; j < nprune; j++) { 10083c602fabSXin LI ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1)); 1009*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0) 1010*0bff6a5aSEd Maste goto trunc; 1011b0453382SBill Fenner bp += advance; len -= advance; 1012b0453382SBill Fenner } 1013b0453382SBill Fenner } 1014b0453382SBill Fenner break; 1015b0453382SBill Fenner } 1016b0453382SBill Fenner 1017c1ad1296SSam Leffler case PIMV2_TYPE_BOOTSTRAP: 1018b0453382SBill Fenner { 1019b0453382SBill Fenner int i, j, frpcnt; 1020b0453382SBill Fenner 1021b0453382SBill Fenner /* Fragment Tag, Hash Mask len, and BSR-priority */ 1022*0bff6a5aSEd Maste if (len < 2) 1023*0bff6a5aSEd Maste goto trunc; 1024*0bff6a5aSEd Maste ND_TCHECK_16BITS(bp); 10253c602fabSXin LI ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp))); 1026*0bff6a5aSEd Maste bp += 2; 1027*0bff6a5aSEd Maste len -= 2; 1028*0bff6a5aSEd Maste if (len < 1) 1029*0bff6a5aSEd Maste goto trunc; 1030*0bff6a5aSEd Maste ND_TCHECK(bp[0]); 10313c602fabSXin LI ND_PRINT((ndo, " hashmlen=%d", bp[0])); 1032*0bff6a5aSEd Maste if (len < 2) 1033*0bff6a5aSEd Maste goto trunc; 1034*0bff6a5aSEd Maste ND_TCHECK(bp[2]); 10353c602fabSXin LI ND_PRINT((ndo, " BSRprio=%d", bp[1])); 1036b0453382SBill Fenner bp += 2; 1037*0bff6a5aSEd Maste len -= 2; 1038b0453382SBill Fenner 1039b0453382SBill Fenner /* Encoded-Unicast-BSR-Address */ 10403c602fabSXin LI ND_PRINT((ndo, " BSR=")); 1041*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) 1042*0bff6a5aSEd Maste goto trunc; 1043b0453382SBill Fenner bp += advance; 1044*0bff6a5aSEd Maste len -= advance; 1045b0453382SBill Fenner 1046*0bff6a5aSEd Maste for (i = 0; len > 0; i++) { 1047b0453382SBill Fenner /* Encoded-Group Address */ 10483c602fabSXin LI ND_PRINT((ndo, " (group%d: ", i)); 1049*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) 1050*0bff6a5aSEd Maste goto trunc; 1051b0453382SBill Fenner bp += advance; 1052*0bff6a5aSEd Maste len -= advance; 1053b0453382SBill Fenner 1054b0453382SBill Fenner /* RP-Count, Frag RP-Cnt, and rsvd */ 1055*0bff6a5aSEd Maste if (len < 1) 1056*0bff6a5aSEd Maste goto trunc; 1057*0bff6a5aSEd Maste ND_TCHECK(bp[0]); 10583c602fabSXin LI ND_PRINT((ndo, " RPcnt=%d", bp[0])); 1059*0bff6a5aSEd Maste if (len < 2) 1060*0bff6a5aSEd Maste goto trunc; 1061*0bff6a5aSEd Maste ND_TCHECK(bp[1]); 10623c602fabSXin LI ND_PRINT((ndo, " FRPcnt=%d", frpcnt = bp[1])); 1063*0bff6a5aSEd Maste if (len < 4) 1064*0bff6a5aSEd Maste goto trunc; 1065b0453382SBill Fenner bp += 4; 1066*0bff6a5aSEd Maste len -= 4; 1067b0453382SBill Fenner 1068*0bff6a5aSEd Maste for (j = 0; j < frpcnt && len > 0; j++) { 1069b0453382SBill Fenner /* each RP info */ 10703c602fabSXin LI ND_PRINT((ndo, " RP%d=", j)); 1071*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, 1072b0453382SBill Fenner pimv2_unicast, 1073*0bff6a5aSEd Maste pimv2_addr_len, 1074*0bff6a5aSEd Maste 0)) < 0) 1075*0bff6a5aSEd Maste goto trunc; 1076b0453382SBill Fenner bp += advance; 1077*0bff6a5aSEd Maste len -= advance; 1078b0453382SBill Fenner 1079*0bff6a5aSEd Maste if (len < 2) 1080*0bff6a5aSEd Maste goto trunc; 1081*0bff6a5aSEd Maste ND_TCHECK_16BITS(bp); 10823c602fabSXin LI ND_PRINT((ndo, ",holdtime=")); 10833340d773SGleb Smirnoff unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); 1084*0bff6a5aSEd Maste if (len < 3) 1085*0bff6a5aSEd Maste goto trunc; 1086*0bff6a5aSEd Maste ND_TCHECK(bp[2]); 10873c602fabSXin LI ND_PRINT((ndo, ",prio=%d", bp[2])); 1088*0bff6a5aSEd Maste if (len < 4) 1089*0bff6a5aSEd Maste goto trunc; 1090b0453382SBill Fenner bp += 4; 1091*0bff6a5aSEd Maste len -= 4; 1092b0453382SBill Fenner } 10933c602fabSXin LI ND_PRINT((ndo, ")")); 1094b0453382SBill Fenner } 1095b0453382SBill Fenner break; 1096b0453382SBill Fenner } 1097c1ad1296SSam Leffler case PIMV2_TYPE_ASSERT: 10983c602fabSXin LI ND_PRINT((ndo, " group=")); 1099*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) 1100*0bff6a5aSEd Maste goto trunc; 1101b0453382SBill Fenner bp += advance; len -= advance; 11023c602fabSXin LI ND_PRINT((ndo, " src=")); 1103*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) 1104*0bff6a5aSEd Maste goto trunc; 1105b0453382SBill Fenner bp += advance; len -= advance; 1106*0bff6a5aSEd Maste if (len < 8) 1107*0bff6a5aSEd Maste goto trunc; 1108*0bff6a5aSEd Maste ND_TCHECK2(*bp, 8); 1109b0453382SBill Fenner if (bp[0] & 0x80) 11103c602fabSXin LI ND_PRINT((ndo, " RPT")); 11113c602fabSXin LI ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff)); 11123c602fabSXin LI ND_PRINT((ndo, " metric=%u", EXTRACT_32BITS(&bp[4]))); 1113b0453382SBill Fenner break; 1114b0453382SBill Fenner 1115c1ad1296SSam Leffler case PIMV2_TYPE_CANDIDATE_RP: 1116b0453382SBill Fenner { 1117b0453382SBill Fenner int i, pfxcnt; 1118b0453382SBill Fenner 1119b0453382SBill Fenner /* Prefix-Cnt, Priority, and Holdtime */ 1120*0bff6a5aSEd Maste if (len < 1) 1121*0bff6a5aSEd Maste goto trunc; 1122*0bff6a5aSEd Maste ND_TCHECK(bp[0]); 11233c602fabSXin LI ND_PRINT((ndo, " prefix-cnt=%d", bp[0])); 1124b0453382SBill Fenner pfxcnt = bp[0]; 1125*0bff6a5aSEd Maste if (len < 2) 1126*0bff6a5aSEd Maste goto trunc; 1127*0bff6a5aSEd Maste ND_TCHECK(bp[1]); 11283c602fabSXin LI ND_PRINT((ndo, " prio=%d", bp[1])); 1129*0bff6a5aSEd Maste if (len < 4) 1130*0bff6a5aSEd Maste goto trunc; 1131*0bff6a5aSEd Maste ND_TCHECK_16BITS(&bp[2]); 11323c602fabSXin LI ND_PRINT((ndo, " holdtime=")); 11333340d773SGleb Smirnoff unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2])); 1134b0453382SBill Fenner bp += 4; 1135*0bff6a5aSEd Maste len -= 4; 1136b0453382SBill Fenner 1137b0453382SBill Fenner /* Encoded-Unicast-RP-Address */ 11383c602fabSXin LI ND_PRINT((ndo, " RP=")); 1139*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) 1140*0bff6a5aSEd Maste goto trunc; 1141b0453382SBill Fenner bp += advance; 1142*0bff6a5aSEd Maste len -= advance; 1143b0453382SBill Fenner 1144b0453382SBill Fenner /* Encoded-Group Addresses */ 1145*0bff6a5aSEd Maste for (i = 0; i < pfxcnt && len > 0; i++) { 11463c602fabSXin LI ND_PRINT((ndo, " Group%d=", i)); 1147*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) 1148*0bff6a5aSEd Maste goto trunc; 1149b0453382SBill Fenner bp += advance; 1150*0bff6a5aSEd Maste len -= advance; 1151b0453382SBill Fenner } 1152b0453382SBill Fenner break; 1153b0453382SBill Fenner } 1154b0453382SBill Fenner 1155c1ad1296SSam Leffler case PIMV2_TYPE_PRUNE_REFRESH: 11563c602fabSXin LI ND_PRINT((ndo, " src=")); 1157*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) 1158*0bff6a5aSEd Maste goto trunc; 1159b0453382SBill Fenner bp += advance; 1160*0bff6a5aSEd Maste len -= advance; 11613c602fabSXin LI ND_PRINT((ndo, " grp=")); 1162*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0) 1163*0bff6a5aSEd Maste goto trunc; 1164b0453382SBill Fenner bp += advance; 1165*0bff6a5aSEd Maste len -= advance; 11663c602fabSXin LI ND_PRINT((ndo, " forwarder=")); 1167*0bff6a5aSEd Maste if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0) 1168*0bff6a5aSEd Maste goto trunc; 1169b0453382SBill Fenner bp += advance; 1170*0bff6a5aSEd Maste len -= advance; 1171*0bff6a5aSEd Maste if (len < 2) 1172*0bff6a5aSEd Maste goto trunc; 1173*0bff6a5aSEd Maste ND_TCHECK_16BITS(bp); 11743c602fabSXin LI ND_PRINT((ndo, " TUNR ")); 11753340d773SGleb Smirnoff unsigned_relts_print(ndo, EXTRACT_16BITS(bp)); 1176b0453382SBill Fenner break; 1177b0453382SBill Fenner 1178b0453382SBill Fenner 1179b0453382SBill Fenner default: 11803c602fabSXin LI ND_PRINT((ndo, " [type %d]", PIM_TYPE(pim->pim_typever))); 1181b0453382SBill Fenner break; 1182b0453382SBill Fenner } 1183b0453382SBill Fenner 1184b0453382SBill Fenner return; 1185b0453382SBill Fenner 1186b0453382SBill Fenner trunc: 11873c602fabSXin LI ND_PRINT((ndo, "[|pim]")); 11884edb46e9SPaul Traina } 1189c1ad1296SSam Leffler 1190c1ad1296SSam Leffler /* 1191c1ad1296SSam Leffler * Local Variables: 1192c1ad1296SSam Leffler * c-style: whitesmith 1193c1ad1296SSam Leffler * c-basic-offset: 8 1194c1ad1296SSam Leffler * End: 1195c1ad1296SSam Leffler */ 1196