Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Oct 2011 09:53:46 -0500
From:      Dan Nelson <dnelson@allantgroup.com>
To:        George Neville-Neil <gnn@neville-neil.com>
Cc:        net@freebsd.org
Subject:   Re: Patch to enable our tcpdump to handle CARP
Message-ID:  <20111020145346.GA86426@dan.emsphone.com>
In-Reply-To: <00C1A678-1654-40D2-9ADD-1857C2ECCA04@neville-neil.com>
References:  <00C1A678-1654-40D2-9ADD-1857C2ECCA04@neville-neil.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--5mCyUwZo2JvN/JJP
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

In the last episode (Oct 19), George Neville-Neil said:
> I've been trying to debug CARP problems of late. I noticed that our
> tcpdump didn't have CARP support.  I took and fixed some code from OpenBSD
> so that our tcpdump can work with CARP.  Unlike OpenBSD you have to
> specify -T carp to read carp packets.  In their version you specify -T
> VRRP, because they don't like VRRP.  I decided that we should go with what
> most of the industry cares about rather than what OpenBSD cares about.
> 
> Patch is here: http://people.freebsd.org/~gnn/tcpdump-carp.diff
> 
> Technical comments welcome.

Here's the patch I've been using.  I include a rendering of the packet
format in the comments (since the CARP packet is otherwise completely
undocumented), and also examine the packet to decide whether to print it as
CARP or VRRP.  CARP hardcodes a 7 in the AuthLen field, so it'll get the
packet type right unless you happen to use VRRP with 7 IP addresses.

-- 
	Dan Nelson
	dnelson@allantgroup.com

--5mCyUwZo2JvN/JJP
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="carp.diff"

Index: print-vrrp.c
===================================================================
--- print-vrrp.c	(revision 226523)
+++ print-vrrp.c	(working copy)
@@ -62,6 +62,33 @@ static const char rcsid[] _U_ =
  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *    |                     Authentication Data (2)                   |
  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *
+ * The CARP header layout is as follows.  The distinguishing feature
+ * seems to be that the AuthLen field is always 7:
+ *
+ *     0                   1                   2                   3
+ *     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
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |Version| Type  | VirtualHostID |    AdvSkew    | AuthLen == 7  |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |    Demote     |     AdvBase   |          Checksum             |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                         Counter (1)                           |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                         Counter (2)                           |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                        SHA-1 HMAC (1)                         |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                        SHA-1 HMAC (2)                         |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                        SHA-1 HMAC (3)                         |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                        SHA-1 HMAC (4)                         |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                        SHA-1 HMAC (5)                         |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
  */
 
 /* Type */
@@ -85,6 +112,9 @@ static const struct tok auth2str[] = {
 };
 
 void
+carp_print(register const u_char *bp, register u_int len, int ttl);
+
+void
 vrrp_print(register const u_char *bp, register u_int len, int ttl)
 {
 	int version, type, auth_type;
@@ -93,6 +123,13 @@ vrrp_print(register const u_char *bp, register u_i
 	TCHECK(bp[0]);
 	version = (bp[0] & 0xf0) >> 4;
 	type = bp[0] & 0x0f;
+
+	if ((bp[3] == 7) && (version == 2) && (type == 1))
+	{
+		carp_print(bp, len, ttl);
+		return;
+	}
+
 	type_s = tok2str(type2str, "unknown type (%u)", type);
 	printf("VRRPv%u, %s", version, type_s);
 	if (ttl != 255)
@@ -139,3 +176,30 @@ vrrp_print(register const u_char *bp, register u_i
 trunc:
 	printf("[|vrrp]");
 }
+
+void
+carp_print(register const u_char *bp, register u_int len, int ttl)
+{
+	int version, type, auth_type;
+	const char *type_s;
+
+	TCHECK(bp[0]);
+	version = (bp[0] & 0xf0) >> 4;
+	type = bp[0] & 0x0f;
+	type_s = tok2str(type2str, "unknown type (%u)", type);
+	printf("CARPv%u, %s", version, type_s);
+	if (ttl != 255)
+		printf(", (ttl %u)", ttl);
+	if (version != 2 || type != VRRP_TYPE_ADVERTISEMENT)
+		return;
+	TCHECK(bp[2]);
+	printf(", vhid %u, advskew %u", bp[1], bp[2]);
+	TCHECK(bp[5]);
+	printf(", advbase %us", bp[5]);
+	TCHECK(bp[15]);
+	printf(", counter %llu", EXTRACT_64BITS(&bp[8]));
+
+	return;
+trunc:
+	printf("[|carp]");
+}

--5mCyUwZo2JvN/JJP--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111020145346.GA86426>