Michael Richardson wrote:
> 
> >>>>> "Volf," == Volf, Frank <[EMAIL PROTECTED]> writes:
>     Volf,> I once did a different approach, I made a patch to ipmon to write IP 
>packets
>     Volf> to a file format that can be read by tcpdump. I even made to tcpdump so it
>     Volf> could read and print these files). 
> 
>   patch appreciated...

Attached. Keep in mind that they need some clean up, which I will do when
this issue is resolved (any pointers appreciated):

>     Volf> It works as that tcpdump can indeed read the file and decode the packets. I
>     Volf> got stuck however trying to find out how the pcap compiler should be 
>changed
>     Volf> so you can apply tcpdump packet filter expressions on such a file, so you
>     Volf> can currently only dump the entire file.

To get this to work, you have to apply the ipmon patch to ipmon.c of IP
Filter 3.4.20, you have to apply the tcpdump patch on the CVS'uped tcpdump
tree and you have to copy the ipfilter.h and print-ipfilter.c files to the
tcpdump directory.

Frank

--- ipmon.c.orig	Sun Aug  5 21:41:06 2001
+++ ipmon.c	Mon Aug  6 19:06:45 2001
@@ -65,6 +65,11 @@
 #include "netinet/ip_nat.h"
 #include "netinet/ip_state.h"
 
+#define _NET_BPF_H_
+#include "/home/volf/anoncvs/tcpdump/libpcap/net/bpf.h"
+#include "/home/volf/anoncvs/tcpdump/libpcap/pcap-int.h"
+#include "/home/volf/anoncvs/tcpdump/tcpdump/ipfilter.h"
+
 #if !defined(lint)
 static const char sccsid[] = "@(#)ipmon.c	1.21 6/5/96 (C)1993-2000 Darren Reed";
 static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.12.2.13 2001/07/19 12:24:59 darrenr Exp $";
@@ -110,6 +115,8 @@
 static	int	opts = 0;
 static	FILE	*newlog = NULL;
 static	char	*logfile = NULL;
+static	char	*tcpdumpfile = NULL;
+static	FILE	*tcpdump = NULL;
 static	int	donehup = 0;
 static	void	usage __P((char *));
 static	void	handlehup __P((int));
@@ -122,6 +129,7 @@
 static	int	read_log __P((int, int *, char *, int));
 static	void	write_pid __P((char *));
 static	char	*icmpname __P((u_int, u_int));
+static	FILE 	*open_tcpdump __P((const char *));
 
 char	*hostname __P((int, int, u_32_t *));
 char	*portname __P((int, char *, u_int));
@@ -142,6 +150,7 @@
 #define	OPT_VERBOSE	0x008
 #define	OPT_HEXHDR	0x010
 #define	OPT_TAIL	0x020
+#define	OPT_TCPDUMP	0x040
 #define	OPT_NAT		0x080
 #define	OPT_STATE	0x100
 #define	OPT_FILTER	0x200
@@ -703,6 +712,7 @@
 	struct	icmp	*ic;
 	struct	icmp	*icmp;
 	struct	tm	*tm;
+	struct  ipfilter_header ipfh;
 	char	*t, *proto;
 	int	i, v, lvl, res, len, off, plen, ipoff;
 	ip_t	*ipc, *ip;
@@ -713,12 +723,55 @@
 #ifdef	USE_INET6
 	ip6_t *ip6;
 #endif
+	char	ifname[16];
 
 	ipl = (iplog_t *)buf;
 	ipf = (ipflog_t *)((char *)buf + sizeof(*ipl));
 	ip = (ip_t *)((char *)ipf + sizeof(*ipf));
 	v = ip->ip_v;
 	res = (opts & OPT_RESOLVE) ? 1 : 0;
