From: George Neville-Neil Date: Wed, 23 Nov 2011 19:53:13 +0000 (-0800) Subject: Add a CARP dissector and a command-line option to dissect proto 112 as CARP. X-Git-Tag: tcpdump-4.2.1~10 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/214e360d476a7022b1bfbd0d5a1ba922cb5d6ea4 Add a CARP dissector and a command-line option to dissect proto 112 as CARP. 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. --- diff --git a/Makefile.in b/Makefile.in index 48634a1a..b62327d6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 \ diff --git a/interface.h b/interface.h index ae1cc2f9..18668a21 100644 --- a/interface.h +++ b/interface.h @@ -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); diff --git a/ipproto.c b/ipproto.c index 644b3642..cbb9bf3f 100755 --- 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 } }; diff --git a/ipproto.h b/ipproto.h index 96407541..c9801a62 100644 --- 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 diff --git a/netdissect.h b/netdissect.h index 5b589c78..0c66dfaf 100644 --- a/netdissect.h +++ b/netdissect.h @@ -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 index 00000000..ba5be7c6 --- /dev/null +++ b/print-carp.c @@ -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 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 + +#include +#include +#include + +#include + +#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]"); +} diff --git a/print-ip.c b/print-ip.c index d2df0a89..1fa7aab0 100644 --- a/print-ip.c +++ b/print-ip.c @@ -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: diff --git a/tcpdump.c b/tcpdump.c index ee9304d5..ac35b2b3 100644 --- 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;