Ethereal-dev: [ethereal-dev] ipsec/ike support for tcpdump 3.4 (fwd)

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

Date Prev Thread Prev
From: Bill Fumerola <billf@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 29 Jun 1999 17:57:01 -0400 (EDT)
This may help someone somewhere. Maybe not.

- bill fumerola - billf@xxxxxxxxxxxxxx - BF1560 - computer horizons corp -
- ph:(800) 252-2421 - bfumerol@xxxxxxxxxxxxxxxxxxxx - billf@xxxxxxxxxxx  -



---------- Forwarded message ----------
Date: Wed, 30 Jun 1999 00:45:49 +0300 (EEST)
From: Timo J Rinne <tri@xxxxxx>
To: tcpdump@xxxxxxxxxx, bugs@xxxxxxxxxxx, bugs@xxxxxxxxxx, bugs@xxxxxxxxxxx,
    bugs@xxxxxxxxx
Subject: ipsec/ike support for tcpdump 3.4

Hi

While developing our IPSEC Express Toolkit we at SSH Communications
Security have hacked support for printing IPSEC and IKE packets with
tcpdump.  Support is not complete but still it has proven very helpful
in our development efforts.  In hope that these are useful for other
IPSEC developers we contribute our patches to tcpdump developers as
well as to {{Free,Net,Open}BSD,Linux} teams.

Best Regards,
//Rinne

>>>>>>>>>>>>>>>>>>   C U T   H E R E   >>>>>>>>>>>>>>>>>>

--- INSTALL.orig	Thu Sep 17 14:04:36 1998
+++ INSTALL	Wed Jun 30 00:20:14 1999
@@ -112,7 +112,9 @@
 print-gre.c	- Generic Routing Encapsulation printer routines
 print-icmp.c	- Internet Control Message Protocol printer routines
 print-igrp.c	- Interior Gateway Routing Protocol printer routines
+print-ike.c	- internet key exchange (ike, isakmp/oakley) printer routines
 print-ip.c	- ip printer routines
+print-ipsec.c   - ipsec (esp/ah) printer routines
 print-ipx.c	- IPX printer routines
 print-isoclns.c	- isoclns printer routines
 print-krb.c	- Kerberos printer routines
--- Makefile.in.orig	Thu Sep 17 14:04:37 1998
+++ Makefile.in	Wed Jun 30 00:23:18 1999
@@ -71,7 +71,8 @@
 	print-llc.c print-nfs.c print-ntp.c print-null.c print-ospf.c \
 	print-pim.c print-ppp.c print-raw.c print-rip.c print-sl.c \
 	print-snmp.c print-sunrpc.c print-tcp.c print-tftp.c print-udp.c \
-	print-wb.c addrtoname.c bpf_dump.c gmt2local.c machdep.c \
+	print-wb.c print-ike.c print-ipsec.c \
+	addrtoname.c bpf_dump.c gmt2local.c machdep.c \
 	parsenfsfh.c util.c savestr.c setsignal.c
 LOCALSRC =
 GENSRC = version.c
--- print-ip.c.orig	Thu Sep 17 14:04:59 1998
+++ print-ip.c	Wed Jun 30 00:22:42 1999
@@ -477,6 +477,20 @@
   			}
   			break;
 
+#ifndef IPPROTO_ESP
+#define IPPROTO_ESP 50
+#endif
+		case IPPROTO_ESP:
+		        esp_print(cp, len, (const u_char *)ip);
+			break;
+
+#ifndef IPPROTO_AH
+#define IPPROTO_AH 51
+#endif
+		case IPPROTO_AH:
+		        ah_print(cp, len, (const u_char *)ip);
+			break;
+
 		default:
 			(void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
 				ipaddr_string(&ip->ip_dst));
--- print-udp.c.orig	Thu Sep 17 14:05:14 1998
+++ print-udp.c	Tue Jun 29 22:07:19 1999
@@ -293,6 +293,9 @@
 #define SNMPTRAP_PORT 162	/*XXX*/
 #define RIP_PORT 520		/*XXX*/
 #define KERBEROS_SEC_PORT 750	/*XXX*/
