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>