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