+#define ISAKMP_PORT 500		/*XXX*/
+#define ISAKMP_UPORT1 7500	/*XXX*/
+#define ISAKMP_UPORT2 8500	/*XXX*/
 
 void
 udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
@@ -432,6 +435,10 @@
 			ntp_print((const u_char *)(up + 1), length);
 		else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT))
 			krb_print((const void *)(up + 1), length);
+                else if (ISPORT(ISAKMP_PORT) ||
+                         ISPORT(ISAKMP_UPORT1) ||
+                         ISPORT(ISAKMP_UPORT2))
+                        isakmp_print((const u_char *)(up + 1), length);
 		else if (dport == 3456)
 			vat_print((const void *)(up + 1), length, up);
 		/*
--- tcpdump.1.orig	Sun Jan 10 13:14:11 1999
+++ tcpdump.1	Tue Jun 29 22:17:43 1999
@@ -215,6 +215,11 @@
 The smaller of the entire packet or
 .I snaplen
 bytes will be printed.
+.TP
+.B \-X
+Like
+.B \-x
+but dumps the packet in emacs-hexl like format.
 .IP "\fI expression\fP"
 .RS
 selects which packets will be dumped.  If no \fIexpression\fP
--- tcpdump.c.orig	Sat Mar  6 14:31:26 1999
+++ tcpdump.c	Tue Jun 29 22:21:22 1999
@@ -66,6 +66,7 @@
 int tflag = 1;			/* print packet arrival time */
 int vflag;			/* verbose */
 int xflag;			/* print packet in hex */
+int Xflag;			/* print packet in emacs-hexl style */
 
 int packettype;
 
@@ -149,7 +150,7 @@
 
 	opterr = 0;
 	while (
-	    (op = getopt(argc, argv, "ac:defF:i:lnNOpqr:s:StT:vw:xY")) != EOF)
+	    (op = getopt(argc, argv, "ac:defF:i:lnNOpqr:s:StT:vw:xXY")) != EOF)
 		switch (op) {
 
 		case 'a':
@@ -263,6 +264,12 @@
 			++xflag;
 			break;
 
+		case 'X':
+			++Xflag;
+			if (xflag == 0)
+				++xflag;
+			break;
+
 		default:
 			usage();
 			/* NOTREACHED */
@@ -381,6 +388,55 @@
 	exit(0);
 }
 
+/* dump the buffer in `emacs-hexl' style */
+void
+tcp_hexdump(unsigned int offset, const u_char *cp, unsigned int length)
+{
+        unsigned int i, j, jm;
+        int c;
+        char ln[128];
+
+        printf("\n");
+        for (i = 0; i < length; i += 0x10) {
+                snprintf(ln, 
+                         sizeof(ln),
+                         "  %04x: ", (unsigned int)(i + offset));
+                jm = length - i;
+                jm = jm > 16 ? 16 : jm;
+
+                for (j = 0; j < jm; j++) {
+                        if ((j % 2) == 1)
+                                snprintf(ln + strlen(ln),
+                                         sizeof(ln) - strlen(ln),
+                                         "%02x ", (unsigned int)cp[i+j]);
+                        else
+                                snprintf(ln + strlen(ln), 
+                                         sizeof(ln) - strlen(ln),
+                                         "%02x", (unsigned int)cp[i+j]);
+                }
+                for (; j < 16; j++) {
+                        if ((j % 2) == 1)
+                                snprintf(ln + strlen(ln), 
+                                         sizeof(ln) - strlen(ln),
+                                         "   ");
+                        else
+                                snprintf(ln + strlen(ln), 
+                                         sizeof(ln) - strlen(ln),
+                                         "  ");
+                }                         
+
+                snprintf(ln + strlen(ln), sizeof(ln) - strlen(ln), " ");
+                for (j = 0; j < jm; j++) {
+                        c = cp[i+j];
+                        c = c < 32 || c >= 127 ? '.' : c;
+                        snprintf(ln + strlen(ln), 
+                                 sizeof(ln) - strlen(ln), 
+                                 "%c", c);
+                }
+                printf("%s\n", ln);
+        }
+}
+
 /* Like default_print() but data need not be aligned */
 void
 default_print_unaligned(register const u_char *cp, register u_int length)
