1 /* 2 * Copyright (c) 2000 William C. Fenner. 3 * All rights reserved. 4 * 5 * Kevin Steves <ks@hp.se> July 2000 6 * Modified to: 7 * - print version, type string and packet length 8 * - print IP address count if > 1 (-v) 9 * - verify checksum (-v) 10 * - print authentication string (-v) 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that: (1) source code 14 * distributions retain the above copyright notice and this paragraph 15 * in its entirety, and (2) distributions including binary code include 16 * the above copyright notice and this paragraph in its entirety in 17 * the documentation or other materials provided with the distribution. 18 * The name of William C. Fenner may not be used to endorse or 19 * promote products derived from this software without specific prior 20 * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND 21 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 22 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE. 24 */ 25 26 #include <sys/cdefs.h> 27 #ifndef lint 28 __RCSID("$NetBSD: print-vrrp.c,v 1.7 2019/10/01 16:06:16 christos Exp $"); 29 #endif 30 31 /* \summary: Virtual Router Redundancy Protocol (VRRP) printer */ 32 33 #ifdef HAVE_CONFIG_H 34 #include "config.h" 35 #endif 36 37 #include <netdissect-stdinc.h> 38 39 #include "netdissect.h" 40 #include "extract.h" 41 #include "addrtoname.h" 42 43 #include "ip.h" 44 #include "ipproto.h" 45 /* 46 * RFC 2338 (VRRP v2): 47 * 48 * 0 1 2 3 49 * 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 50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 51 * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| 52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 53 * | Auth Type | Adver Int | Checksum | 54 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 55 * | IP Address (1) | 56 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 57 * | . | 58 * | . | 59 * | . | 60 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 61 * | IP Address (n) | 62 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63 * | Authentication Data (1) | 64 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 65 * | Authentication Data (2) | 66 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 67 * 68 * 69 * RFC 5798 (VRRP v3): 70 * 71 * 0 1 2 3 72 * 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 73 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 74 * | IPv4 Fields or IPv6 Fields | 75 * ... ... 76 * | | 77 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 78 * |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr| 79 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 80 * |(rsvd) | Max Adver Int | Checksum | 81 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 82 * | | 83 * + + 84 * | IPvX Address(es) | 85 * + + 86 * | | 87 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 88 */ 89 90 /* Type */ 91 #define VRRP_TYPE_ADVERTISEMENT 1 92 93 static const struct tok type2str[] = { 94 { VRRP_TYPE_ADVERTISEMENT, "Advertisement" }, 95 { 0, NULL } 96 }; 97 98 /* Auth Type */ 99 #define VRRP_AUTH_NONE 0 100 #define VRRP_AUTH_SIMPLE 1 101 #define VRRP_AUTH_AH 2 102 103 static const struct tok auth2str[] = { 104 { VRRP_AUTH_NONE, "none" }, 105 { VRRP_AUTH_SIMPLE, "simple" }, 106 { VRRP_AUTH_AH, "ah" }, 107 { 0, NULL } 108 }; 109 110 void 111 vrrp_print(netdissect_options *ndo, 112 register const u_char *bp, register u_int len, 113 register const u_char *bp2, int ttl) 114 { 115 int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */ 116 const char *type_s; 117 118 ND_TCHECK(bp[0]); 119 version = (bp[0] & 0xf0) >> 4; 120 type = bp[0] & 0x0f; 121 type_s = tok2str(type2str, "unknown type (%u)", type); 122 ND_PRINT((ndo, "VRRPv%u, %s", version, type_s)); 123 if (ttl != 255) 124 ND_PRINT((ndo, ", (ttl %u)", ttl)); 125 if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT) 126 return; 127 ND_TCHECK(bp[2]); 128 ND_PRINT((ndo, ", vrid %u, prio %u", bp[1], bp[2])); 129 ND_TCHECK(bp[5]); 130 131 if (version == 2) { 132 auth_type = bp[4]; 133 ND_PRINT((ndo, ", authtype %s", tok2str(auth2str, NULL, auth_type))); 134 ND_PRINT((ndo, ", intvl %us, length %u", bp[5], len)); 135 } else { /* version == 3 */ 136 uint16_t intvl = (bp[4] & 0x0f) << 8 | bp[5]; 137 ND_PRINT((ndo, ", intvl %ucs, length %u", intvl, len)); 138 } 139 140 if (ndo->ndo_vflag) { 141 int naddrs = bp[3]; 142 int i; 143 char c; 144 145 if (version == 2 && ND_TTEST2(bp[0], len)) { 146 struct cksum_vec vec[1]; 147 148 vec[0].ptr = bp; 149 vec[0].len = len; 150 if (in_cksum(vec, 1)) { 151 ND_TCHECK_16BITS(&bp[6]); 152 ND_PRINT((ndo, ", (bad vrrp cksum %x)", 153 EXTRACT_16BITS(&bp[6]))); 154 } 155 } 156 157 if (version == 3 && ND_TTEST2(bp[0], len)) { 158 uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp, 159 len, len, IPPROTO_VRRP); 160 if (cksum) { 161 ND_TCHECK_16BITS(&bp[6]); 162 ND_PRINT((ndo, ", (bad vrrp cksum %x)", 163 EXTRACT_16BITS(&bp[6]))); 164 } 165 } 166 167 ND_PRINT((ndo, ", addrs")); 168 if (naddrs > 1) 169 ND_PRINT((ndo, "(%d)", naddrs)); 170 ND_PRINT((ndo, ":")); 171 c = ' '; 172 bp += 8; 173 for (i = 0; i < naddrs; i++) { 174 ND_TCHECK(bp[3]); 175 ND_PRINT((ndo, "%c%s", c, ipaddr_string(ndo, bp))); 176 c = ','; 177 bp += 4; 178 } 179 if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ 180 ND_TCHECK(bp[7]); 181 ND_PRINT((ndo, " auth \"")); 182 if (fn_printn(ndo, bp, 8, ndo->ndo_snapend)) { 183 ND_PRINT((ndo, "\"")); 184 goto trunc; 185 } 186 ND_PRINT((ndo, "\"")); 187 } 188 } 189 return; 190 trunc: 191 ND_PRINT((ndo, "[|vrrp]")); 192 } 193