]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Add a CARP dissector and a command-line option to dissect proto 112 as CARP.
authorGeorge Neville-Neil <[email protected]>
Wed, 23 Nov 2011 19:53:13 +0000 (11:53 -0800)
committerGuy Harris <[email protected]>
Wed, 23 Nov 2011 19:53:48 +0000 (11:53 -0800)
CARP and VRRP both use IP protocol number 112, so there needs to be a -T
flag to specify that protocol 112 be dissected as CARP rather than VRRP.

Also update the man page.

Makefile.in
interface.h
ipproto.c
ipproto.h
netdissect.h
print-carp.c [new file with mode: 0644]
print-ip.c
tcpdump.c

index 48634a1a36c3db8f4a34db82f5824905ed2448e1..b62327d605cf17392033398eec04dd65633d8ab4 100644 (file)
@@ -73,8 +73,8 @@ CSRC =        addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c
        print-802_11.c print-802_15_4.c print-ap1394.c print-ah.c \
        print-arcnet.c print-aodv.c print-arp.c print-ascii.c print-atalk.c \
        print-atm.c print-beep.c print-bfd.c print-bgp.c \
-       print-bootp.c print-bt.c print-cdp.c print-cfm.c print-chdlc.c \
-       print-cip.c print-cnfp.c print-dccp.c print-decnet.c \
+       print-bootp.c print-bt.c print-carp.c print-cdp.c print-cfm.c \
+       print-chdlc.c print-cip.c print-cnfp.c print-dccp.c print-decnet.c \
        print-domain.c print-dtp.c print-dvmrp.c print-enc.c print-egp.c \
        print-eap.c print-eigrp.c\
        print-esp.c print-ether.c print-fddi.c print-fr.c \
index ae1cc2f9231aac3cf337dd4bad9afab8a44af4d1..18668a21f3773758056e53363af8007a7d4f210d 100644 (file)
@@ -70,6 +70,7 @@ extern char *strsep(char **, const char *);
 #define PT_CNFP                7       /* Cisco NetFlow protocol */
 #define PT_TFTP                8       /* trivial file transfer protocol */
 #define PT_AODV                9       /* Ad-hoc On-demand Distance Vector Protocol */
+#define PT_CARP         10      /* Common Address Redundancy Protocol */
 
 #ifndef min
 #define min(a,b) ((a)>(b)?(b):(a))
@@ -290,6 +291,7 @@ extern const char *nt_errstr(u_int32_t);
 extern void print_data(const unsigned char *, int);
 extern void l2tp_print(const u_char *, u_int);
 extern void vrrp_print(const u_char *, u_int, int);
+extern void carp_print(const u_char *, u_int, int);
 extern void slow_print(const u_char *, u_int);
 extern void sflow_print(const u_char *, u_int);
 extern void mpcp_print(const u_char *, u_int);
index 644b364277199ceba1c5892feb52d56d9a12c44c..cbb9bf3f74e6191f6b40896e13bbfffeb592974b 100755 (executable)
--- a/ipproto.c
+++ b/ipproto.c
@@ -55,6 +55,7 @@ const struct tok ipproto_values[] = {
     { IPPROTO_PGM, "PGM" },
     { IPPROTO_SCTP, "SCTP" },
     { IPPROTO_MOBILITY, "Mobility" },
+    { IPPROTO_CARP, "CARP" },
     { 0, NULL }
 };
 
index 96407541f64dd891e875cf15aab513c490f84fef..c9801a624a491dfc20c27acf40f6e0aa50ed5167 100644 (file)
--- a/ipproto.h
+++ b/ipproto.h
@@ -133,6 +133,9 @@ extern const struct tok ipproto_values[];
 #ifndef IPPROTO_VRRP
 #define IPPROTO_VRRP           112
 #endif
+#ifndef IPPROTO_CARP
+#define IPPROTO_CARP           112
+#endif
 #ifndef IPPROTO_PGM
 #define IPPROTO_PGM             113
 #endif
