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 /* \summary: Virtual Router Redundancy Protocol (VRRP) printer */ 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #include <netdissect-stdinc.h> 33 34 #include "netdissect.h" 35 #include "extract.h" 36 #include "addrtoname.h" 37 38 #include "ip.h" 39 #include "ipproto.h" 40 /* 41 * RFC 2338 (VRRP v2): 42 * 43 * 0 1 2 3 44 * 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 45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 46 * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| 47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 48 * | Auth Type | Adver Int | Checksum | 49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 50 * | IP Address (1) | 51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 52 * | . | 53 * | . | 54 * | . | 55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 56 * | IP Address (n) | 57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 58 * | Authentication Data (1) | 59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 60 * | Authentication Data (2) | 61 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 62 * 63 * 64 * RFC 5798 (VRRP v3): 65 * 66 * 0 1 2 3 67 * 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 68 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 69 * | IPv4 Fields or IPv6 Fields | 70 * ... ... 71 * | | 72 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 73 * |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr| 74 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 75 * |(rsvd) | Max Adver Int | Checksum | 76 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 77 * | | 78 * + + 79 * | IPvX Address(es) | 80 * + + 81 * | | 82 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 83 */ 84 85 /* Type */ 86 #define VRRP_TYPE_ADVERTISEMENT 1 87 88 static const struct tok type2str[] = { 89 { VRRP_TYPE_ADVERTISEMENT, "Advertisement" }, 90 { 0, NULL } 91 }; 92 93 /* Auth Type */ 94 #define VRRP_AUTH_NONE 0 95 #define VRRP_AUTH_SIMPLE 1 96 #define VRRP_AUTH_AH 2 97 98 static const struct tok auth2str[] = { 99 { VRRP_AUTH_NONE, "none" }, 100 { VRRP_AUTH_SIMPLE, "simple" }, 101 { VRRP_AUTH_AH, "ah" }, 102 { 0, NULL } 103 }; 104 105 void 106 vrrp_print(netdissect_options *ndo, 107 register const u_char *bp, register u_int len, 108 register const u_char *bp2, int ttl) 109 { 110 int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */ 111 const char *type_s; 112 113 ND_TCHECK(bp[0]); 114 version = (bp[0] & 0xf0) >> 4; 115 type = bp[0] & 0x0f; 116 type_s = tok2str(type2str, "unknown type (%u)", type); 117 ND_PRINT((ndo, "VRRPv%u, %s", version, type_s)); 118 if (ttl != 255) 119 ND_PRINT((ndo, ", (ttl %u)", ttl)); 120 if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT) 121 return; 122 ND_TCHECK(bp[2]); 123 ND_PRINT((ndo, ", vrid %u, prio %u", bp[1], bp[2])); 124 ND_TCHECK(bp[5]); 125 126 if (version == 2) { 127 auth_type = bp[4]; 128 ND_PRINT((ndo, ", authtype %s", tok2str(auth2str, NULL, auth_type))); 129 ND_PRINT((ndo, ", intvl %us, length %u", bp[5], len)); 130 } else { /* version == 3 */ 131 uint16_t intvl = (bp[4] & 0x0f) << 8 | bp[5]; 132 ND_PRINT((ndo, ", intvl %ucs, length %u", intvl, len)); 133 } 134 135 if (ndo->ndo_vflag) { 136 int naddrs = bp[3]; 137 int i; 138 char c; 139 140 if (version == 2 && ND_TTEST2(bp[0], len)) { 141 struct cksum_vec vec[1]; 142 143 vec[0].ptr = bp; 144 vec[0].len = len; 145 if (in_cksum(vec, 1)) { 146 ND_TCHECK_16BITS(&bp[6]); 147 ND_PRINT((ndo, ", (bad vrrp cksum %x)", 148 EXTRACT_16BITS(&bp[6]))); 149 } 150 } 151 152 if (version == 3 && ND_TTEST2(bp[0], len)) { 153 uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp, 154 len, len, IPPROTO_VRRP); 155 if (cksum) { 156 ND_TCHECK_16BITS(&bp[6]); 157 ND_PRINT((ndo, ", (bad vrrp cksum %x)", 158 EXTRACT_16BITS(&bp[6]))); 159 } 160 } 161 162 ND_PRINT((ndo, ", addrs")); 163 if (naddrs > 1) 164 ND_PRINT((ndo, "(%d)", naddrs)); 165 ND_PRINT((ndo, ":")); 166 c = ' '; 167 bp += 8; 168 for (i = 0; i < naddrs; i++) { 169 ND_TCHECK(bp[3]); 170 ND_PRINT((ndo, "%c%s", c, ipaddr_string(ndo, bp))); 171 c = ','; 172 bp += 4; 173 } 174 if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ 175 ND_TCHECK(bp[7]); 176 ND_PRINT((ndo, " auth \"")); 177 if (fn_printn(ndo, bp, 8, ndo->ndo_snapend)) { 178 ND_PRINT((ndo, "\"")); 179 goto trunc; 180 } 181 ND_PRINT((ndo, "\"")); 182 } 183 } 184 return; 185 trunc: 186 ND_PRINT((ndo, "[|vrrp]")); 187 } 188