Ethereal-dev: [Ethereal-dev] Firestorm Network Intrusion Detection support for Ethereal

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

From: John Leach <john@xxxxxxxxxxxxxxx>
Date: 05 Mar 2003 10:13:41 +0000
Hi all,

I've added support to Ethereal 0.9.9 for the Firestorm Network Intrusion
Detection System.  Ethereal can now open and display the Firestorm elog
files, which contains alert data and the captured packet.

I've added a new protocols dissectors to display the alert information
(not actually a protocol; it grabs the data from the record header).

Firestorm writes the entire capture data into it's elog files, so the
packet includes any SLL layer stuff too.  I modified the SLL dissector
to register itself for use by the alert dissector, and added a new SLL
dissector to support Linux mmapped SLL headers (different size and
structure to the usual SLL header).

My patch
http://www.johnleach.co.uk/downloads/firestorm/ethereal/ethereal-0.9.9-elog.diff
(attached too) (+.asc for gpg sig)

Screen shot
http://www.johnleach.co.uk/downloads/firestorm/ethereal/sshot02.png

Firestorm
http://www.scaramanga.co.uk/firestorm

I could generate some dummy elog files to play with if anybody needs
them.

-- 
GPG KEY: B89C D450 5B2C 74D8 58FB A360 9B06 B5C2 26F0 3047
   HTTP: http://www.johnleach.co.uk
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/Makefile.am ethereal-0.9.9-elog/Makefile.am
--- ethereal-0.9.9/Makefile.am	2003-03-03 15:41:45.000000000 +0000
+++ ethereal-0.9.9-elog/Makefile.am	2003-02-16 16:25:44.000000000 +0000
@@ -177,6 +177,7 @@
 	packet-eap.c \
 	packet-eapol.c \
 	packet-eigrp.c \
+	packet-elog.c \
 	packet-esis.c  \
 	packet-eth.c   \
 	packet-ethertype.c   \
@@ -258,6 +259,7 @@
 	packet-mdshdr.c \
 	packet-mip.c  \
 	packet-mmse.c  \