+
+#if (SOLARIS || \
+	(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+	(defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
+	len = (int)sizeof(ipf->fl_ifname);
+	(void) snprintf(ifname, 16, "%*.*s", len, len, ipf->fl_ifname);
+	t = ifname + strlen(ifname);
+# if SOLARIS
+	if (isalpha(*(t- 1)))
+		*t++ = '0' + ipf->fl_unit;
+# endif
+#else
+	for (len = 0; len < 3; len++)
+		if (ipf->fl_ifname[len] == '\0')
+			break;
+	if (ipf->fl_ifname[len])
+		len++;
+	(void) snprintf(ifname, 16, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
+#endif
+
+	if (tcpdump) {
+		struct pcap_sf_pkthdr sf_hdr;
+
+		sf_hdr.ts.tv_sec  = ipl->ipl_sec;
+		sf_hdr.ts.tv_usec = ipl->ipl_usec;
+		sf_hdr.caplen     = ipf->fl_hlen + ipf->fl_plen + sizeof(ipfh);
+		sf_hdr.len        = ip->ip_len + sizeof(ipfh);
+		strncpy(ipfh.ipf_ifname, ifname, sizeof(ipfh.ipf_ifname));
+		ipfh.ipf_rule     = ipf->fl_rule;
+		ipfh.ipf_group    = ipf->fl_group;
+		ipfh.ipf_flags	  = ipf->fl_flags;
+		ipfh.ipf_tag	  = ipf->fl_tag;
+		(void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, tcpdump);
+		(void)fwrite(&ipfh, sizeof(ipfh), 1, tcpdump);
+		ip->ip_len = htons(ip->ip_len);
+		ip->ip_off = htons(ip->ip_off);
+		(void)fwrite((char *)ip, ipf->fl_hlen + ipf->fl_plen, 1, tcpdump);
+		ip->ip_len = ntohs(ip->ip_len);
+		ip->ip_off = ntohs(ip->ip_off);
+		(void)fflush(tcpdump);
+	} 
+	
 	t = line;
 	*t = '\0';
 	tm = localtime((time_t *)&ipl->ipl_sec);
@@ -742,25 +795,8 @@
 		(void) sprintf(t, "%dx ", ipl->ipl_count);
 		t += strlen(t);
 	}
-#if (SOLARIS || \
-	(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
-	(defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
-	len = (int)sizeof(ipf->fl_ifname);
-	(void) sprintf(t, "%*.*s", len, len, ipf->fl_ifname);
-	t += strlen(t);
-# if SOLARIS
-	if (isalpha(*(t - 1)))
-		*t++ = '0' + ipf->fl_unit;
-# endif
-#else
-	for (len = 0; len < 3; len++)
-		if (ipf->fl_ifname[len] == '\0')
-			break;
-	if (ipf->fl_ifname[len])
-		len++;
-	(void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
+	(void) sprintf(t, ifname);
 	t += strlen(t);
-#endif
 	(void) sprintf(t, " @%hu:%hu ", ipf->fl_group, ipf->fl_rule + 1);
 	t += strlen(t);
 
@@ -1054,6 +1090,33 @@
 }
 
 
+static FILE *open_tcpdump(filename)
+const char *filename;
+{
+
+	FILE *fd;
+	
+	fd = fopen(filename, "w");
+	if (!fd) {
+		fprintf(stderr, "%s: fopen: %s\n", filename,  STRERROR(errno));
+		exit(1);
+	}
+	
+	
+	/* Snaplen, is the maximal size of logged packet. Be safe and
+	 * calculate 64 for the IP header and 128 data bytes that IP
+	 * Filteripmon logs when using 'log body'
+	 *
+	 * Timezone offset is currently set to zero, until I figure
+	 * out exactly how to change it
+	 */
+	sf_write_header(fd, DLT_IPFILTER, 0, 192);
+	(void)fflush(tcpdump);
+	
+	return fd;
+}
+
+
 int main(argc, argv)
 int argc;
 char *argv[];
@@ -1079,7 +1142,7 @@
 	else
 		argv0++;
 
-	while ((c = getopt(argc, argv, "?abDf:FhnN:o:O:pP:sS:tvxX")) != -1)
+	while ((c = getopt(argc, argv, "?abDf:FhnN:o:O:pP:sS:tT:vxX")) != -1)
 		switch (c)
 		{
 		case 'a' :
@@ -1141,6 +1204,10 @@
 		case 't' :
 			opts |= OPT_TAIL;
 			break;
+		case 'T' :
+			opts |= OPT_TCPDUMP;
+			tcpdumpfile = optarg;
+			break;
 		case 'v' :
 			opts |= OPT_VERBOSE;
 			break;
@@ -1201,6 +1268,9 @@
 	} else
 		log = NULL;
 
+	if (opts & OPT_TCPDUMP)
+		tcpdump = open_tcpdump(tcpdumpfile);
+	
 	if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) {
 #if BSD
 		daemon(0, !(opts & OPT_SYSLOG));
? tcpdump/print-ip.c.save
? tcpdump/print-icmp.c.save
? tcpdump/ipfilter.h
? tcpdump/print-ipfilter.c
Index: libpcap/gencode.c
===================================================================
RCS file: /tcpdump/master/libpcap/gencode.c,v
retrieving revision 1.157
diff -u -r1.157 gencode.c
--- gencode.c	2001/07/03 19:15:47	1.157
+++ gencode.c	2001/08/06 17:17:26
@@ -703,6 +703,11 @@
 		off_linktype = -1;
 		off_nl = 0;
 		return;
+	
+	case DLT_IPFILTER:
+		off_linktype = 115;
+		off_nl = 32;
+		return;
 	}
 	bpf_error("unknown data link type %d", linktype);
 	/* NOTREACHED */
Index: libpcap/pcap-int.h
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-int.h,v
retrieving revision 1.32
diff -u -r1.32 pcap-int.h
--- pcap-int.h	2000/12/21 10:29:23	1.32
+++ pcap-int.h	2001/08/06 17:17:26
@@ -203,6 +203,10 @@
 
 int	install_bpf_program(pcap_t *, struct bpf_program *);
 
+/* savefile public routines */
+int	sf_write_header(FILE *, int, int, int);
+           
+            
 #ifdef __cplusplus
 }
 #endif
Index: libpcap/savefile.c
===================================================================
RCS file: /tcpdump/master/libpcap/savefile.c,v
retrieving revision 1.51
diff -u -r1.51 savefile.c
--- savefile.c	2001/06/05 03:09:39	1.51
+++ savefile.c	2001/08/06 17:17:27
@@ -173,6 +173,8 @@
 
 #define LINKTYPE_LTALK		114		/* Apple LocalTalk hardware */
 
+#define LINKTYPE_IPFILTER	115		/* IP Filter capture files */
+
 static struct linktype_map {
 	int	dlt;
 	int	linktype;
@@ -235,6 +237,9 @@
 	/* Apple LocalTalk hardware */
 	{ DLT_LTALK,		LINKTYPE_LTALK },
 
+	/* IP Filter capture files */
+	{ DLT_IPFILTER,		LINKTYPE_IPFILTER },
+	
 	/*
 	 * Any platform that defines additional DLT_* codes should:
 	 *
@@ -292,7 +297,7 @@
 	return linktype;
 }
 
-static int
+int
 sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
 {
 	struct pcap_file_header hdr;
Index: libpcap/bpf/net/bpf.h
===================================================================
RCS file: /tcpdump/master/libpcap/bpf/net/bpf.h,v
retrieving revision 1.46
diff -u -r1.46 bpf.h
--- bpf.h	2001/06/05 03:09:40	1.46
+++ bpf.h	2001/08/06 17:17:28
@@ -282,6 +282,11 @@
 #define DLT_LTALK	114
 
 /*
+ * IP Filter format 
+ */
+#define DLT_IPFILTER	115 
+ 
+/*
  * The instruction encodings.
  */
 /* instruction classes */
Index: tcpdump/Makefile.in
===================================================================
RCS file: /tcpdump/master/tcpdump/Makefile.in,v
retrieving revision 1.252
diff -u -r1.252 Makefile.in
--- Makefile.in	2001/06/21 17:56:02	1.252
+++ Makefile.in	2001/08/06 17:17:28
@@ -82,7 +82,7 @@
 	print-snmp.c print-stp.c print-sunrpc.c print-tcp.c \
 	print-telnet.c print-tftp.c print-timed.c print-token.c \
 	print-udp.c print-vjc.c print-vrrp.c print-wb.c \
-	setsignal.c smbutil.c tcpdump.c util.c
+	setsignal.c smbutil.c tcpdump.c util.c print-ipfilter.c
 
 LOCALSRC = @LOCALSRC@
 GENSRC = version.c
Index: tcpdump/interface.h
===================================================================
RCS file: /tcpdump/master/tcpdump/interface.h,v
retrieving revision 1.166
diff -u -r1.166 interface.h
--- interface.h	2001/07/05 18:54:13	1.166
+++ interface.h	2001/08/06 17:17:29
@@ -145,7 +145,7 @@
 /* Bail if "var" was not captured */
 #define TCHECK(var) TCHECK2(var, sizeof(var))
 
-extern void ts_print(const struct timeval *);
+extern int ts_print(const struct timeval *);
 extern void relts_print(int);
 
 extern int fn_print(const u_char *, const u_char *);
@@ -281,6 +281,7 @@
 extern void pptp_print(const u_char *, u_int);
 extern void sctp_print(const u_char *, const u_char *, u_int);
 extern void mpls_print(const u_char *, u_int);
+extern void ipfilter_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p);
 
 #ifdef INET6
 extern void ip6_print(const u_char *, int);
Index: tcpdump/tcpdump.c
===================================================================
RCS file: /tcpdump/master/tcpdump/tcpdump.c,v
retrieving revision 1.166
diff -u -r1.166 tcpdump.c
--- tcpdump.c	2001/07/04 22:03:13	1.166
+++ tcpdump.c	2001/08/06 17:17:29
@@ -148,6 +148,9 @@
 #ifdef DLT_LTALK
 	{ ltalk_if_print,	DLT_LTALK },
 #endif
+#ifdef DLT_IPFILTER
+	{ ipfilter_print,	DLT_IPFILTER },
+#endif
 	{ NULL,			0 },
 };
 
@@ -159,7 +162,7 @@
 	for (p = printers; p->f; ++p)
 		if (type == p->type)
 			return p->f;
-
+		
 	error("unknown data link type %d", type);
 	/* NOTREACHED */
 }
