10f74e101Schristos /* 20f74e101Schristos * Copyright (C) 2001 Julian Cowley 30f74e101Schristos * All rights reserved. 40f74e101Schristos * 50f74e101Schristos * Redistribution and use in source and binary forms, with or without 60f74e101Schristos * modification, are permitted provided that the following conditions 70f74e101Schristos * are met: 80f74e101Schristos * 1. Redistributions of source code must retain the above copyright 90f74e101Schristos * notice, this list of conditions and the following disclaimer. 100f74e101Schristos * 2. Redistributions in binary form must reproduce the above copyright 110f74e101Schristos * notice, this list of conditions and the following disclaimer in the 120f74e101Schristos * documentation and/or other materials provided with the distribution. 130f74e101Schristos * 3. Neither the name of the project nor the names of its contributors 140f74e101Schristos * may be used to endorse or promote products derived from this software 150f74e101Schristos * without specific prior written permission. 160f74e101Schristos * 170f74e101Schristos * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 180f74e101Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 190f74e101Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 200f74e101Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 210f74e101Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 220f74e101Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 230f74e101Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 240f74e101Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 250f74e101Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 260f74e101Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 270f74e101Schristos * SUCH DAMAGE. 280f74e101Schristos */ 290f74e101Schristos 30dc860a36Sspz /* \summary: Cisco Hot Standby Router Protocol (HSRP) printer */ 31dc860a36Sspz 32c74ad251Schristos /* specification: RFC 2281 for version 1 */ 330f74e101Schristos 3411b3aaa1Schristos #include <sys/cdefs.h> 350f74e101Schristos #ifndef lint 36*26ba0b50Schristos __RCSID("$NetBSD: print-hsrp.c,v 1.9 2024/09/02 16:15:31 christos Exp $"); 370f74e101Schristos #endif 380f74e101Schristos 39c74ad251Schristos #include <config.h> 400f74e101Schristos 41c74ad251Schristos #include "netdissect-stdinc.h" 420f74e101Schristos 43fdccd7e4Schristos #include "netdissect.h" 440f74e101Schristos #include "addrtoname.h" 45c74ad251Schristos #include "extract.h" 460f74e101Schristos 470f74e101Schristos /* HSRP op code types. */ 480f74e101Schristos static const char *op_code_str[] = { 490f74e101Schristos "hello", 500f74e101Schristos "coup", 510f74e101Schristos "resign" 520f74e101Schristos }; 530f74e101Schristos 540f74e101Schristos /* HSRP states and associated names. */ 55870189d2Schristos static const struct tok states[] = { 560f74e101Schristos { 0, "initial" }, 570f74e101Schristos { 1, "learn" }, 580f74e101Schristos { 2, "listen" }, 590f74e101Schristos { 4, "speak" }, 600f74e101Schristos { 8, "standby" }, 610f74e101Schristos { 16, "active" }, 620f74e101Schristos { 0, NULL } 630f74e101Schristos }; 640f74e101Schristos 650f74e101Schristos /* 660f74e101Schristos * RFC 2281: 670f74e101Schristos * 680f74e101Schristos * 0 1 2 3 690f74e101Schristos * 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 700f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 710f74e101Schristos * | Version | Op Code | State | Hellotime | 720f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 730f74e101Schristos * | Holdtime | Priority | Group | Reserved | 740f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 750f74e101Schristos * | Authentication Data | 760f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 770f74e101Schristos * | Authentication Data | 780f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 790f74e101Schristos * | Virtual IP Address | 800f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 810f74e101Schristos */ 820f74e101Schristos 830f74e101Schristos #define HSRP_AUTH_SIZE 8 840f74e101Schristos 850f74e101Schristos /* HSRP protocol header. */ 860f74e101Schristos struct hsrp { 87c74ad251Schristos nd_uint8_t hsrp_version; 88c74ad251Schristos nd_uint8_t hsrp_op_code; 89c74ad251Schristos nd_uint8_t hsrp_state; 90c74ad251Schristos nd_uint8_t hsrp_hellotime; 91c74ad251Schristos nd_uint8_t hsrp_holdtime; 92c74ad251Schristos nd_uint8_t hsrp_priority; 93c74ad251Schristos nd_uint8_t hsrp_group; 94c74ad251Schristos nd_uint8_t hsrp_reserved; 95c74ad251Schristos nd_byte hsrp_authdata[HSRP_AUTH_SIZE]; 96c74ad251Schristos nd_ipv4 hsrp_virtaddr; 970f74e101Schristos }; 980f74e101Schristos 990f74e101Schristos void 100c74ad251Schristos hsrp_print(netdissect_options *ndo, const u_char *bp, u_int len) 1010f74e101Schristos { 102fdccd7e4Schristos const struct hsrp *hp = (const struct hsrp *) bp; 103c74ad251Schristos uint8_t version; 1040f74e101Schristos 105c74ad251Schristos ndo->ndo_protocol = "hsrp"; 106c74ad251Schristos version = GET_U_1(hp->hsrp_version); 107c74ad251Schristos ND_PRINT("HSRPv%u", version); 108c74ad251Schristos if (version != 0) 1090f74e101Schristos return; 110c74ad251Schristos ND_PRINT("-"); 111c74ad251Schristos ND_PRINT("%s ", 112c74ad251Schristos tok2strary(op_code_str, "unknown (%u)", GET_U_1(hp->hsrp_op_code))); 113c74ad251Schristos ND_PRINT("%u: ", len); 114c74ad251Schristos ND_PRINT("state=%s ", 115c74ad251Schristos tok2str(states, "Unknown (%u)", GET_U_1(hp->hsrp_state))); 116c74ad251Schristos ND_PRINT("group=%u ", GET_U_1(hp->hsrp_group)); 117c74ad251Schristos if (GET_U_1(hp->hsrp_reserved) != 0) { 118c74ad251Schristos ND_PRINT("[reserved=%u!] ", GET_U_1(hp->hsrp_reserved)); 1190f74e101Schristos } 120c74ad251Schristos ND_PRINT("addr=%s", GET_IPADDR_STRING(hp->hsrp_virtaddr)); 121b3a00663Schristos if (ndo->ndo_vflag) { 122c74ad251Schristos ND_PRINT(" hellotime="); 123c74ad251Schristos unsigned_relts_print(ndo, GET_U_1(hp->hsrp_hellotime)); 124c74ad251Schristos ND_PRINT(" holdtime="); 125c74ad251Schristos unsigned_relts_print(ndo, GET_U_1(hp->hsrp_holdtime)); 126c74ad251Schristos ND_PRINT(" priority=%u", GET_U_1(hp->hsrp_priority)); 127c74ad251Schristos ND_PRINT(" auth=\""); 128c74ad251Schristos /* 129c74ad251Schristos * RFC 2281 Section 5.1 does not specify the encoding of 130c74ad251Schristos * Authentication Data explicitly, but zero padding can be 131c74ad251Schristos * inferred from the "recommended default value". 132c74ad251Schristos */ 133c74ad251Schristos nd_printjnp(ndo, hp->hsrp_authdata, HSRP_AUTH_SIZE); 134c74ad251Schristos ND_PRINT("\""); 1350f74e101Schristos } 1360f74e101Schristos } 137