+	packet-mmsll.c \
 	packet-mount.c \
 	packet-mpeg1.c  \
 	packet-mpls.c \
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/packet-elog.c ethereal-0.9.9-elog/packet-elog.c
--- ethereal-0.9.9/packet-elog.c	1970-01-01 01:00:00.000000000 +0100
+++ ethereal-0.9.9-elog/packet-elog.c	2003-03-03 15:36:59.000000000 +0000
@@ -0,0 +1,177 @@
+/* packet-fsalert.c
+ * Routines for Firestorm ELOG Packet disassembly
+ * Copyright 2003 John Leach <john@xxxxxxxxxxxxxxx>
+ *
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <netinet/in.h>
+#include <string.h>
+#include "prefs.h"
+#include "etypes.h"
+#include <epan/resolv.h>
+#include "wiretap/elog.h"
+#include "wiretap/elog_read.h"
+
+#define TPACKET_SIZE            32
+
+static dissector_handle_t	data_handle;
+
+static int proto_elog = -1;
+
+static gint hf_elog_encap = -1;
+static gint hf_elog_alert = -1;
+static gint hf_elog_generator = -1;
+static gint hf_elog_sid = -1;
+static gint hf_elog_rev = -1;
+static gint hf_elog_prio = -1;
+static gint fsa_frame = -1;
+static gint *fsat[] = {
+	&fsa_frame,
+};
+
+struct {
+	char *fs_name;
+	char *et_name;
+	dissector_handle_t d_handle;
+	int offset;
+}elog_encaps[]={
+	{"linux", "mmsll", NULL, TPACKET_SIZE},
+	{"sll", "sll", NULL, 0 },
+	{"ethernet", "eth", NULL, 0},
+	{"802.3", "eth", NULL, 0 },
+	{"802.3-novell", "ipx", NULL, 0},
+	{"ip", "ip", NULL, 0},
+	{NULL,NULL,NULL,0}
+};
+
+
+static void
+dissect_elog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	proto_item 	*ti;
+	proto_tree	*volatile fh_tree = NULL;
+        tvbuff_t 	*next_tvb;
+	char		*decoder;
+	int		i;
+
+	/* Get first decoder layer name */
+	decoder=pinfo->pseudo_header->elog.decode_buf+sizeof(struct elog_dhdr);
+	/* Build elog protocol tree */
+	if (tree) {
+		/* Root elog node */
+		ti = proto_tree_add_protocol_format(tree, 
+				proto_elog,tvb, 0, 0, "Firestorm ELOG");
+	  	fh_tree = proto_item_add_subtree(ti, fsa_frame);
+		/* Alert attribute */
+		proto_tree_add_string_format(fh_tree, hf_elog_alert, tvb, 0 ,0, 
+				pinfo->pseudo_header->elog.alert, "Alert: %s", 
+				pinfo->pseudo_header->elog.alert);
+		/* Encap attribute */
+		proto_tree_add_string_format(fh_tree, hf_elog_encap, tvb, 0 ,0, 
+				decoder, "Encapsulation: %s", 
+				decoder);
+		/* Generator attribute */
+		proto_tree_add_string_format(fh_tree, hf_elog_generator, tvb, 0 ,0, 
+				pinfo->pseudo_header->elog.generator, "Generator: %s",
+				pinfo->pseudo_header->elog.generator);
+		/* Priority Attribute */
+		proto_tree_add_uint(fh_tree, hf_elog_prio, tvb, 0 ,0, 
+				pinfo->pseudo_header->elog.hdr->h.prio);
+		/* SID Attribute */
+		proto_tree_add_uint(fh_tree, hf_elog_sid, tvb, 0 ,0, 
+				ntohl(pinfo->pseudo_header->elog.hdr->sid));
+		/* Rev Attribute */
+		proto_tree_add_uint(fh_tree, hf_elog_rev, tvb, 0 ,0, 
+				ntohl(pinfo->pseudo_header->elog.hdr->rev));
+	}
+	/* Detect what encapsulation type the first layer is and call 
+	 * appropriate dissector */
+	for (i=0;;i++) {
+		if (elog_encaps[i].fs_name==NULL) break;
+		if (strncmp(decoder,elog_encaps[i].fs_name,strlen(elog_encaps[i].fs_name))==0) {
+			next_tvb = tvb_new_subset(tvb,elog_encaps[i].offset,-1,-1);
+			call_dissector(elog_encaps[i].d_handle, next_tvb, pinfo, tree);
+			goto done;
+		}
+
+	}
+	/* Data dissector as default */
+	call_dissector(data_handle, tvb, pinfo, tree);
+done:
+	return;
+}
+
+void
+proto_register_elog(void)
+{
+	/* Define the elog fields  */
+	static hf_register_info hf[] = {
+		{ &hf_elog_alert,
+		       { "Alert", "elog.alert",  FT_STRING, BASE_DEC, 
+			       NULL, 0x0,"", HFILL }},		       
+		{ &hf_elog_encap,
+		       { "Encapsulation", "elog.encap",  FT_STRING, BASE_DEC, 
+			       NULL, 0x0,"", HFILL }},		       
+		{ &hf_elog_generator,
+		       { "Generator", "elog.generator",  FT_STRING, BASE_DEC, 
+			       NULL, 0x0,"", HFILL }},		       
+		{ &hf_elog_prio,
+		       { "Priority", "elog.prio",  FT_UINT32, BASE_DEC, 
+			       NULL, 0x0,"", HFILL }},
+		{ &hf_elog_sid,
+		       { "Sid", "elog.sid",  FT_UINT32, BASE_DEC, 
+			       NULL, 0x0,"", HFILL }},
+		{ &hf_elog_rev,
+		       { "Revision", "elog.rev",  FT_UINT32, BASE_DEC, 
+			       NULL, 0x0,"", HFILL }},
+	};
+	/* Register the elog protocol, fields and subtree */
+	proto_elog = proto_register_protocol("Firestorm ELOG", "Firestorm ELOG", "elog"); 
+	proto_register_field_array(proto_elog, hf, array_length(hf));
+	proto_register_subtree_array(fsat, array_length(fsat));
+	/* Register the dissector */
+	register_dissector("elog", dissect_elog, proto_elog);
+}
+
+void
+proto_reg_handoff_elog(void)
+{
+	int	i;
+	dissector_handle_t elog_handle;
+
+	/* Find all dissector handles */
+	for (i=0;;i++) {
+		if (elog_encaps[i].et_name==NULL) break;
+		elog_encaps[i].d_handle = find_dissector(elog_encaps[i].et_name);
+	}
+
+	data_handle = find_dissector("data");
+	
+	/* Add our dissector */
+	elog_handle = find_dissector("elog");
+	dissector_add("wtap_encap", WTAP_ENCAP_ELOG, elog_handle);
+}
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/packet-mmsll.c ethereal-0.9.9-elog/packet-mmsll.c
--- ethereal-0.9.9/packet-mmsll.c	1970-01-01 01:00:00.000000000 +0100
+++ ethereal-0.9.9-elog/packet-mmsll.c	2003-03-03 15:30:41.000000000 +0000
@@ -0,0 +1,304 @@
+/* packet-mmsll.c
+ * Routines for disassembly of packets from MMapped packet socket Linux 
+ * "cooked mode" captures
+ *
+ * Copyright 2003 John Leach <john@xxxxxxxxxxxxxxx>
+ * based on packet-sll.c
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <epan/packet.h>
+#include <netinet/in.h>
+#include "packet-sll.h"
+#include "packet-ipx.h"
+#include "packet-llc.h"
+#include <epan/resolv.h>
+#include "etypes.h"
+
+static int proto_mmsll = -1;
+static int hf_mmsll_pkttype = -1;
+static int hf_mmsll_hatype = -1;
+static int hf_mmsll_halen = -1;
+static int hf_mmsll_src_eth = -1;
+static int hf_mmsll_src_other = -1;
+static int hf_mmsll_ltype = -1;
+static int hf_mmsll_etype = -1;
+static int hf_mmsll_trailer = -1;
+static int hf_mmsll_family = -1;
+static int hf_mmsll_ifindex = -1;
+
+static gint ett_mmsll = -1;
+
+/*
+  	SLL header structure from Linux for mmapped packet socket:
+	struct sockaddr_ll
+	{
+	        unsigned short  sll_family;
+	        unsigned short  sll_protocol;
+	        int             sll_ifindex;
+	        unsigned short  sll_hatype;
+	        unsigned char   sll_pkttype;
+	        unsigned char   sll_halen;
+	        unsigned char   sll_addr[8];
+	};
+
+*/
+
+/*
+ * A DLT_LINUX_SLL fake link-layer header.
+ */
+#define MMSLL_HEADER_SIZE	20		/* total header length */
+
+/*
+ * The LINUX_SLL_ values for "sll_pkttype"
+ */
+#define LINUX_SLL_HOST		0
+#define LINUX_SLL_BROADCAST	1
+#define LINUX_SLL_MULTICAST	2
+#define LINUX_SLL_OTHERHOST	3
+#define LINUX_SLL_OUTGOING	4
+
+static const value_string packet_type_vals[] = {
+	{ LINUX_SLL_HOST,	"Unicast to us" },
+	{ LINUX_SLL_BROADCAST,	"Broadcast" },
+	{ LINUX_SLL_MULTICAST,	"Multicast" },
+	{ LINUX_SLL_OTHERHOST,	"Unicast to another host" },
+	{ LINUX_SLL_OUTGOING,	"Sent by us" },
+	{ 0,			NULL }
+};
+
+/*
+ * The LINUX_SLL_ values for "sll_protocol".
+ */
+#define LINUX_SLL_P_802_3	0x0001	/* Novell 802.3 frames without 802.2 LLC header */
+#define LINUX_SLL_P_802_2	0x0004	/* 802.2 frames (not D/I/X Ethernet) */
+
+static const value_string ltype_vals[] = {
+	{ LINUX_SLL_P_802_3,	"Raw 802.3" },
+	{ LINUX_SLL_P_802_2,	"802.2 LLC" },
+	{ 0,			NULL }
+};
+
+static dissector_handle_t ipx_handle;
+static dissector_handle_t llc_handle;
+static dissector_handle_t data_handle;
+
+static void
+dissect_mmsll(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	guint8 pkttype;
+	guint16 protocol;
+	guint16 hatype, halen, family;
+	guint32 ifindex;
+	const guint8 *src;
+	proto_item *ti;
+	tvbuff_t *next_tvb;
+	proto_tree *fh_tree = NULL;
+
+	if (check_col(pinfo->cinfo, COL_PROTOCOL))
+		col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMSLL");
+	if (check_col(pinfo->cinfo, COL_INFO))
+		col_clear(pinfo->cinfo, COL_INFO);
+
+	/* Packet Type */
+	pkttype = tvb_get_guint8(tvb, 10);		
+	if (check_col(pinfo->cinfo, COL_INFO))
+		col_add_str(pinfo->cinfo, COL_INFO,
+		    val_to_str(pkttype, packet_type_vals, "Unknown (%u)"));
+
+	if (tree) {
+		ti = proto_tree_add_protocol_format(tree, proto_mmsll, tvb, 0,
+		    MMSLL_HEADER_SIZE, "Linux mmapped cooked capture");
+		fh_tree = proto_item_add_subtree(ti, ett_mmsll);
+		proto_tree_add_item(fh_tree, hf_mmsll_pkttype, tvb, 10, 1, FALSE);
+	}
+
+	/* Family - This is in host order, see ifindex below for conversion */
+	family = tvb_get_ntohs(tvb,0);
+	
+	/* ifindex  (Interface index) */
+	ifindex = tvb_get_ntohl(tvb,4);
+	/* Unfortunately for us this is in host order.  This is a nasty hack to
+	   try and detect endian-ness I think it's highly unlikely you'll find
+	   an interface index of this size */
+	if ( ifindex & (0xFF << 24) ) {
+		ifindex = ntohl(ifindex); 
+		family = ntohs(family);
+	}
+	if (tree) {
+		proto_tree_add_uint(fh_tree, hf_mmsll_family, tvb, 0, 2, family);
+		proto_tree_add_uint(fh_tree, hf_mmsll_ifindex, tvb, 4, 4, ifindex);
+	}
+
+	/*
+	 * XXX - check the link-layer address type value?
+	 * For now, we just assume 6 means Ethernet.
+	 */
+	hatype = tvb_get_ntohs(tvb, 8);
+	halen = tvb_get_guint8(tvb, 11);
+	if (tree) {
+		proto_tree_add_uint(fh_tree, hf_mmsll_hatype, tvb, 8, 2, hatype);
+		proto_tree_add_uint(fh_tree, hf_mmsll_halen, tvb, 11, 1, halen);
+	}
+	if (halen == 6) {
+		src = tvb_get_ptr(tvb, 12, 6);
+		SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
+		SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
+		if (tree) {
+			proto_tree_add_ether(fh_tree, hf_mmsll_src_eth, tvb,
+			    12, 6, src);
+		}
+	} else {
+		if (tree) {
+			proto_tree_add_item(fh_tree, hf_mmsll_src_other, tvb,
+			   12, halen, FALSE);
+		}
+	}
+
+	/* Protocol */
+	protocol = tvb_get_ntohs(tvb, 2);
+	if (protocol <= 1536) {	/* yes, 1536 - that's how Linux does it */
+		/*
+		 * "proto" is *not* a length field, it's a Linux internal
+		 * protocol type.
+		 * We therefore cannot say how much of the packet will
+		 * be trailer data.
+		 * XXX - do the same thing we do for packets with Ethertypes?
+		 */
+		proto_tree_add_uint(fh_tree, hf_mmsll_ltype, tvb, 2, 2,
+		    protocol);
+
+		/* skip the tpacket data, bleh */		
+		next_tvb = tvb_new_subset(tvb, 48, -1, -1);
+		switch (protocol) {
+
+		case LINUX_SLL_P_802_2:
+			/*
+			 * 802.2 LLC.
+			 */
+			call_dissector(llc_handle, next_tvb, pinfo, tree);
+			break;
+
+		case LINUX_SLL_P_802_3:
+			/*
+			 * Novell IPX inside 802.3 with no 802.2 LLC
+			 * header.
+			 */
+			call_dissector(ipx_handle, next_tvb, pinfo, tree);
+			break;
+
+		default:
+			call_dissector(data_handle, next_tvb, pinfo, tree);
+			break;
+		}
+	} else {
+		ethertype(protocol, tvb, 48, pinfo, tree,
+		    fh_tree, hf_mmsll_etype, hf_mmsll_trailer);
+	}
+	
+}
+
+void
+proto_register_mmsll(void)
+{
+	static hf_register_info hf[] = {
+		{ &hf_mmsll_pkttype,
+		{ "Packet type",	"mmsll.pkttype", FT_UINT16, BASE_DEC,
+		  VALS(packet_type_vals), 0x0, "Packet type", HFILL }},
+
+		/* ARP hardware type?  With Linux extensions? */
+		{ &hf_mmsll_hatype,
+		{ "Link-layer address type",	"mmsll.hatype", FT_UINT16, BASE_DEC,
+		  NULL, 0x0, "Link-layer address type", HFILL }},
+
+		{ &hf_mmsll_halen,
+		{ "Link-layer address length",	"mmsll.halen", FT_UINT16, BASE_DEC,
+		  NULL, 0x0, "Link-layer address length", HFILL }},
+
+		/* Source address if it's an Ethernet-type address */
+		{ &hf_mmsll_src_eth,
+		{ "Source",	"mmsll.src.eth", FT_ETHER, BASE_NONE, NULL, 0x0,
+			"Source link-layer address", HFILL }},
+
+		/* Source address if it's not an Ethernet-type address */
+		{ &hf_mmsll_src_other,
+		{ "Source",	"mmsll.src.other", FT_BYTES, BASE_HEX, NULL, 0x0,
+			"Source link-layer address", HFILL }},
+
+		/* if the protocol field is an internal Linux protocol type */
+		{ &hf_mmsll_ltype,
+		{ "Protocol",	"mmsll.ltype", FT_UINT16, BASE_HEX,
+		   VALS(ltype_vals), 0x0, "Linux protocol type", HFILL }},
+
+		/* registered here but handled in ethertype.c */
+		{ &hf_mmsll_etype,
+		{ "Protocol",	"mmsll.etype", FT_UINT16, BASE_HEX,
+		   VALS(etype_vals), 0x0, "Ethernet protocol type", HFILL }},
+		
+		/* Family */
+		{ &hf_mmsll_family,
+		{ "Family",	"mmsll.family", FT_UINT16, BASE_DEC,
+		   NULL, 0x0, "Family", HFILL }},
+		
+		/* Ifindex */
+		{ &hf_mmsll_ifindex,
+		{ "IfIndex",	"mmsll.ifindex", FT_UINT32, BASE_DEC,
+		   NULL, 0x0, "Interface index", HFILL }},
+
+                { &hf_mmsll_trailer,
+		{ "Trailer", "mmsll.trailer", FT_BYTES, BASE_NONE, NULL, 0x0,
+			"Trailer", HFILL }},
+	};
+	static gint *ett[] = {
+		&ett_mmsll,
+	};
+
+	proto_mmsll = proto_register_protocol("Linux mmapped cooked-mode capture",
+	    "MMSLL", "mmsll" );
+	proto_register_field_array(proto_mmsll, hf, array_length(hf));
+	proto_register_subtree_array(ett, array_length(ett));
+	register_dissector("mmsll", dissect_mmsll, proto_mmsll);
+		
+}
+
+void
+proto_reg_handoff_mmsll(void)
+{
+	dissector_handle_t mmsll_handle;
+
+	/*
+	 * Get handles for the IPX and LLC dissectors.
+	 */
+	llc_handle = find_dissector("llc");
+	ipx_handle = find_dissector("ipx");
+	data_handle = find_dissector("data");
+
+	mmsll_handle = create_dissector_handle(dissect_mmsll, proto_mmsll);
+	dissector_add("wtap_encap", WTAP_ENCAP_MMSLL, mmsll_handle);
+}
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/elog.c ethereal-0.9.9-elog/wiretap/elog.c
--- ethereal-0.9.9/wiretap/elog.c	1970-01-01 01:00:00.000000000 +0100
+++ ethereal-0.9.9-elog/wiretap/elog.c	2003-02-02 19:09:04.000000000 +0000
@@ -0,0 +1,165 @@
+/*
+* This file is part of Firestorm NIDS
+* Copyright (c) 2002 Gianni Tedesco
+* This program is released under the terms of the GNU GPL version 2
+*
+* This file provides a simple API for reading elog files. It only
+* works for files <2GB right now and isn't very secure. Don't read
+* untrusted data files just yet.
+*
+* TODO:
+*  o Sliding mmap() to support large files
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+#include <elog.h>
+#include <elog_read.h>
+
+/* Create a new elog parsing structure */
+struct elog *elog_new(int fd)
+{
+	struct efile_hdr *fh;
+	struct elog *e;
+	struct stat st;
+	char *map;
+
+	if ( fd<0 )
+		return NULL;
+
+	/* Find length of the file */
+	if ( fstat(fd, &st) )
+		return NULL;
+
+	/* Make sure file is big enough for header */
+	if ( st.st_size < sizeof(*fh) )
+		return 0;
+
+	/* Map it all in */
+	if ( (map=mmap(NULL, st.st_size, PROT_READ,
+		MAP_SHARED, fd, 0))==MAP_FAILED ) {
+		return NULL;
+	}
+
+	/* Allocate a new structure */
+	if ( !(e=calloc(1,sizeof(struct elog))) ) {
+		munmap(map, st.st_size);
+		return NULL;
+	}
+
+	/* Check the header magic and versions */
+	fh=(struct efile_hdr *)map;
+	if ( ntohl(fh->magic)!=EF_MAGIC ||
+		fh->vers_major != EF_VERS_MAJ ||
+		fh->vers_minor != EF_VERS_MIN ) {
+		munmap(map, st.st_size);
+		free(e);
+		return NULL;
+	}
+
+	/* Fill it in */
+	e->fd=fd;
+	e->map=map;
+	e->end=map+st.st_size;
+	e->maplen=st.st_size;
+
+	return e;
+}
+
+/* Free the created structure */
+void elog_free(struct elog *e)
+{
+	if ( e->map )
+		munmap(e->map, e->maplen);
+
+	free(e);
+}
+
+/* Set the dispatch function */
+proc_elogfn elog_set_alert_fn(struct elog *e, proc_elogfn d)
+{
+	proc_elogfn old=d;
+	e->dispatch=d;
+	return old;
+}
+
+/* Run a single packet at a given offset */
+size_t elog_pkt(struct elog *e, size_t ofs)
+{
+	struct elog_pkthdr *ph;
+	struct elog_pkt pkt;
+	char *decode_buf;
+	char *pkt_data;
+	char *str_g;
+	char *str_a;
+	char *cur=e->map+ofs;
+
+	/* Check the header even exists */
+	if ( cur+sizeof(*ph) > e->end )
+		return 0;
+
+	/* Pull out all the bits we need */
+	ph=(struct elog_pkthdr *)cur;
+	decode_buf=cur+sizeof(*ph);
+	pkt_data=decode_buf+(ntohs(ph->decode_len)<<2);
+	str_g=pkt_data+(ntohl(ph->pkt_caplen));
+	str_a=str_g+ph->gen_len;
+
+	/* Only deal with alert packets for now */
+	if ( ntohs(ph->h.type) != ELOG_ALERT )
+		goto skip;
+
+	/* Quick integrity checks */
+	if ( ntohl(ph->h.reclen) < sizeof(*ph) )
+		return 0;
+
+	if ( cur+ntohl(ph->h.reclen) > e->end )
+		return 0;
+
+	if ( str_a+ph->alert_len > e->end )
+		return 0;
+
+	/* Check null termination of strings */
+	if ( str_g[ph->gen_len-1] )
+		goto skip;
+
+	if ( str_a[ph->alert_len-1] )
+		goto skip;
+
+	/* Fill in the structure */
+	pkt.file=e;
+	pkt.hdr=ph;
+	pkt.decode_buf=decode_buf;
+	pkt.data=pkt_data;
+	pkt.generator=str_g;
+	pkt.alert=str_a;
+	pkt.ofs=ofs;
+
+	/* Dispatch this record to
+	 * the appropriate handler */
+	if ( e->dispatch && !e->dispatch(&pkt) )
+		return 0;
+
+skip:
+	return ntohl(ph->h.reclen);
+}
+
+/* Run through the packet */
+int elog_run(struct elog *e)
+{
+	size_t ofs=sizeof(struct efile_hdr);
+	size_t ret;
+
+	/* Loop through each packet */
+	for(; ofs < e->maplen; ofs+=ret) {
+		if ( !(ret=elog_pkt(e, ofs)) )
+			return 0;
+	}
+
+	return 1;
+}
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/elog.h ethereal-0.9.9-elog/wiretap/elog.h
--- ethereal-0.9.9/wiretap/elog.h	1970-01-01 01:00:00.000000000 +0100
+++ ethereal-0.9.9-elog/wiretap/elog.h	2003-02-02 19:09:43.000000000 +0000
@@ -0,0 +1,83 @@
+#ifndef __ELOG_HEADER_INCLUDED__
+#define __ELOG_HEADER_INCLUDED__
+
+/* 
+ * An extended logfile is described by a single header at the start
+ * of a file - it contains little more than a magic number.
+ * 
+ * Each alert is a variable length record comprising of:
+ *  o a fixed size header
+ *  o a variable number of variable length records describing
+ *    each layer in the packet such as protocol name, offset 
+ *    within the packet and additional data.
+ *  o optional packet data
+ *  o an optional variable length generator string
+ *  o an optional variable length alert string
+ *  o Any extra padding
+ *
+ * Exact structures are described below.
+ *
+ */
+
+/* please to god change this magic number if you are fiddling
+ * with the format - even in local development trees!! */
+#define EF_MAGIC 0x656c6f67 /* "elog" */
+#define EF_VERS_MAJ 0
+#define EF_VERS_MIN 2
+
+/* Extended log file header (big endian integers) */
+struct efile_hdr {
+	u_int32_t magic;
+	u_int16_t flags;
+	u_int8_t vers_major;
+	u_int8_t vers_minor;
+};
+
+/* common to all types of packet */
+struct elog_common_hdr {
+	u_int32_t reclen;
+	u_int16_t type;
+	u_int8_t prio;
+	u_int8_t reserved; /* must be zero */
+	struct timeval ts;
+};
+
+/* Different record types */
+#define ELOG_ALERT 0
+struct elog_pkthdr {
+	struct elog_common_hdr h;
+
+	/* Specific to alerts */
+	u_int32_t sid,rev;	/* signature id and revision */
+	u_int32_t pflags;	/* packet flags */
+	u_int16_t decode_len;	/* decode data length (multiples of 4) */
+	u_int8_t gen_len;	/* generator length (including null) */
+	u_int8_t alert_len;	/* alert length (including null) */
+	u_int32_t pkt_len;	/* packet length on wire */
+	u_int32_t pkt_caplen;	/* length of present captured packet */
+
+	/* <protocol decode data> */
+	/* pkt_caplen bytes of data */
+	/* null terminated generator string (gen_len) */
+	/* null terminated alert string (alert_len) */
+	/* any extra padding */
+};
+
+/* decode data for each layer */
+struct elog_dhdr {
+	u_int8_t	tot_len;	/* multiples of 4 */
+	u_int8_t	name_len;	/* multiples of 4 */
+	u_int16_t 	pkt_ofs;
+	u_int32_t	flags;
+	/* null terminated protocol name */
+	/* protocol private data */
+};
+
+#define ELOG_MESG 1
+struct elog_mesghdr {
+	struct elog_common_hdr h;
+	/* NULL terminated message */
+	/* padding to 4 bytes */
+};
+
+#endif /* __ELOG_HEADER_INCLUDED__ */
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/elog_read.h ethereal-0.9.9-elog/wiretap/elog_read.h
--- ethereal-0.9.9/wiretap/elog_read.h	1970-01-01 01:00:00.000000000 +0100
+++ ethereal-0.9.9-elog/wiretap/elog_read.h	2003-02-02 19:09:46.000000000 +0000
@@ -0,0 +1,38 @@
+#ifndef __ELOG_READ_HEADER_INCLUDED__
+#define __ELOG_READ_HEADER_INCLUDED__
+
+struct elog_pkt {
+	struct elog *file;
+	struct elog_pkthdr *hdr;
+	char *decode_buf;
+	char *data;
+	char *generator;
+	char *alert;
+	size_t ofs;
+};
+
+typedef int(*proc_elogfn)(struct elog_pkt *);
+
+struct elog {
+	char *map, *end;
+	int fd;
+	size_t maplen;
+	proc_elogfn dispatch;
+};
+
+#ifndef __PLUGIN__
+
+struct elog *elog_new(int);
+void elog_free(struct elog *);
+int elog_run(struct elog *);
+size_t elog_pkt(struct elog *, size_t);
+proc_elogfn elog_set_alert_fn(struct elog *, proc_elogfn);
+
+/* Packetization API (elog_pkt.c) */
+#ifdef __TARGET_HEADER_INCLUDED__
+int elog_pkt_alert(struct elog_pkt *, proc_target, void *);
+#endif
+
+#endif /* __PLUGIN__ */
+
+#endif /* __ELOG_READ_HEADER_INCLUDED__ */
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/file.c ethereal-0.9.9-elog/wiretap/file.c
--- ethereal-0.9.9/wiretap/file.c	2003-03-03 15:41:45.000000000 +0000
+++ ethereal-0.9.9-elog/wiretap/file.c	2003-02-02 20:48:58.000000000 +0000
@@ -68,6 +68,7 @@
 #include "dbs-etherwatch.h"
 #include "visual.h"
 #include "cosine.h"
