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