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 24*3c602fabSXin 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 37*3c602fabSXin LI #define PIMV1_TYPE_QUERY 0 38*3c602fabSXin LI #define PIMV1_TYPE_REGISTER 1 39*3c602fabSXin LI #define PIMV1_TYPE_REGISTER_STOP 2 40*3c602fabSXin LI #define PIMV1_TYPE_JOIN_PRUNE 3 41*3c602fabSXin LI #define PIMV1_TYPE_RP_REACHABILITY 4 42*3c602fabSXin LI #define PIMV1_TYPE_ASSERT 5 43*3c602fabSXin LI #define PIMV1_TYPE_GRAFT 6 44*3c602fabSXin LI #define PIMV1_TYPE_GRAFT_ACK 7 45*3c602fabSXin LI 46*3c602fabSXin LI static const struct tok pimv1_type_str[] = { 47*3c602fabSXin LI { PIMV1_TYPE_QUERY, "Query" }, 48*3c602fabSXin LI { PIMV1_TYPE_REGISTER, "Register" }, 49*3c602fabSXin LI { PIMV1_TYPE_REGISTER_STOP, "Register-Stop" }, 50*3c602fabSXin LI { PIMV1_TYPE_JOIN_PRUNE, "Join/Prune" }, 51*3c602fabSXin LI { PIMV1_TYPE_RP_REACHABILITY, "RP-reachable" }, 52*3c602fabSXin LI { PIMV1_TYPE_ASSERT, "Assert" }, 53*3c602fabSXin LI { PIMV1_TYPE_GRAFT, "Graft" }, 54*3c602fabSXin LI { PIMV1_TYPE_GRAFT_ACK, "Graft-ACK" }, 55*3c602fabSXin LI { 0, NULL } 56*3c602fabSXin LI }; 57*3c602fabSXin 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 68*3c602fabSXin LI #define PIMV2_TYPE_DF_ELECTION 10 69*3c602fabSXin LI #define PIMV2_TYPE_ECMP_REDIRECT 11 70c1ad1296SSam Leffler 71*3c602fabSXin 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" }, 82*3c602fabSXin LI { PIMV2_TYPE_DF_ELECTION, "DF Election" }, 83*3c602fabSXin 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 97*3c602fabSXin 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 114*3c602fabSXin 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 { 126*3c602fabSXin 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 139*3c602fabSXin 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 142*3c602fabSXin LI pimv1_join_prune_print(netdissect_options *ndo, 143*3c602fabSXin LI register const u_char *bp, register u_int len) 144b0453382SBill Fenner { 145*3c602fabSXin 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. */ 149*3c602fabSXin 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 153*3c602fabSXin LI ND_PRINT((ndo, " RPF %s ", ipaddr_string(ndo, bp))); 154b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[6]); 155b0453382SBill Fenner if (hold != 180) { 156*3c602fabSXin LI ND_PRINT((ndo, "Hold ")); 157*3c602fabSXin LI relts_print(ndo, hold); 158b0453382SBill Fenner } 159*3c602fabSXin LI ND_PRINT((ndo, "%s (%s/%d, %s", njoin ? "Join" : "Prune", 160*3c602fabSXin LI ipaddr_string(ndo, &bp[26]), bp[25] & 0x3f, 161*3c602fabSXin LI ipaddr_string(ndo, &bp[12]))); 162b0453382SBill Fenner if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) 163*3c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[16]))); 164*3c602fabSXin LI ND_PRINT((ndo, ") %s%s %s", 165b0453382SBill Fenner (bp[24] & 0x01) ? "Sparse" : "Dense", 166b0453382SBill Fenner (bp[25] & 0x80) ? " WC" : "", 167*3c602fabSXin LI (bp[25] & 0x40) ? "RP" : "SPT")); 168b0453382SBill Fenner return; 169b0453382SBill Fenner } 170b0453382SBill Fenner 171*3c602fabSXin LI ND_TCHECK2(bp[0], sizeof(struct in_addr)); 172*3c602fabSXin LI if (ndo->ndo_vflag > 1) 173*3c602fabSXin LI ND_PRINT((ndo, "\n")); 174*3c602fabSXin LI ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp))); 175*3c602fabSXin LI ND_TCHECK2(bp[6], 2); 176*3c602fabSXin LI if (ndo->ndo_vflag > 1) 177*3c602fabSXin LI ND_PRINT((ndo, "\n")); 178*3c602fabSXin LI ND_PRINT((ndo, " Hold time: ")); 179*3c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[6])); 180*3c602fabSXin LI if (ndo->ndo_vflag < 2) 181a1c2090eSBill Fenner return; 182a1c2090eSBill Fenner bp += 8; 183a1c2090eSBill Fenner len -= 8; 184b0453382SBill Fenner 185*3c602fabSXin 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 */ 194*3c602fabSXin LI ND_TCHECK2(bp[0], sizeof(struct in_addr)); 195*3c602fabSXin LI ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp))); 196*3c602fabSXin LI ND_TCHECK2(bp[4], sizeof(struct in_addr)); 197b0453382SBill Fenner if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) 198*3c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[4]))); 199*3c602fabSXin LI ND_TCHECK2(bp[8], 4); 200b0453382SBill Fenner njoin = EXTRACT_16BITS(&bp[8]); 201b0453382SBill Fenner nprune = EXTRACT_16BITS(&bp[10]); 202*3c602fabSXin 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"; 212*3c602fabSXin LI ND_TCHECK2(bp[0], 6); 213*3c602fabSXin 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 ", 217*3c602fabSXin 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: 224*3c602fabSXin LI ND_PRINT((ndo, "[|pim]")); 225b0453382SBill Fenner return; 226b0453382SBill Fenner } 2274edb46e9SPaul Traina 2284edb46e9SPaul Traina void 229*3c602fabSXin LI pimv1_print(netdissect_options *ndo, 230*3c602fabSXin 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 235*3c602fabSXin LI ep = (const u_char *)ndo->ndo_snapend; 2364edb46e9SPaul Traina if (bp >= ep) 2374edb46e9SPaul Traina return; 2384edb46e9SPaul Traina 239*3c602fabSXin LI ND_TCHECK(bp[1]); 2404edb46e9SPaul Traina type = bp[1]; 2414edb46e9SPaul Traina 242*3c602fabSXin LI ND_PRINT((ndo, " %s", tok2str(pimv1_type_str, "[type %u]", type))); 2434edb46e9SPaul Traina switch (type) { 244*3c602fabSXin LI case PIMV1_TYPE_QUERY: 245*3c602fabSXin LI if (ND_TTEST(bp[8])) { 246b0453382SBill Fenner switch (bp[8] >> 4) { 247a1c2090eSBill Fenner case 0: 248*3c602fabSXin LI ND_PRINT((ndo, " Dense-mode")); 249b0453382SBill Fenner break; 250a1c2090eSBill Fenner case 1: 251*3c602fabSXin LI ND_PRINT((ndo, " Sparse-mode")); 252b0453382SBill Fenner break; 253a1c2090eSBill Fenner case 2: 254*3c602fabSXin LI ND_PRINT((ndo, " Sparse-Dense-mode")); 255b0453382SBill Fenner break; 256a1c2090eSBill Fenner default: 257*3c602fabSXin LI ND_PRINT((ndo, " mode-%d", bp[8] >> 4)); 258b0453382SBill Fenner break; 259b0453382SBill Fenner } 260b0453382SBill Fenner } 261*3c602fabSXin LI if (ndo->ndo_vflag) { 262*3c602fabSXin LI ND_TCHECK2(bp[10],2); 263*3c602fabSXin LI ND_PRINT((ndo, " (Hold-time ")); 264*3c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[10])); 265*3c602fabSXin LI ND_PRINT((ndo, ")")); 266b0453382SBill Fenner } 2674edb46e9SPaul Traina break; 2684edb46e9SPaul Traina 269*3c602fabSXin LI case PIMV1_TYPE_REGISTER: 270*3c602fabSXin LI ND_TCHECK2(bp[8], 20); /* ip header */ 271*3c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[20]), 272*3c602fabSXin LI ipaddr_string(ndo, &bp[24]))); 2734edb46e9SPaul Traina break; 274*3c602fabSXin LI case PIMV1_TYPE_REGISTER_STOP: 275*3c602fabSXin LI ND_TCHECK2(bp[12], sizeof(struct in_addr)); 276*3c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[8]), 277*3c602fabSXin LI ipaddr_string(ndo, &bp[12]))); 2784edb46e9SPaul Traina break; 279*3c602fabSXin LI case PIMV1_TYPE_RP_REACHABILITY: 280*3c602fabSXin LI if (ndo->ndo_vflag) { 281*3c602fabSXin LI ND_TCHECK2(bp[22], 2); 282*3c602fabSXin LI ND_PRINT((ndo, " group %s", ipaddr_string(ndo, &bp[8]))); 283b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 284*3c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); 285*3c602fabSXin LI ND_PRINT((ndo, " RP %s hold ", ipaddr_string(ndo, &bp[16]))); 286*3c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[22])); 287b0453382SBill Fenner } 2884edb46e9SPaul Traina break; 289*3c602fabSXin LI case PIMV1_TYPE_ASSERT: 290*3c602fabSXin LI ND_TCHECK2(bp[16], sizeof(struct in_addr)); 291*3c602fabSXin LI ND_PRINT((ndo, " for %s > %s", ipaddr_string(ndo, &bp[16]), 292*3c602fabSXin LI ipaddr_string(ndo, &bp[8]))); 293b0453382SBill Fenner if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) 294*3c602fabSXin LI ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[12]))); 295*3c602fabSXin LI ND_TCHECK2(bp[24], 4); 296*3c602fabSXin LI ND_PRINT((ndo, " %s pref %d metric %d", 297b0453382SBill Fenner (bp[20] & 0x80) ? "RP-tree" : "SPT", 298b0453382SBill Fenner EXTRACT_32BITS(&bp[20]) & 0x7fffffff, 299*3c602fabSXin LI EXTRACT_32BITS(&bp[24]))); 3004edb46e9SPaul Traina break; 301*3c602fabSXin LI case PIMV1_TYPE_JOIN_PRUNE: 302*3c602fabSXin LI case PIMV1_TYPE_GRAFT: 303*3c602fabSXin LI case PIMV1_TYPE_GRAFT_ACK: 304*3c602fabSXin LI if (ndo->ndo_vflag) 305*3c602fabSXin LI pimv1_join_prune_print(ndo, &bp[8], len - 8); 3064edb46e9SPaul Traina break; 3074edb46e9SPaul Traina } 308b0453382SBill Fenner if ((bp[4] >> 4) != 1) 309*3c602fabSXin LI ND_PRINT((ndo, " [v%d]", bp[4] >> 4)); 310b0453382SBill Fenner return; 311b0453382SBill Fenner 312b0453382SBill Fenner trunc: 313*3c602fabSXin 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 324*3c602fabSXin LI cisco_autorp_print(netdissect_options *ndo, 325*3c602fabSXin 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 331*3c602fabSXin LI ND_TCHECK(bp[0]); 332*3c602fabSXin LI ND_PRINT((ndo, " auto-rp ")); 333b0453382SBill Fenner type = bp[0]; 334b0453382SBill Fenner switch (type) { 335b0453382SBill Fenner case 0x11: 336*3c602fabSXin LI ND_PRINT((ndo, "candidate-advert")); 337b0453382SBill Fenner break; 338b0453382SBill Fenner case 0x12: 339*3c602fabSXin LI ND_PRINT((ndo, "mapping")); 340b0453382SBill Fenner break; 341b0453382SBill Fenner default: 342*3c602fabSXin LI ND_PRINT((ndo, "type-0x%02x", type)); 343b0453382SBill Fenner break; 344b0453382SBill Fenner } 345b0453382SBill Fenner 346*3c602fabSXin LI ND_TCHECK(bp[1]); 347b0453382SBill Fenner numrps = bp[1]; 348b0453382SBill Fenner 349*3c602fabSXin LI ND_TCHECK2(bp[2], 2); 350*3c602fabSXin LI ND_PRINT((ndo, " Hold ")); 351b0453382SBill Fenner hold = EXTRACT_16BITS(&bp[2]); 352b0453382SBill Fenner if (hold) 353*3c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(&bp[2])); 354b0453382SBill Fenner else 355*3c602fabSXin 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 378*3c602fabSXin LI ND_TCHECK2(bp[0], 4); 379*3c602fabSXin LI ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp))); 380*3c602fabSXin LI ND_TCHECK(bp[4]); 381b0453382SBill Fenner switch (bp[4] & 0x3) { 382*3c602fabSXin LI case 0: ND_PRINT((ndo, " PIMv?")); 383b0453382SBill Fenner break; 384*3c602fabSXin LI case 1: ND_PRINT((ndo, " PIMv1")); 385b0453382SBill Fenner break; 386*3c602fabSXin LI case 2: ND_PRINT((ndo, " PIMv2")); 387b0453382SBill Fenner break; 388*3c602fabSXin LI case 3: ND_PRINT((ndo, " PIMv1+2")); 389b0453382SBill Fenner break; 390b0453382SBill Fenner } 391a1c2090eSBill Fenner if (bp[4] & 0xfc) 392*3c602fabSXin LI ND_PRINT((ndo, " [rsvd=0x%02x]", bp[4] & 0xfc)); 393*3c602fabSXin LI ND_TCHECK(bp[5]); 394b0453382SBill Fenner nentries = bp[5]; 395b0453382SBill Fenner bp += 6; len -= 6; 396b0453382SBill Fenner s = ' '; 397b0453382SBill Fenner for (; nentries; nentries--) { 398*3c602fabSXin LI ND_TCHECK2(bp[0], 6); 399*3c602fabSXin LI ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "", 400*3c602fabSXin LI ipaddr_string(ndo, &bp[2]), bp[1])); 401cac3dcd5SXin LI if (bp[0] & 0x02) { 402*3c602fabSXin LI ND_PRINT((ndo, " bidir")); 403cac3dcd5SXin LI } 404cac3dcd5SXin LI if (bp[0] & 0xfc) { 405*3c602fabSXin 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: 414*3c602fabSXin LI ND_PRINT((ndo, "[|autorp]")); 415b0453382SBill Fenner return; 416b0453382SBill Fenner } 417b0453382SBill Fenner 418b0453382SBill Fenner void 419*3c602fabSXin LI pim_print(netdissect_options *ndo, 420*3c602fabSXin 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 425*3c602fabSXin 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 */ 429*3c602fabSXin LI ND_TCHECK(pim->pim_rsv); 430b0453382SBill Fenner #endif 431b0453382SBill Fenner 432b0453382SBill Fenner switch (PIM_VER(pim->pim_typever)) { 433c1ad1296SSam Leffler case 2: 434*3c602fabSXin LI if (!ndo->ndo_vflag) { 435*3c602fabSXin 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)), 438*3c602fabSXin LI len)); 439c1ad1296SSam Leffler return; 440c1ad1296SSam Leffler } else { 441*3c602fabSXin LI ND_PRINT((ndo, "PIMv%u, length %u\n\t%s", 442c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 443c1ad1296SSam Leffler len, 444*3c602fabSXin LI tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)))); 445*3c602fabSXin LI pimv2_print(ndo, bp, len, cksum); 446c1ad1296SSam Leffler } 447b0453382SBill Fenner break; 448b0453382SBill Fenner default: 449*3c602fabSXin LI ND_PRINT((ndo, "PIMv%u, length %u", 450c1ad1296SSam Leffler PIM_VER(pim->pim_typever), 451*3c602fabSXin 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 524*3c602fabSXin LI pimv2_addr_print(netdissect_options *ndo, 525*3c602fabSXin LI const u_char *bp, enum pimv2_addrtype at, int silent) 526b0453382SBill Fenner { 527b0453382SBill Fenner int af; 528b0453382SBill Fenner int len, hdrlen; 529b0453382SBill Fenner 530*3c602fabSXin LI ND_TCHECK(bp[0]); 531b0453382SBill Fenner 532b0453382SBill Fenner if (pimv2_addr_len == 0) { 533*3c602fabSXin 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: 572*3c602fabSXin LI ND_TCHECK2(bp[0], len); 573b0453382SBill Fenner if (af == AF_INET) { 574b0453382SBill Fenner if (!silent) 575*3c602fabSXin 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) 580*3c602fabSXin 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: 586*3c602fabSXin LI ND_TCHECK2(bp[0], len + 2); 587b0453382SBill Fenner if (af == AF_INET) { 588b0453382SBill Fenner if (!silent) { 589*3c602fabSXin LI ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2))); 590b0453382SBill Fenner if (bp[1] != 32) 591*3c602fabSXin 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) { 597*3c602fabSXin LI ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp + 2))); 598b0453382SBill Fenner if (bp[1] != 128) 599*3c602fabSXin 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) { 605*3c602fabSXin LI ND_PRINT((ndo, "(0x%02x)", bp[0])); 606b0453382SBill Fenner } else { 607*3c602fabSXin LI ND_PRINT((ndo, "(%s%s%s", 608b0453382SBill Fenner bp[0] & 0x04 ? "S" : "", 609b0453382SBill Fenner bp[0] & 0x02 ? "W" : "", 610*3c602fabSXin LI bp[0] & 0x01 ? "R" : "")); 611b0453382SBill Fenner if (bp[0] & 0xf8) { 612*3c602fabSXin LI ND_PRINT((ndo, "+0x%02x", bp[0] & 0xf8)); 613b0453382SBill Fenner } 614*3c602fabSXin 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 626*3c602fabSXin LI pimv2_print(netdissect_options *ndo, 627*3c602fabSXin 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 633*3c602fabSXin 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; 638*3c602fabSXin LI ND_TCHECK(pim->pim_rsv); 639b0453382SBill Fenner pimv2_addr_len = pim->pim_rsv; 640b0453382SBill Fenner if (pimv2_addr_len != 0) 641*3c602fabSXin LI ND_PRINT((ndo, ", RFC2117-encoding")); 642b0453382SBill Fenner 643*3c602fabSXin LI ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum))); 644abf25193SMax Laier if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { 645*3c602fabSXin LI ND_PRINT((ndo, "(unverified)")); 646abf25193SMax Laier } else { 647*3c602fabSXin 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 { 653*3c602fabSXin LI uint16_t otype, olen; 654b0453382SBill Fenner bp += 4; 655b0453382SBill Fenner while (bp < ep) { 656*3c602fabSXin LI ND_TCHECK2(bp[0], 4); 657b0453382SBill Fenner otype = EXTRACT_16BITS(&bp[0]); 658b0453382SBill Fenner olen = EXTRACT_16BITS(&bp[2]); 659*3c602fabSXin LI ND_TCHECK2(bp[0], 4 + olen); 660*3c602fabSXin LI ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ", 661c1ad1296SSam Leffler tok2str(pimv2_hello_option_values, "Unknown", otype), 662c1ad1296SSam Leffler otype, 663*3c602fabSXin LI olen)); 664c1ad1296SSam Leffler bp += 4; 665c1ad1296SSam Leffler 666b0453382SBill Fenner switch (otype) { 667c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_HOLDTIME: 668*3c602fabSXin 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) { 673*3c602fabSXin LI ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen)); 674cc391cceSBruce M Simpson } else { 675cc391cceSBruce M Simpson char t_bit; 676*3c602fabSXin 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; 681*3c602fabSXin LI ND_PRINT((ndo, "\n\t T-bit=%d, LAN delay %dms, Override interval %dms", 682*3c602fabSXin 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: 690*3c602fabSXin LI ND_PRINT((ndo, "Bi-Directional Capability (Old)")); 6910e0def19SBill Fenner break; 692c1ad1296SSam Leffler case 4: 693*3c602fabSXin LI ND_PRINT((ndo, "%u", EXTRACT_32BITS(bp))); 694c1ad1296SSam Leffler break; 695c1ad1296SSam Leffler default: 696*3c602fabSXin 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: 702*3c602fabSXin LI ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp))); 703c1ad1296SSam Leffler break; 704c1ad1296SSam Leffler 705c1ad1296SSam Leffler case PIMV2_HELLO_OPTION_REFRESH_CAP: 706*3c602fabSXin LI ND_PRINT((ndo, "v%d", *bp)); 707c1ad1296SSam Leffler if (*(bp+1) != 0) { 708*3c602fabSXin LI ND_PRINT((ndo, ", interval ")); 709*3c602fabSXin LI relts_print(ndo, *(bp+1)); 710c1ad1296SSam Leffler } 711c1ad1296SSam Leffler if (EXTRACT_16BITS(bp+2) != 0) { 712*3c602fabSXin 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: 721*3c602fabSXin 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 726*3c602fabSXin LI ND_PRINT((ndo, "\n\t ")); 727*3c602fabSXin LI advance = pimv2_addr_print(ndo, ptr, pimv2_unicast, 0); 728cc391cceSBruce M Simpson if (advance < 0) { 729*3c602fabSXin 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: 737*3c602fabSXin LI if (ndo->ndo_vflag <= 1) 738*3c602fabSXin LI print_unknown_data(ndo, bp, "\n\t ", olen); 739c1ad1296SSam Leffler break; 740b0453382SBill Fenner } 741c1ad1296SSam Leffler /* do we want to see an additionally hexdump ? */ 742*3c602fabSXin LI if (ndo->ndo_vflag> 1) 743*3c602fabSXin 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 753*3c602fabSXin LI ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN); 754b0453382SBill Fenner 755*3c602fabSXin LI ND_PRINT((ndo, ", Flags [ %s ]\n\t", 756abf25193SMax Laier tok2str(pimv2_register_flag_values, 757abf25193SMax Laier "none", 758*3c602fabSXin 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 */ 765*3c602fabSXin LI ND_PRINT((ndo, "IP-Null-header %s > %s", 766*3c602fabSXin LI ipaddr_string(ndo, &ip->ip_src), 767*3c602fabSXin LI ipaddr_string(ndo, &ip->ip_dst))); 768abf25193SMax Laier break; 769abf25193SMax Laier 770b0453382SBill Fenner case 4: /* IPv4 */ 771*3c602fabSXin LI ip_print(ndo, bp, len); 772b0453382SBill Fenner break; 773b0453382SBill Fenner #ifdef INET6 774b0453382SBill Fenner case 6: /* IPv6 */ 775*3c602fabSXin LI ip6_print(ndo, bp, len); 776b0453382SBill Fenner break; 777b0453382SBill Fenner #endif 778b0453382SBill Fenner default: 779*3c602fabSXin 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; 789*3c602fabSXin LI ND_PRINT((ndo, " group=")); 790*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 791*3c602fabSXin LI ND_PRINT((ndo, "...")); 792b0453382SBill Fenner break; 793b0453382SBill Fenner } 794b0453382SBill Fenner bp += advance; len -= advance; 795b0453382SBill Fenner if (bp >= ep) 796b0453382SBill Fenner break; 797*3c602fabSXin LI ND_PRINT((ndo, " source=")); 798*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 799*3c602fabSXin 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 { 846*3c602fabSXin LI uint8_t ngroup; 847*3c602fabSXin LI uint16_t holdtime; 848*3c602fabSXin LI uint16_t njoin; 849*3c602fabSXin 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; 856*3c602fabSXin LI ND_PRINT((ndo, ", upstream-neighbor: ")); 857*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 858*3c602fabSXin 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]); 867*3c602fabSXin LI ND_PRINT((ndo, "\n\t %u group(s)", ngroup)); 868b0453382SBill Fenner if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ 869*3c602fabSXin LI ND_PRINT((ndo, ", holdtime: ")); 870b0453382SBill Fenner if (holdtime == 0xffff) 871*3c602fabSXin LI ND_PRINT((ndo, "infinite")); 872b0453382SBill Fenner else 873*3c602fabSXin 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; 879*3c602fabSXin LI ND_PRINT((ndo, "\n\t group #%u: ", i+1)); 880*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 881*3c602fabSXin LI ND_PRINT((ndo, "...)")); 882b0453382SBill Fenner goto jp_done; 883b0453382SBill Fenner } 884b0453382SBill Fenner bp += advance; len -= advance; 885b0453382SBill Fenner if (bp + 4 > ep) { 886*3c602fabSXin 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]); 891*3c602fabSXin 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++) { 894*3c602fabSXin LI ND_PRINT((ndo, "\n\t joined source #%u: ", j+1)); 895*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) { 896*3c602fabSXin 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++) { 902*3c602fabSXin LI ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1)); 903*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) { 904*3c602fabSXin 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 */ 920*3c602fabSXin LI if (bp + sizeof(uint16_t) >= ep) break; 921*3c602fabSXin LI ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp))); 922*3c602fabSXin LI bp += sizeof(uint16_t); 923b0453382SBill Fenner if (bp >= ep) break; 924*3c602fabSXin LI ND_PRINT((ndo, " hashmlen=%d", bp[0])); 925b0453382SBill Fenner if (bp + 1 >= ep) break; 926*3c602fabSXin 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; 931*3c602fabSXin LI ND_PRINT((ndo, " BSR=")); 932*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 933*3c602fabSXin 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 */ 940*3c602fabSXin LI ND_PRINT((ndo, " (group%d: ", i)); 941*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) 942b0453382SBill Fenner < 0) { 943*3c602fabSXin 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) { 950*3c602fabSXin LI ND_PRINT((ndo, "...)")); 951b0453382SBill Fenner goto bs_done; 952b0453382SBill Fenner } 953*3c602fabSXin LI ND_PRINT((ndo, " RPcnt=%d", bp[0])); 954b0453382SBill Fenner if (bp + 1 >= ep) { 955*3c602fabSXin LI ND_PRINT((ndo, "...)")); 956b0453382SBill Fenner goto bs_done; 957b0453382SBill Fenner } 958*3c602fabSXin 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 */ 963*3c602fabSXin LI ND_PRINT((ndo, " RP%d=", j)); 964*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, 965b0453382SBill Fenner pimv2_unicast, 966b0453382SBill Fenner 0)) < 0) { 967*3c602fabSXin LI ND_PRINT((ndo, "...)")); 968b0453382SBill Fenner goto bs_done; 969b0453382SBill Fenner } 970b0453382SBill Fenner bp += advance; 971b0453382SBill Fenner 972b0453382SBill Fenner if (bp + 1 >= ep) { 973*3c602fabSXin LI ND_PRINT((ndo, "...)")); 974b0453382SBill Fenner goto bs_done; 975b0453382SBill Fenner } 976*3c602fabSXin LI ND_PRINT((ndo, ",holdtime=")); 977*3c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(bp)); 978b0453382SBill Fenner if (bp + 2 >= ep) { 979*3c602fabSXin LI ND_PRINT((ndo, "...)")); 980b0453382SBill Fenner goto bs_done; 981b0453382SBill Fenner } 982*3c602fabSXin LI ND_PRINT((ndo, ",prio=%d", bp[2])); 983b0453382SBill Fenner bp += 4; 984b0453382SBill Fenner } 985*3c602fabSXin 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; 994*3c602fabSXin LI ND_PRINT((ndo, " group=")); 995*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 996*3c602fabSXin LI ND_PRINT((ndo, "...")); 997b0453382SBill Fenner break; 998b0453382SBill Fenner } 999b0453382SBill Fenner bp += advance; len -= advance; 1000b0453382SBill Fenner if (bp >= ep) 1001b0453382SBill Fenner break; 1002*3c602fabSXin LI ND_PRINT((ndo, " src=")); 1003*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 1004*3c602fabSXin 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) 1011*3c602fabSXin LI ND_PRINT((ndo, " RPT")); 1012*3c602fabSXin LI ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff)); 1013*3c602fabSXin 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; 1023*3c602fabSXin LI ND_PRINT((ndo, " prefix-cnt=%d", bp[0])); 1024b0453382SBill Fenner pfxcnt = bp[0]; 1025b0453382SBill Fenner if (bp + 1 >= ep) break; 1026*3c602fabSXin LI ND_PRINT((ndo, " prio=%d", bp[1])); 1027b0453382SBill Fenner if (bp + 3 >= ep) break; 1028*3c602fabSXin LI ND_PRINT((ndo, " holdtime=")); 1029*3c602fabSXin 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; 1034*3c602fabSXin LI ND_PRINT((ndo, " RP=")); 1035*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 1036*3c602fabSXin 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++) { 1043*3c602fabSXin LI ND_PRINT((ndo, " Group%d=", i)); 1044*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) 1045b0453382SBill Fenner < 0) { 1046*3c602fabSXin 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: 1055*3c602fabSXin LI ND_PRINT((ndo, " src=")); 1056*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 1057*3c602fabSXin LI ND_PRINT((ndo, "...")); 1058b0453382SBill Fenner break; 1059b0453382SBill Fenner } 1060b0453382SBill Fenner bp += advance; 1061*3c602fabSXin LI ND_PRINT((ndo, " grp=")); 1062*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) { 1063*3c602fabSXin LI ND_PRINT((ndo, "...")); 1064b0453382SBill Fenner break; 1065b0453382SBill Fenner } 1066b0453382SBill Fenner bp += advance; 1067*3c602fabSXin LI ND_PRINT((ndo, " forwarder=")); 1068*3c602fabSXin LI if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) { 1069*3c602fabSXin LI ND_PRINT((ndo, "...")); 1070b0453382SBill Fenner break; 1071b0453382SBill Fenner } 1072b0453382SBill Fenner bp += advance; 1073*3c602fabSXin LI ND_TCHECK2(bp[0], 2); 1074*3c602fabSXin LI ND_PRINT((ndo, " TUNR ")); 1075*3c602fabSXin LI relts_print(ndo, EXTRACT_16BITS(bp)); 1076b0453382SBill Fenner break; 1077b0453382SBill Fenner 1078b0453382SBill Fenner 1079b0453382SBill Fenner default: 1080*3c602fabSXin 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: 1087*3c602fabSXin 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