Index: tcpdump/util.c
===================================================================
RCS file: /tcpdump/master/tcpdump/util.c,v
retrieving revision 1.69
diff -u -r1.69 util.c
--- util.c	2000/07/11 00:49:03	1.69
+++ util.c	2001/08/06 17:17:29
@@ -118,7 +118,7 @@
 /*
  * Print the timestamp
  */
-void
+int
 ts_print(register const struct timeval *tvp)
 {
 	register int s;
@@ -126,22 +126,23 @@
 	time_t Time;
 	static unsigned b_sec;
 	static unsigned b_usec;
+	int printed = 0;
 
 	switch(tflag) {
 	case 1: /* Default */
 		s = (tvp->tv_sec + thiszone) % 86400;
-		(void)printf("%02d:%02d:%02d.%06u ",
+		printed = printf("%02d:%02d:%02d.%06u ",
 			     s / 3600, (s % 3600) / 60, s % 60,
 			     (unsigned)tvp->tv_usec);
 		break;
 	case -1: /* Unix timeval style */
-		(void)printf("%u.%06u ",
+		printed = printf("%u.%06u ",
 			     (unsigned)tvp->tv_sec,
 			     (unsigned)tvp->tv_usec);
 		break;
 	case -2:
 		if (b_sec == 0) {
-			printf("000000 ");
+			printed = printf("000000 ");
 		} else {
 			int d_usec = tvp->tv_usec - b_usec;
 			int d_sec = tvp->tv_sec - b_sec;
@@ -151,8 +152,8 @@
 				d_sec--;
 			}
 			if (d_sec)
-				printf("%d. ", d_sec);
-			printf("%06d ", d_usec);
+				printed = printf("%d. ", d_sec);
+			printed += printf("%06d ", d_usec);
 		}
 		b_sec = tvp->tv_sec;
 		b_usec = tvp->tv_usec;
@@ -161,13 +162,15 @@
 		s = (tvp->tv_sec + thiszone) % 86400;
 		Time = (tvp->tv_sec + thiszone) - s;
 		tm  = gmtime (&Time);
-		(void)printf("%02d/%02d/%04d %02d:%02d:%02d.%06u ",
+		printed = printf("%02d/%02d/%04d %02d:%02d:%02d.%06u ",
 			     tm->tm_mon+1, tm->tm_mday,
 			     tm->tm_year+1900,
 			     s / 3600, (s % 3600) / 60,
 			     s % 60, (unsigned)tvp->tv_usec);
 		break;
 	}
+
+	return printed;
 }
 
 /*
/*
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
 *	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.
 */
#ifndef lint
static const char rcsid[] =
    "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.65 2001/07/04 22:03:14 fenner Exp $ (LBL)";
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>

struct mbuf;
struct rtentry;

#include <netinet/in.h>

#include <stdio.h>
#include <pcap.h>

#include "interface.h"
#include "addrtoname.h"
#include "ethertype.h"

#include "ipfilter.h"

const u_char *packetp;
const u_char *snapend;

/*
 * This is the top level routine of the printer.  'p' is the points
 * to the IP Filter header of the packet, 'h->tv' is the timestamp,
 * 'h->length' is the length of the packet off the wire, and 'h->caplen'
 * is the number of bytes actually captured.
 */
void
ipfilter_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
	struct ipfilter_header *ipfh;
	int decode_error = 0;
	int tssize;
	
	u_int caplen = h->caplen;
	u_int length = h->len;

	/* print timestamp */
	tssize = ts_print(&h->ts);
	if (caplen < IPFILTER_HDRLEN) {
		printf("[|ipfilter]");
		goto out;
	}

	/*
	 * Some printers want to check that they're not walking off the 
	 * end of the packet. Rather than pass them all the way down, we 
	 * set these globals.
	 */
	packetp = p;
	snapend = p + caplen;

	length -= IPFILTER_HDRLEN;
	caplen -= IPFILTER_HDRLEN;
	ipfh = (struct ipfilter_header *)p;
	p += IPFILTER_HDRLEN;

	/* print IP Filter action */
	decode_error = 0;
	if (ipfh->ipf_flags & IPFILTER_ACTION_BLOCK)
		printf("blocked");
	else if (ipfh->ipf_flags & IPFILTER_ACTION_PASS)
		printf("passed");
	else {
		printf("[unknown]");
		decode_error++;
	}

	/* print IP Filter direction  */
 	if (ipfh->ipf_flags & IPFILTER_DIRECTION_IN)
		printf(" in");
	else if (ipfh->ipf_flags & IPFILTER_DIRECTION_OUT)
		printf(" out");
	else {
		printf(" [unknown]");
		decode_error++;
	}
	
	/* print IP Filter interface */
	if (ipfh->ipf_ifname[0] == '\0')
		printf(" on [unknown]");
	else
		printf(" on %s", ipfh->ipf_ifname);	
	
	/* by which rule */
	printf(" by rule %d:%d", ipfh->ipf_group, ipfh->ipf_rule);	
	
	/* print tag */
	if (ipfh->ipf_tag != IPFILTER_NOTAG) {
		printf(" with tag %ul", ipfh->ipf_tag);
	}

	/* print the log flags when verbose or a decode error occured */
	if (vflag || decode_error) 
		printf(" [flags %lx]",  ipfh->ipf_flags);
		
	/* pad timestamp with spaces */
	printf("\n");
	while (tssize-- > 0)
		printf(" ");

	/* print IP packet */	
	ip_print(p, length);
	if (xflag)
		default_print(p, caplen);
	printf("\n");
	return;
	
 out:
	putchar('\n');
	--infodelay;
	if (infoprint)
		info(0);
}
/* @(#) $Header: /tcpdump/master/tcpdump/ether.h,v 1.6 2000/10/09 03:24:24 guy Exp $ (LBL) */
/*
 * Copyright (c) 1982, 1986, 1993
 *	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 the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)if_ether.h	8.3 (Berkeley) 5/2/95
 */


struct ipfilter_header {
	u_char		ipf_ifname[16];
	u_int32_t	ipf_rule;
	u_int32_t	ipf_group;
	u_int32_t	ipf_flags;
	u_int32_t	ipf_tag;
};

/*
 * The number of bytes in an ipfilter_header
 */
#define	IPFILTER_HDRLEN	32

/*
 * These need to be kept in sync with IP Filter
 */
#define	IPFILTER_ACTION_BLOCK	0x00000001
#define	IPFILTER_ACTION_PASS	0x00000002

#define	IPFILTER_DIRECTION_OUT	0x00000004
#define	IPFILTER_DIRECTION_IN	0x00000008

#define IPFILTER_NOTAG		0xffffffff

Reply via email to