From owner-freebsd-net@FreeBSD.ORG Thu Oct 20 15:15:08 2011 Return-Path: Delivered-To: net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E979A106566B for ; Thu, 20 Oct 2011 15:15:08 +0000 (UTC) (envelope-from dan@dan.emsphone.com) Received: from email2.allantgroup.com (email2.emsphone.com [199.67.51.116]) by mx1.freebsd.org (Postfix) with ESMTP id 892F68FC16 for ; Thu, 20 Oct 2011 15:15:08 +0000 (UTC) Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101]) by email2.allantgroup.com (8.14.4/8.14.4) with ESMTP id p9KErkUR009622 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 20 Oct 2011 09:53:47 -0500 (CDT) (envelope-from dan@dan.emsphone.com) Received: from dan.emsphone.com (smmsp@localhost [127.0.0.1]) by dan.emsphone.com (8.14.5/8.14.5) with ESMTP id p9KErk0F084524 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 20 Oct 2011 09:53:46 -0500 (CDT) (envelope-from dan@dan.emsphone.com) Received: (from dan@localhost) by dan.emsphone.com (8.14.5/8.14.5/Submit) id p9KErk8x084393; Thu, 20 Oct 2011 09:53:46 -0500 (CDT) (envelope-from dan) Date: Thu, 20 Oct 2011 09:53:46 -0500 From: Dan Nelson To: George Neville-Neil Message-ID: <20111020145346.GA86426@dan.emsphone.com> References: <00C1A678-1654-40D2-9ADD-1857C2ECCA04@neville-neil.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="5mCyUwZo2JvN/JJP" Content-Disposition: inline In-Reply-To: <00C1A678-1654-40D2-9ADD-1857C2ECCA04@neville-neil.com> X-OS: FreeBSD 8.2-STABLE User-Agent: Mutt/1.5.21 (2010-09-15) X-Virus-Scanned: clamav-milter 0.97.2 at email2.allantgroup.com X-Virus-Status: Clean X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.6 (email2.allantgroup.com [199.67.51.78]); Thu, 20 Oct 2011 09:53:47 -0500 (CDT) X-Scanned-By: MIMEDefang 2.68 on 199.67.51.78 Cc: net@freebsd.org Subject: Re: Patch to enable our tcpdump to handle CARP X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Oct 2011 15:15:09 -0000 --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--