@@ -388,6 +444,11 @@
 	register u_int i, s;
 	register int nshorts;
 
+        if (Xflag) {
+                /* dump the buffer in `emacs-hexl' style */
+                tcp_hexdump(0, cp, length);
+        } else {
+                /* dump the buffer in old tcpdump style */
 	nshorts = (u_int) length / sizeof(u_short);
 	i = 0;
 	while (--nshorts >= 0) {
@@ -402,6 +463,7 @@
 		(void)printf(" %02x", *cp);
 	}
 }
+}
 
 /*
  * By default, print the packet out in hex.
@@ -415,6 +477,11 @@
 	register u_int i;
 	register int nshorts;
 
+        if (Xflag) {
+                /* dump the buffer in `emacs-hexl' style */
+                tcp_hexdump(0, bp, length);
+        } else {
+                /* dump the buffer in old tcpdump style */
 	if ((long)bp & 1) {
 		default_print_unaligned(bp, length);
 		return;
@@ -433,6 +500,7 @@
 		(void)printf(" %02x", *(u_char *)sp);
 	}
 }
+}
 
 __dead void
 usage(void)
@@ -443,7 +511,7 @@
 	(void)fprintf(stderr, "%s version %s\n", program_name, version);
 	(void)fprintf(stderr, "libpcap version %s\n", pcap_version);
 	(void)fprintf(stderr,
-"Usage: %s [-adeflnNOpqStvx] [-c count] [ -F file ]\n", program_name);
+"Usage: %s [-adeflnNOpqStvxX] [-c count] [ -F file ]\n", program_name);
 	(void)fprintf(stderr,
 "\t\t[ -i interface ] [ -r file ] [ -s snaplen ]\n");
 	(void)fprintf(stderr,
--- /dev/null	Wed Jun 30 00:14:17 1999
+++ print-ike.c	Wed Jun 30 00:29:13 1999
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * 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, (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, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may 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.
+ *
+ * Format and print ike (isakmp) packets.
+ *	By Tero Kivinen <kivinen@xxxxxx>, Tero Mononen <tmo@xxxxxx>,
+ *         Tatu Ylonen <ylo@xxxxxx> and Timo J. Rinne <tri@xxxxxx>
+ *         in co-operation with SSH Communications Security, Espoo, Finland
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: print-ike.c,v 0.0 00/00/00 00:00:00 xxx Exp $ (XXX)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <net/ethernet.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#ifdef MODEMASK
+#undef MODEMASK					/* Solaris sucks */
+#endif
+
+struct isakmp_header {
+	u_char  init_cookie[8];
+	u_char  resp_cookie[8];
+	u_char  nextpayload;
+	u_char  version;
+	u_char  exgtype;
+	u_char  flags;
+	u_char  msgid[4];
+	u_int32_t length;
+	u_char  payloads[0];  
+};
+
+static int isakmp_doi;
+
+#define FLAGS_ENCRYPTION 1
+#define FLAGS_COMMIT     2
+
+#define PAYLOAD_NONE       0
+#define PAYLOAD_SA         1
+#define PAYLOAD_PROPOSAL   2
+#define PAYLOAD_TRANSFORM  3
+#define PAYLOAD_KE         4
+#define PAYLOAD_ID         5
+#define PAYLOAD_CERT       6
+#define PAYLOAD_CERTREQUEST 7
+#define PAYLOAD_HASH       8
+#define PAYLOAD_SIG        9
+#define PAYLOAD_NONCE     10
+#define PAYLOAD_NOTIFICATION 11
+#define PAYLOAD_DELETE    12
+
+#define IPSEC_DOI          1
+
+static void isakmp_pl_print(register u_char type, 
+			    register u_char *payload, 
+			    register int paylen);
+
+/*
+ * Print isakmp requests
+ */
+void isakmp_print(register const u_char *cp, register int length)
+{
+	struct isakmp_header *ih;
+	register const u_char *ep;
+	int mode, version, leapind;
+	u_char *payload;
+	u_char  nextpayload, np1;
+	u_int   paylen;
+	int encrypted;
+
+	encrypted = 0;
+
+#ifdef TCHECK
+#undef TCHECK
+#endif
+#define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
+	
+	ih = (struct isakmp_header *)cp;
+	/* Note funny sized packets */
+	if (length < 20) {
+	        (void)printf(" [len=%d]", length);
+	}
+
+	/* 'ep' points to the end of avaible data. */
+	ep = snapend;
+
+	printf(" isakmp");
+
+	printf(" v%d.%d\n\t", ih->version >> 4, ih->version & 0xf);
+
+	if (ih->flags & FLAGS_ENCRYPTION) {
+	        printf(" encrypted");
+		encrypted = 1;
+	}
+	
+	if (ih->flags & FLAGS_COMMIT) {
+	        printf(" commit");
+	}
+
+	printf(" cookie: %02x%02x%02x%02x%02x%02x%02x%02x->%02x%02x%02x%02x%02x%02x%02x%02x\n\t",
+	       ih->init_cookie[0], ih->init_cookie[1],
+	       ih->init_cookie[2], ih->init_cookie[3], 
+	       ih->init_cookie[4], ih->init_cookie[5], 
+	       ih->init_cookie[6], ih->init_cookie[7], 
+	       ih->resp_cookie[0], ih->resp_cookie[1], 
+	       ih->resp_cookie[2], ih->resp_cookie[3], 
+	       ih->resp_cookie[4], ih->resp_cookie[5], 
+	       ih->resp_cookie[6], ih->resp_cookie[7]);
+
+	TCHECK(ih->msgid, sizeof(ih->msgid));
+	printf(" msgid:%02x%02x%02x%02x",
+	       ih->msgid[0], ih->msgid[1],
+	       ih->msgid[2], ih->msgid[3]);
+
+	TCHECK(ih->length, sizeof(ih->length));
+	printf(" length %d", ntohl(ih->length));
+	
+	if (ih->version > 16) {
+	        printf(" new version");
+	        return;
+	}
+
+	/* now, process payloads */
+	payload = ih->payloads;
+	nextpayload = ih->nextpayload;
+
+	/* if encrypted, then open special file for encryption keys */
+	if (encrypted) {
+	        /* decrypt XXX */
+	        return;
+	}
+
+	while (nextpayload != 0) {
+	        np1 = payload[0];
+	        paylen = (payload[2] << 8) + payload[3];
+	        printf("\n\t\tload: %02x len: %04x",
+		       nextpayload, paylen);
+		TCHECK(payload[0], paylen);  
+		isakmp_pl_print(nextpayload, payload, paylen);
+		payload += paylen;
+		nextpayload = np1;
+	}
+
+	return;
+
+trunc:
+	fputs(" [|isakmp]", stdout);
+}
+
+void isakmp_sa_print(register u_char *buf, register int len)
+{
+	isakmp_doi = ntohl((*(u_int32_t *)(buf+4)));
+	printf(" SA doi: %d",
+	       isakmp_doi, (isakmp_doi == IPSEC_DOI ? "(ipsec)" : ""));
+	printf(" situation\n");
+}
+	
+void isakmp_proposal_print(register u_char *buf, register int len)
+{
+	u_char *spis;
+	int spisize, numspi, i;
+
+	spisize = buf[6];
+	numspi  = buf[7];
+	  
+
+	printf(" proposal number: %d protocol: %d spisize: %d #spi: %d", 
+	       buf[4], buf[5], spisize, numspi);
+
+	spis = buf+8;
+	while (numspi) {
+	        printf("\n\t ");
+		for (i=0; i<spisize; i++) {
+		        printf("%02x", *spis);
+			spis++;
+		}
+	}
+}
+	
+void isakmp_ke_print(register u_char *buf, register int len)
+{
+	if (isakmp_doi != IPSEC_DOI) {
+	        printf("KE unknown doi\n");
+		return;
+	}
+}
+	
+void isakmp_pl_print(register u_char type, 
+		     register u_char *buf, 
+		     register int len)
+{
+	switch(type) {
+	case PAYLOAD_NONE:
+	        return;
+	case PAYLOAD_SA:
+	        isakmp_sa_print(buf, len);
+	        break;
+	    
+	case PAYLOAD_PROPOSAL:
+	        isakmp_proposal_print(buf, len);
+	        break;
+	    
+	case PAYLOAD_TRANSFORM:
+	        break;
+	    
+	case PAYLOAD_KE:
+	        isakmp_ke_print(buf, len);
+	        break;
+	    
+	case PAYLOAD_ID:
+	case PAYLOAD_CERT:
+	case PAYLOAD_CERTREQUEST:
+	case PAYLOAD_HASH:
+	case PAYLOAD_SIG:
+	        break;
+	    
+	case PAYLOAD_NONCE:
+#if 0
+	        isakmp_nonce_print(buf, len);
+#endif
+	        break;
+	    
+	case PAYLOAD_NOTIFICATION:
+	case PAYLOAD_DELETE:
+	default:
+	}
+}
--- /dev/null	Wed Jun 30 00:14:17 1999
+++ print-ipsec.c	Wed Jun 30 00:29:48 1999
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * 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, (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, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may 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.
+ *
+ * Format and print ipsec (esp/ah) packets.
+ *      By Tero Kivinen <kivinen@xxxxxx>, Tero Mononen <tmo@xxxxxx>,  
+ *         Tatu Ylonen <ylo@xxxxxx> and Timo J. Rinne <tri@xxxxxx>
+ *         in co-operation with SSH Communications Security, Espoo, Finland    
+ */
+
+#ifndef lint
+static const char rcsid[] =
+    "@(#) $Header: print-ike.c,v 0.0 00/00/00 00:00:00 xxx Exp $ (XXX)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "extract.h"                    /* must come after interface.h */
+
+/*
+ * IPSec/ESP header
+ */
+struct esp_hdr {
+        u_int esp_spi;
+        u_int esp_seq;
+};
+
+void esp_print(register const u_char *bp, register u_int len,
+               register const u_char *bp2)
+{
+        const struct ip *ip;
+        const struct esp_hdr *esp;
+
+        ip = (const struct ip *)bp2;
+        esp = (const struct esp_hdr *)bp;
+
+        (void)printf("esp %s > %s spi 0x%08X seq %d",
+                     ipaddr_string(&ip->ip_src),
+                     ipaddr_string(&ip->ip_dst),
+                     ntohl(esp->esp_spi), ntohl(esp->esp_seq));
+
+}
+
+/*
+ * IPSec/AH header
+ */
+struct ah_hdr {
+        u_int ah_dummy;
+        u_int ah_spi;
+        u_int ah_seq;
+};
+
+ah_print(register const u_char *bp, register u_int len,
+         register const u_char *bp2)
+{
+        const struct ip *ip;
+        const struct ah_hdr *ah;
+
+        ip = (const struct ip *)bp2;
+        ah = (const struct ah_hdr *)bp;
+
+        (void)printf("ah %s > %s spi 0x%08X seq %d",
+                     ipaddr_string(&ip->ip_src),
+                     ipaddr_string(&ip->ip_dst),
+                     ntohl(ah->ah_spi), ntohl(ah->ah_seq));
+
+}
+


To Unsubscribe: send mail to majordomo@xxxxxxxxxxx
with "unsubscribe freebsd-bugs" in the body of the message