index 5b589c78ac7dc75ba804c0b52366eb504e6b7b64..0c66dfaf809487800dcb10db80f5c8f89829ab4a 100644 (file)
@@ -450,6 +450,8 @@ extern void l2tp_print(netdissect_options *,const u_char *, u_int);
 extern void lcp_print(netdissect_options *,const u_char *, u_int);
 extern void vrrp_print(netdissect_options *,const u_char *bp,
                       u_int len, int ttl);
+extern void carp_print(netdissect_options *,const u_char *bp,
+                      u_int len, int ttl);
 extern void cdp_print(netdissect_options *,const u_char *,
                      u_int, u_int, const u_char *, const u_char *);
 extern void stp_print(netdissect_options *,const u_char *p, u_int length);
diff --git a/print-carp.c b/print-carp.c
new file mode 100644 (file)
index 0000000..ba5be7c
--- /dev/null
@@ -0,0 +1,88 @@
+/*     $OpenBSD: print-carp.c,v 1.6 2009/10/27 23:59:55 deraadt Exp $  */
+
+/*
+ * Copyright (c) 2000 William C. Fenner.
+ *                All rights reserved.
+ *
+ * Kevin Steves <[email protected]> July 2000
+ * Modified to:
+ * - print version, type string and packet length
+ * - print IP address count if > 1 (-v)
+ * - verify checksum (-v)
+ * - print authentication string (-v)
+ *
+ * Copyright (c) 2011 Advanced Computing Technologies
+ * George V. Neille-Neil
+ *
+ * Modified to:
+ * - work correctly with CARP
+ * - compile into the latest tcpdump
+ * - print out the counter
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * The name of William C. Fenner may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+void
+carp_print(register const u_char *bp, register u_int len, int ttl)
+{
+       int version, type;
+       const char *type_s;
+
+       TCHECK(bp[0]);
+       version = (bp[0] & 0xf0) >> 4;
+       type = bp[0] & 0x0f;
+       if (type == 1)
+               type_s = "advertise";
+       else
+               type_s = "unknown";
+       printf("CARPv%d-%s %d: ", version, type_s, len);
+       if (ttl != 255)
+               printf("[ttl=%d!] ", ttl);
+       if (version != 2 || type != 1)
+               return;
+       TCHECK(bp[2]);
+       TCHECK(bp[5]);
+       printf("vhid=%d advbase=%d advskew=%d authlen=%d ",
+           bp[1], bp[5], bp[2], bp[3]);
+       if (vflag) {
+               struct cksum_vec vec[1];
+               vec[0].ptr = (const u_int8_t *)bp;
+               vec[0].len = len;
+               if (TTEST2(bp[0], len) && in_cksum(vec, 1))
+                       printf(" (bad carp cksum %x!)",
+                               EXTRACT_16BITS(&bp[6]));
+       }
+       printf("counter=%" PRIu64, EXTRACT_64BITS(&bp[8]));
+
+       return;
+trunc:
+       printf("[|carp]");
+}
index d2df0a898c999fb46ed497be53d9b1fadb924e1e..1fa7aab0d6cae8830aa92c9f8ac3cf37dfb9d01a 100644 (file)
@@ -462,7 +462,19 @@ again:
                break;
 
        case IPPROTO_VRRP:
-               vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+               if (packettype == PT_CARP) {
+                       if (vflag)
+                               (void)printf("carp %s > %s: ",
+                                            ipaddr_string(&ipds->ip->ip_src),
+                                            ipaddr_string(&ipds->ip->ip_dst));
+                       carp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+               } else {
+                       if (vflag)
+                               (void)printf("vrrp %s > %s: ",
+                                            ipaddr_string(&ipds->ip->ip_src),
+                                            ipaddr_string(&ipds->ip->ip_dst));
+                       vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+               }
                break;
 
        case IPPROTO_PGM:
index ee9304d55f8cc8aeeef0bc5d348945fe4ac52797..ac35b2b3490986d3d8c08b16a1478f62e6a55a6f 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -933,6 +933,8 @@ main(int argc, char **argv)
                                packettype = PT_TFTP;
                        else if (strcasecmp(optarg, "aodv") == 0)
                                packettype = PT_AODV;
+                       else if (strcasecmp(optarg, "carp") == 0)
+                               packettype = PT_CARP;
                        else
                                error("unknown packet type `%s'", optarg);
                        break;