TCP-MD5 (RFC 2385) digest verification if we have libcrypto.
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.224 2004-03-17 19:40:41 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.225 2004-03-23 07:15:36 guy Exp $ (LBL)
*/
#ifndef tcpdump_interface_h
extern int Xflag; /* print packet in hex/ascii */
extern int Aflag; /* print packet only in ascii observing TAB, LF, CR and SPACE as graphical chars */
extern char *espsecret;
+extern char *tcpmd5secret;
extern int packettype; /* as specified by -T */
#define PT_VAT 1 /* Visual Audio Tool */
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.110 2003-11-19 00:17:32 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.111 2004-03-23 07:15:36 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "nameser.h"
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/md5.h>
+
+static int tcp_verify_signature(const struct ip *ip, struct tcphdr *tp,
+ const u_char *data, int length, const u_char *rcvsig);
+#endif
+
static void print_tcp_rst_data(register const u_char *sp, u_int length);
#define MAX_RST_DATA_LEN 30
(void)printf(" %u", EXTRACT_32BITS(cp));
break;
+ case TCPOPT_SIGNATURE:
+ (void)printf("md5:");
+ if (IP_V(ip) != 4) {
+ (void)printf("!ipv4");
+ break;
+ }
+ datalen = TCP_SIGLEN;
+ LENCHECK(datalen);
+#ifdef HAVE_LIBCRYPTO
+ if (tcp_verify_signature(ip, tp,
+ bp + TH_OFF(tp) * 4, length, cp) == 0)
+ (void)printf("valid");
+ else
+ (void)printf("invalid");
+#else
+ for (i = 0; i < TCP_SIGLEN; ++i)
+ (void)printf("%02x", cp[i]);
+#endif
+ break;
+
default:
(void)printf("opt-%u:", opt);
datalen = len - 2;
}
putchar(']');
}
+
+#ifdef HAVE_LIBCRYPTO
+static int
+tcp_verify_signature(const struct ip *ip, struct tcphdr *tp,
+ const u_char *data, int length, const u_char *rcvsig)
+{
+ char sig[TCP_SIGLEN];
+ char zero_proto = 0;
+ MD5_CTX ctx;
+ u_short savecsum, tlen;
+
+ if (tcpmd5secret == NULL)
+ return (-1);
+
+ MD5_Init(&ctx);
+ /*
+ * Step 1: Update MD5 hash with IP pseudo-header.
+ */
+ MD5_Update(&ctx, (char *)&ip->ip_src, sizeof(ip->ip_src));
+ MD5_Update(&ctx, (char *)&ip->ip_dst, sizeof(ip->ip_dst));
+ MD5_Update(&ctx, (char *)&zero_proto, sizeof(zero_proto));
+ MD5_Update(&ctx, (char *)&ip->ip_p, sizeof(ip->ip_p));
+ tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4;
+ tlen = htons(tlen);
+ MD5_Update(&ctx, (char *)&tlen, sizeof(tlen));
+ /*
+ * Step 2: Update MD5 hash with TCP header, excluding options.
+ * The TCP checksum must be set to zero.
+ */
+ savecsum = tp->th_sum;
+ tp->th_sum = 0;
+ MD5_Update(&ctx, (char *)tp, sizeof(struct tcphdr));
+ tp->th_sum = savecsum;
+ /*
+ * Step 3: Update MD5 hash with TCP segment data, if present.
+ */
+ if (length > 0)
+ MD5_Update(&ctx, data, length);
+ /*
+ * Step 4: Update MD5 hash with shared secret.
+ */
+ MD5_Update(&ctx, tcpmd5secret, strlen(tcpmd5secret));
+ MD5_Final(sig, &ctx);
+
+ return (memcmp(rcvsig, sig, 16));
+}
+#endif /* HAVE_LIBCRYPTO */
-/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.10 2002-12-11 07:14:11 guy Exp $ (LBL) */
+/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.11 2004-03-23 07:15:37 guy Exp $ (LBL) */
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
#define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */
#define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */
#define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */
+#define TCPOPT_SIGNATURE 19 /* Keyed MD5 (rfc2385) */
+#define TCPOLEN_SIGNATURE 18
+
+#define TCP_SIGLEN 16 /* length of an option 19 digest */
#define TCPOPT_TSTAMP_HDR \
(TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
-.\" @(#) $Header: /tcpdump/master/tcpdump/Attic/tcpdump.1,v 1.160 2004-01-26 02:05:18 guy Exp $ (LBL)
+.\" @(#) $Header: /tcpdump/master/tcpdump/Attic/tcpdump.1,v 1.161 2004-03-23 07:15:37 guy Exp $ (LBL)
.\"
.\" $NetBSD: tcpdump.8,v 1.9 2003/03/31 00:18:17 perry Exp $
.\"
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH TCPDUMP 1 "25 January 2004"
+.TH TCPDUMP 1 "22 March 2004"
.SH NAME
tcpdump \- dump traffic on a network
.SH SYNOPSIS
.I module
]
[
+.B \-M
+.I secret
+]
+[
.B \-r
.I file
]
This option
can be used several times to load several MIB modules into \fItcpdump\fP.
.TP
+.B \-M
+Use \fIsecret\fP as a shared secret for validating the digests found in
+TCP segments with the TCP-MD5 option (RFC 2385), if present.
+.TP
.B \-n
Don't convert addresses (i.e., host addresses, port numbers, etc.) to names.
.TP
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.236 2004-03-19 21:36:35 risso Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.237 2004-03-23 07:15:38 guy Exp $ (LBL)";
#endif
/*
const char *dlt_name = NULL;
char *espsecret = NULL; /* ESP secret key */
+char *tcpmd5secret = NULL; /* TCP-MD5 secret key */
int packettype;
opterr = 0;
while (
- (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:YZ:")) != -1)
+ (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:YZ:")) != -1)
switch (op) {
case 'a':
#endif
break;
+ case 'M':
+ /* TCP-MD5 shared secret */
+#ifndef HAVE_LIBCRYPTO
+ warning("crypto code not compiled in");
+#endif
+ tcpmd5secret = optarg;
+ break;
+
case 'O':
Oflag = 0;
break;
(void)fprintf(stderr,
"Usage: %s [-aAd" D_FLAG "eflLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name);
(void)fprintf(stderr,
-"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -r file ]\n");
+"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]\n");
(void)fprintf(stderr,
-"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n");
+"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n");
(void)fprintf(stderr,
"\t\t[ -y datalinktype ] [ -Z user ]\n");
(void)fprintf(stderr,