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