10f74e101Schristos /* 20f74e101Schristos * Copyright (c) 2000 William C. Fenner. 30f74e101Schristos * All rights reserved. 40f74e101Schristos * 50f74e101Schristos * Kevin Steves <ks@hp.se> July 2000 60f74e101Schristos * Modified to: 70f74e101Schristos * - print version, type string and packet length 80f74e101Schristos * - print IP address count if > 1 (-v) 90f74e101Schristos * - verify checksum (-v) 100f74e101Schristos * - print authentication string (-v) 110f74e101Schristos * 120f74e101Schristos * Redistribution and use in source and binary forms, with or without 130f74e101Schristos * modification, are permitted provided that: (1) source code 140f74e101Schristos * distributions retain the above copyright notice and this paragraph 150f74e101Schristos * in its entirety, and (2) distributions including binary code include 160f74e101Schristos * the above copyright notice and this paragraph in its entirety in 170f74e101Schristos * the documentation or other materials provided with the distribution. 180f74e101Schristos * The name of William C. Fenner may not be used to endorse or 190f74e101Schristos * promote products derived from this software without specific prior 200f74e101Schristos * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND 210f74e101Schristos * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 220f74e101Schristos * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 230f74e101Schristos * FOR A PARTICULAR PURPOSE. 240f74e101Schristos */ 250f74e101Schristos 2611b3aaa1Schristos #include <sys/cdefs.h> 270f74e101Schristos #ifndef lint 28*26ba0b50Schristos __RCSID("$NetBSD: print-vrrp.c,v 1.9 2024/09/02 16:15:33 christos Exp $"); 290f74e101Schristos #endif 300f74e101Schristos 31dc860a36Sspz /* \summary: Virtual Router Redundancy Protocol (VRRP) printer */ 32dc860a36Sspz 33c74ad251Schristos #include <config.h> 340f74e101Schristos 35c74ad251Schristos #include "netdissect-stdinc.h" 360f74e101Schristos 37fdccd7e4Schristos #include "netdissect.h" 380f74e101Schristos #include "extract.h" 390f74e101Schristos #include "addrtoname.h" 400f74e101Schristos 41b3a00663Schristos #include "ip.h" 42b3a00663Schristos #include "ipproto.h" 430f74e101Schristos /* 44b3a00663Schristos * RFC 2338 (VRRP v2): 45b3a00663Schristos * 460f74e101Schristos * 0 1 2 3 470f74e101Schristos * 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 480f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 490f74e101Schristos * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| 500f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 510f74e101Schristos * | Auth Type | Adver Int | Checksum | 520f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 530f74e101Schristos * | IP Address (1) | 540f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 550f74e101Schristos * | . | 560f74e101Schristos * | . | 570f74e101Schristos * | . | 580f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 590f74e101Schristos * | IP Address (n) | 600f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 610f74e101Schristos * | Authentication Data (1) | 620f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 630f74e101Schristos * | Authentication Data (2) | 640f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 65b3a00663Schristos * 66b3a00663Schristos * 67b3a00663Schristos * RFC 5798 (VRRP v3): 68b3a00663Schristos * 69b3a00663Schristos * 0 1 2 3 70b3a00663Schristos * 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 71b3a00663Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 72b3a00663Schristos * | IPv4 Fields or IPv6 Fields | 73b3a00663Schristos * ... ... 74b3a00663Schristos * | | 75b3a00663Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 76b3a00663Schristos * |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr| 77b3a00663Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 78b3a00663Schristos * |(rsvd) | Max Adver Int | Checksum | 79b3a00663Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 80b3a00663Schristos * | | 81b3a00663Schristos * + + 82b3a00663Schristos * | IPvX Address(es) | 83b3a00663Schristos * + + 84b3a00663Schristos * | | 85b3a00663Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 860f74e101Schristos */ 870f74e101Schristos 880f74e101Schristos /* Type */ 890f74e101Schristos #define VRRP_TYPE_ADVERTISEMENT 1 900f74e101Schristos 910f74e101Schristos static const struct tok type2str[] = { 920f74e101Schristos { VRRP_TYPE_ADVERTISEMENT, "Advertisement" }, 930f74e101Schristos { 0, NULL } 940f74e101Schristos }; 950f74e101Schristos 960f74e101Schristos /* Auth Type */ 970f74e101Schristos #define VRRP_AUTH_NONE 0 980f74e101Schristos #define VRRP_AUTH_SIMPLE 1 990f74e101Schristos #define VRRP_AUTH_AH 2 1000f74e101Schristos 1010f74e101Schristos static const struct tok auth2str[] = { 1020f74e101Schristos { VRRP_AUTH_NONE, "none" }, 1030f74e101Schristos { VRRP_AUTH_SIMPLE, "simple" }, 1040f74e101Schristos { VRRP_AUTH_AH, "ah" }, 1050f74e101Schristos { 0, NULL } 1060f74e101Schristos }; 1070f74e101Schristos 1080f74e101Schristos void 109b3a00663Schristos vrrp_print(netdissect_options *ndo, 110c74ad251Schristos const u_char *bp, u_int len, 111c74ad251Schristos const u_char *bp2, int ttl, 112c74ad251Schristos int ver) 1130f74e101Schristos { 114b3a00663Schristos int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */ 1150f74e101Schristos const char *type_s; 1160f74e101Schristos 117c74ad251Schristos ndo->ndo_protocol = "vrrp"; 118c74ad251Schristos nd_print_protocol_caps(ndo); 119c74ad251Schristos version = (GET_U_1(bp) & 0xf0) >> 4; 120c74ad251Schristos type = GET_U_1(bp) & 0x0f; 1210f74e101Schristos type_s = tok2str(type2str, "unknown type (%u)", type); 122c74ad251Schristos ND_PRINT("v%u, %s", version, type_s); 1230f74e101Schristos if (ttl != 255) 124c74ad251Schristos ND_PRINT(", (ttl %u)", ttl); 125b3a00663Schristos if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT) 1260f74e101Schristos return; 127c74ad251Schristos ND_PRINT(", vrid %u, prio %u", GET_U_1(bp + 1), GET_U_1(bp + 2)); 128b3a00663Schristos 129b3a00663Schristos if (version == 2) { 130c74ad251Schristos auth_type = GET_U_1(bp + 4); 131c74ad251Schristos ND_PRINT(", authtype %s", tok2str(auth2str, NULL, auth_type)); 132c74ad251Schristos ND_PRINT(", intvl %us, length %u", GET_U_1(bp + 5), len); 133b3a00663Schristos } else { /* version == 3 */ 134c74ad251Schristos uint16_t intvl = (GET_U_1(bp + 4) & 0x0f) << 8 | GET_U_1(bp + 5); 135c74ad251Schristos ND_PRINT(", intvl %ucs, length %u", intvl, len); 136b3a00663Schristos } 137b3a00663Schristos 138b3a00663Schristos if (ndo->ndo_vflag) { 139c74ad251Schristos u_int naddrs = GET_U_1(bp + 3); 140c74ad251Schristos u_int i; 1410f74e101Schristos char c; 1420f74e101Schristos 143c74ad251Schristos if (version == 2 && ND_TTEST_LEN(bp, len)) { 1440e9868baSchristos struct cksum_vec vec[1]; 1450e9868baSchristos 1460e9868baSchristos vec[0].ptr = bp; 1470e9868baSchristos vec[0].len = len; 148c74ad251Schristos if (in_cksum(vec, 1)) 149c74ad251Schristos ND_PRINT(", (bad vrrp cksum %x)", 150c74ad251Schristos GET_BE_U_2(bp + 6)); 151817e9a7eSchristos } 152b3a00663Schristos 153c74ad251Schristos if (version == 3 && ND_TTEST_LEN(bp, len)) { 154c74ad251Schristos uint16_t cksum; 155c74ad251Schristos 156c74ad251Schristos if (ver == 4) 157c74ad251Schristos cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp, 158b3a00663Schristos len, len, IPPROTO_VRRP); 159c74ad251Schristos else 160c74ad251Schristos cksum = nextproto6_cksum(ndo, (const struct ip6_hdr *)bp2, bp, 161c74ad251Schristos len, len, IPPROTO_VRRP); 162c74ad251Schristos if (cksum) 163c74ad251Schristos ND_PRINT(", (bad vrrp cksum %x)", 164c74ad251Schristos GET_BE_U_2(bp + 6)); 165817e9a7eSchristos } 166b3a00663Schristos 167c74ad251Schristos ND_PRINT(", addrs"); 1680f74e101Schristos if (naddrs > 1) 169c74ad251Schristos ND_PRINT("(%u)", naddrs); 170c74ad251Schristos ND_PRINT(":"); 1710f74e101Schristos c = ' '; 1720f74e101Schristos bp += 8; 1730f74e101Schristos for (i = 0; i < naddrs; i++) { 174c74ad251Schristos if (ver == 4) { 175c74ad251Schristos ND_PRINT("%c%s", c, GET_IPADDR_STRING(bp)); 1760f74e101Schristos bp += 4; 177c74ad251Schristos } else { 178c74ad251Schristos ND_PRINT("%c%s", c, GET_IP6ADDR_STRING(bp)); 179c74ad251Schristos bp += 16; 180c74ad251Schristos } 181c74ad251Schristos c = ','; 1820f74e101Schristos } 183b3a00663Schristos if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ 184c74ad251Schristos ND_PRINT(" auth \""); 185c74ad251Schristos /* 186c74ad251Schristos * RFC 2338 Section 5.3.10: "If the configured authentication string 187c74ad251Schristos * is shorter than 8 bytes, the remaining space MUST be zero-filled. 188c74ad251Schristos */ 189c74ad251Schristos nd_printjnp(ndo, bp, 8); 190c74ad251Schristos ND_PRINT("\""); 1910f74e101Schristos } 1920f74e101Schristos } 1930f74e101Schristos } 194