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#if 0
29static const char rcsid[] _U_ =
30    "@(#) Header: /tcpdump/master/tcpdump/print-vrrp.c,v 1.10 2005-05-06 07:56:54 guy Exp";
31#else
32__RCSID("$NetBSD: print-vrrp.c,v 1.2 2010/12/05 05:11:31 christos Exp $");
33#endif
34#endif
35
36#ifdef HAVE_CONFIG_H
37#include "config.h"
38#endif
39
40#include <tcpdump-stdinc.h>
41
42#include <stdio.h>
43#include <stdlib.h>
44
45#include "interface.h"
46#include "extract.h"
47#include "addrtoname.h"
48
49/*
50 * RFC 2338:
51 *     0                   1                   2                   3
52 *     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
53 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 *    |Version| Type  | Virtual Rtr ID|   Priority    | Count IP Addrs|
55 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 *    |   Auth Type   |   Adver Int   |          Checksum             |
57 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 *    |                         IP Address (1)                        |
59 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 *    |                            .                                  |
61 *    |                            .                                  |
62 *    |                            .                                  |
63 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 *    |                         IP Address (n)                        |
65 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 *    |                     Authentication Data (1)                   |
67 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68 *    |                     Authentication Data (2)                   |
69 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 */
71
72/* Type */
73#define	VRRP_TYPE_ADVERTISEMENT	1
74
75static const struct tok type2str[] = {
76	{ VRRP_TYPE_ADVERTISEMENT,	"Advertisement"	},
77	{ 0,				NULL		}
78};
79
80/* Auth Type */
81#define	VRRP_AUTH_NONE		0
82#define	VRRP_AUTH_SIMPLE	1
83#define	VRRP_AUTH_AH		2
84
85static const struct tok auth2str[] = {
86	{ VRRP_AUTH_NONE,		"none"		},
87	{ VRRP_AUTH_SIMPLE,		"simple"	},
88	{ VRRP_AUTH_AH,			"ah"		},
89	{ 0,				NULL		}
90};
91
92void
93vrrp_print(register const u_char *bp, register u_int len, int ttl)
94{
95	int version, type, auth_type;
96	const char *type_s;
97
98	TCHECK(bp[0]);
99	version = (bp[0] & 0xf0) >> 4;
100	type = bp[0] & 0x0f;
101	type_s = tok2str(type2str, "unknown type (%u)", type);
102	printf("VRRPv%u, %s", version, type_s);
103	if (ttl != 255)
104		printf(", (ttl %u)", ttl);
105	if (version != 2 || type != VRRP_TYPE_ADVERTISEMENT)
106		return;
107	TCHECK(bp[2]);
108	printf(", vrid %u, prio %u", bp[1], bp[2]);
109	TCHECK(bp[5]);
110	auth_type = bp[4];
111	printf(", authtype %s", tok2str(auth2str, NULL, auth_type));
112	printf(", intvl %us, length %u", bp[5],len);
113	if (vflag) {
114		int naddrs = bp[3];
115		int i;
116		char c;
117
118		if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0))
119			printf(", (bad vrrp cksum %x)",
120				EXTRACT_16BITS(&bp[6]));
121		printf(", addrs");
122		if (naddrs > 1)
123			printf("(%d)", naddrs);
124		printf(":");
125		c = ' ';
126		bp += 8;
127		for (i = 0; i < naddrs; i++) {
128			TCHECK(bp[3]);
129			printf("%c%s", c, ipaddr_string(bp));
130			c = ',';
131			bp += 4;
132		}
133		if (auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */
134			TCHECK(bp[7]);
135			printf(" auth \"");
136			if (fn_printn(bp, 8, snapend)) {
137				printf("\"");
138				goto trunc;
139			}
140			printf("\"");
141		}
142	}
143	return;
144trunc:
145	printf("[|vrrp]");
146}
147