+#include "fselog.h"
 
 /* The open_file_* routines should return:
  *
@@ -105,6 +106,7 @@
 	radcom_open,
 	nettl_open,
 	visual_open,
+	elog_open,
 
 	/* Files that don't have magic bytes at a fixed location,
 	 * but that instead require a heuristic of some sort to
@@ -447,6 +449,10 @@
 	/* WTAP_FILE_COSINE */
 	{ "CoSine IPSX L2 capture", "cosine",
 	  NULL, NULL },
+
+	/* WTAP_FILE_ELOG */
+	{ "Firestorm alert elog", "fselog",
+	  NULL, NULL },		
 };
 
 /* Name that should be somewhat descriptive. */
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/fselog.c ethereal-0.9.9-elog/wiretap/fselog.c
--- ethereal-0.9.9/wiretap/fselog.c	1970-01-01 01:00:00.000000000 +0100
+++ ethereal-0.9.9-elog/wiretap/fselog.c	2003-02-25 20:58:54.000000000 +0000
@@ -0,0 +1,140 @@
+/* fselog.c
+ *
+ * Firestorm elog file format handler
+ * Copyright (c) 2003 by John Leach <john@xxxxxxxxxxxxxxx>
+ *
+ * Wiretap Library
+ * Copyright (c) 1999 by Bert Driehuis <driehuis@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <netinet/in.h>
+#include "wtap-int.h"
+#include "file_wrappers.h"
+#include "buffer.h"
+#include "elog.h"
+#include "elog_read.h"
+
+/* Global variable to temporarily hold the wth during the
+ * elog callback function */
+struct elog_pkt gepkt;
+
+
+static gboolean elog_seek_read(wtap *wth, long seek_off, 
+		union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err);
+static gboolean elog_read(wtap *wth, int *err, long *data_offset);
+static void elog_close(wtap *wth);
+int elog_alertpacket(struct elog_pkt *p);
+
+int elog_open(wtap *wth, int *err)
+{
+	/* Open file */
+	errno = WTAP_ERR_CANT_READ;
+        wth->capture.generic=elog_new(wth->fd);
+	/* If something went wrong, work it out and return */
+	if (wth->capture.generic==NULL) {
+		*err = file_error(wth->fh);
+		if (*err != 0)
+			return -1;
+		return 0;	
+	}
+	elog_set_alert_fn(wth->capture.generic, elog_alertpacket);
+		
+	wth->data_offset = sizeof(struct efile_hdr);
+
+	/* Setup the wiretap handle */
+	wth->file_type = WTAP_FILE_ELOG;
+	wth->subtype_read = elog_read;
+	wth->subtype_close = elog_close;
+	wth->subtype_seek_read = elog_seek_read;
+	wth->snapshot_length = 0;	/* not known */
+
+	wth->file_encap = WTAP_ENCAP_ELOG;
+
+	return TRUE;
+}
+
+/* Call-back function from the elog.c routines */
+int elog_alertpacket(struct elog_pkt *p) {
+	/* Copy elog packet into our global variable */
+	memcpy(&gepkt,p,sizeof(struct elog_pkt));
+	return 1;
+}
+
+/* Read the next packet */
+static gboolean elog_read(wtap *wth, int *err, long *data_offset)
+{
+	long ret;
+	void *bufp;
+	/* Attempt to read the packet */
+	ret=elog_pkt(wth->capture.generic,wth->data_offset);
+	if (ret==0) return FALSE; /* End of packets or Something went wrong */
+	if (ret>WTAP_MAX_PACKET_SIZE) { /* Returned packet was too big! */
+		*err = WTAP_ERR_BAD_RECORD;
+		return FALSE;
+	}
+
+	/* Copy the elog_pkt into our pseudo header */
+	memcpy(&wth->pseudo_header.elog,&gepkt,sizeof(struct elog_pkt));
+	
+	/* Setup the wth phdr structure */
+	wth->phdr.ts.tv_sec = ntohl(gepkt.hdr->h.ts.tv_sec);
+	wth->phdr.ts.tv_usec = ntohl(gepkt.hdr->h.ts.tv_usec);
+	wth->phdr.len = ntohl(gepkt.hdr->pkt_len);
+	wth->phdr.caplen = ntohl(gepkt.hdr->pkt_caplen);
+	wth->phdr.pkt_encap = WTAP_ENCAP_ELOG;
+
+	/* Allocate and read in packet data */
+	buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
+	bufp = buffer_start_ptr(wth->frame_buffer);		
+	memcpy(bufp,gepkt.data,wth->phdr.caplen);
+
+	/* Set data offset accordingly */
+	*data_offset=wth->data_offset;
+	wth->data_offset += ntohl(gepkt.hdr->h.reclen);	
+
+	return TRUE;
+}
+
+/* Given an offset, read packet data and setup pseudo header */
+static gboolean elog_seek_read(wtap *wth, long seek_off,
+    union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err)
+{
+	long ret;
+	ret=elog_pkt(wth->capture.generic,seek_off);
+	if (ret==0) return FALSE;
+	if (ret>WTAP_MAX_PACKET_SIZE) { /* Too Big! */
+		*err = WTAP_ERR_BAD_RECORD;
+		return FALSE;
+	}
+	memcpy(&pseudo_header->elog,&gepkt,sizeof(struct elog_pkt));
+	memcpy(pd,gepkt.data,wth->phdr.caplen);
+
+	return TRUE;
+}
+
+static void elog_close(wtap *wth)
+{
+	elog_free(wth->capture.generic);
+}
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/fselog.h ethereal-0.9.9-elog/wiretap/fselog.h
--- ethereal-0.9.9/wiretap/fselog.h	1970-01-01 01:00:00.000000000 +0100
+++ ethereal-0.9.9-elog/wiretap/fselog.h	2003-02-02 20:16:55.000000000 +0000
@@ -0,0 +1,28 @@
+/* fselog.h
+ *
+ *
+ * Wiretap Library
+ * Copyright (c) 1999 by Bert Driehuis <driehuis@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef __ELOG_H__
+#define __ELOG_H__
+
+int elog_open(wtap *wth, int *err);
+
+#endif
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/Makefile.am ethereal-0.9.9-elog/wiretap/Makefile.am
--- ethereal-0.9.9/wiretap/Makefile.am	2003-03-03 15:41:45.000000000 +0000
+++ ethereal-0.9.9-elog/wiretap/Makefile.am	2003-02-02 20:31:38.000000000 +0000
@@ -48,11 +48,16 @@
 	csids.h			\
 	dbs-etherwatch.c	\
 	dbs-etherwatch.h	\
+	elog.h			\
+	elog.c			\
+	elog_read.h		\
 	etherpeek.c             \
 	etherpeek.h             \
 	file.c			\
 	file_wrappers.c		\
 	file_wrappers.h		\
+	fselog.c		\
+	fselog.h		\
 	i4btrace.c		\
 	i4btrace.h		\
 	i4b_trace.h		\
diff -ruN -x 'conf*' -x .deps -x '*.backup' -x '*.1' -x '*.exp' -x register.c -x 'stamp*' -x tethereal -x ethereal -x idl2eth -x libtool -x stamp-h1 -x '*.o' -x Makefile -x Makefile.in ethereal-0.9.9/wiretap/wtap.h ethereal-0.9.9-elog/wiretap/wtap.h
--- ethereal-0.9.9/wiretap/wtap.h	2003-03-03 15:41:45.000000000 +0000
+++ ethereal-0.9.9-elog/wiretap/wtap.h	2003-02-16 16:29:49.000000000 +0000
@@ -33,6 +33,9 @@
 
 #include <glib.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include "elog.h"
+#include "elog_read.h"
 
 /* Encapsulation types. Choose names that truly reflect
  * what is contained in the packet trace file.
@@ -125,9 +128,11 @@
 #define WTAP_ENCAP_WFLEET_HDLC			33
 #define WTAP_ENCAP_SDLC				34
 #define WTAP_ENCAP_TZSP				35
+#define WTAP_ENCAP_ELOG				36
+#define WTAP_ENCAP_MMSLL			37
 
 /* last WTAP_ENCAP_ value + 1 */
-#define WTAP_NUM_ENCAP_TYPES			36
+#define WTAP_NUM_ENCAP_TYPES			38
 
 /* File types that can be read by wiretap.
    We support writing some many of these file types, too, so we
@@ -166,9 +171,10 @@
 #define WTAP_FILE_DBS_ETHERWATCH		31
 #define WTAP_FILE_VISUAL_NETWORKS		32
 #define WTAP_FILE_COSINE			33
+#define WTAP_FILE_ELOG				34
 
 /* last WTAP_FILE_ value + 1 */
-#define WTAP_NUM_FILE_TYPES			34
+#define WTAP_NUM_FILE_TYPES			35
 
 /*
  * Maximum packet size we'll support.
@@ -354,6 +360,7 @@
 	struct p2p_phdr		p2p;
 	struct ieee_802_11_phdr	ieee_802_11;
 	struct cosine_phdr	cosine;
+	struct elog_pkt		elog;
 };
 
 struct wtap_pkthdr {

Attachment: signature.asc
Description: This is a digitally signed message part