Ethereal-dev: [Ethereal-dev] Snort unified log patch

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

From: "Mario D. Santana" <mds@xxxxxxxxxxxxxxxx>
Date: Sun, 26 Jun 2005 19:14:52 -0400
Hi, all.  Find attached a first stab at adding Snort unified log
capability to ethereal.  I had to muck with some internals, in
epan/frame_data.h, and file.c.  I also had to add an encapsulation type
in wiretap/wtap.h.  I hope someone finds this useful enough to check it
out and let me know what they think -- this is my first ethereal hack
and I'm sure I did plenty wrong.

My basic approach was to add a "fake" encapsulation type, while
capturing the "real" encapsulation type (eg, ethernet.)  When my
dissector gets called (by packet-frame.c) to handle the "fake"
encapsulation, I do my thing, then reset the encapsulation to the "real"
one, and do what packet-frame.c does to call the dissector for that
encapsulation (eg, packet-eth.c).  The changes to frame_data.c and
file.c are in support of this "real" vs "fake" encapsulation hack.
There's some more encapsulation-foo for handling special pseudo-packets
created by snort to represent port-scans.

As I mentioned in a previous email, I've also hacked up the libpcap
parser in libwiretap so that it understands the unified log format
(which is similar to pcap format.)

A couple of items that need looking at are marked with TODO.mds in code
comments:

/* TODO.mds: turn this into a VALS */
The signal id needs to have a different mapping depending on the
generator id.  I've left it as an integer for now.

/* TODO.mds: register this value at tcpdump-workers */
The encapsulation type needs to be registered.  I haven't done it
because I'd like to get some feedback as to whether this is the right
way to do this.

/* TODO.mds: this needs to be g_free()d at some point? */
I allocate some memory at one point, but I'm not sure where it might be
used.  I decided to risk leaking in preference to risking a sigsegv,
until I can get some feedback on this.

/* TODO.mds: snort's reference time is fubar'd in this case */
Snort "makes up" a series of special packets when it detects a portscan.
 Parsing these packets yields seemingly random reference dates.  I need
to look at the spec more closely in order to handle this case well.
These packets could probably use their own dissector in order to display
the portscan information in the payload more legibly, allow searching
based on this info, etc.

Enjoy,
mds

Index: epan/frame_data.h
===================================================================
--- epan/frame_data.h	(revision 14717)
+++ epan/frame_data.h	(working copy)
@@ -59,6 +59,8 @@
   gint32       del_usecs;   /* Delta microseconds (yes, it can be negative) */
   long         file_off;    /* File offset */
   int          lnk_t;       /* Per-packet encapsulation/data-link type */
+  int          orig_lnk_t;  /* Original encapsulation/data-link type (used by snort dissector) */
+  void         *snort_data; /* Data to be used by snort dissector */
   struct {
 	unsigned int passed_dfilter	: 1; /* 1 = display, 0 = no display */
   	unsigned int encoding		: 2; /* Character encoding (ASCII, EBCDIC...) */
Index: epan/dissectors/packet-snort_unified.c
===================================================================
--- epan/dissectors/packet-snort_unified.c	(revision 0)
+++ epan/dissectors/packet-snort_unified.c	(revision 0)
@@ -0,0 +1,228 @@
+/* packet-snort_unified.c
+ *
+ * Dissector for Snort Unified Log encapsulation type.  Copied from
+ * packet-frame.c, because this dissector's "protocol" is meta in the
+ * same way that the frame dissector's "protocol" is.  The libpcap
+ * file parser (in the wiretap library) marks snort unified log files
+ * with a special encapsulation type, and stores the real
+ * encapsulation (eg, ethernet, atm, etc.)  This dissector adds
+ * snort-specific information to the tree, and then behaves just like
+ * the frame dissector.
+ *
+ * $Id: $
+ *
+ * Copyright 2005 Mario D. Santana <mds@xxxxxxxxxxxxxxxx>
+ *
+ * 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 <sys/time.h>
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/timestamp.h>
+#include <epan/tvbuff.h>
+#include "packet-frame.h"
+#include "packet-snort_unified.h"
+#include <epan/prefs.h>
+#include <epan/tap.h>
+
+void proto_reg_handoff_snort(void);
+
+/* Initialize the protocol and registered fields */
+static int proto_snort = -1;
+
+static int hf_snort_sig_generator = -1;    /* which part of snort generated the alert? */
+static int hf_snort_sig_id = -1;           /* sig id for this generator */
+static int hf_snort_sig_rev = -1;          /* sig revision for this id */
+static int hf_snort_classification = -1;   /* event classification */
+static int hf_snort_priority = -1;         /* event priority */
+static int hf_snort_event_id = -1;         /* event ID */
+static int hf_snort_event_reference = -1;  /* reference to other events that have gone off,
+					    * such as in the case of tagged packets...
+					    */
+static int hf_snort_ref_time = -1;         /* reference time for the event reference */
+
+/* Initialize the subtree pointers */
+static gint ett_snort = -1;
+
+static dissector_handle_t data_handle;
+
+/* structure put into pinfo->fd->snort_data during file-reading time */
+struct pcaprec_snort_unified_hdr {
+	guint32 sig_generator;   /* which part of snort generated the alert? */
+	guint32 sig_id;          /* sig id for this generator */
+	guint32 sig_rev;         /* sig revision for this id */
+	guint32 classification;  /* event classification */
+	guint32 priority;        /* event priority */
+	guint32 event_id;        /* event ID */
+	guint32 event_reference; /* reference to other events that have gone off,
+                                  * such as in the case of tagged packets...
+                                  */
+	guint32	ref_sec;         /* reference time for the event */
+	guint32	ref_usec;	 /* reference */
+	guint32 flags;           /* bitmap for interesting flags */
+	/* struct pcaprec_hdr hdr;  /* the regular header (unused here) */
+	/* guint32	ts_sec;		/* timestamp seconds */
+	/* guint32	ts_usec;	/* timestamp microseconds */
+	/* guint32	incl_len;	/* number of octets of packet saved in file */
+	/* guint32	orig_len;	/* actual length of packet */
+};
+
+static void
+dissect_snort(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
+{
+	proto_tree	  *sh_tree=NULL;
+	proto_item	  *volatile ti = NULL;
+	proto_tree	  *tree;
+	dissector_table_t wtap_encap_dissector_table;
+	struct pcaprec_snort_unified_hdr *snort_data;
+
+	tree=parent_tree;
+
+	pinfo->current_proto = "Snort";
+
+	/* Put in snort header information. */
+	if (tree) {
+	  ti = proto_tree_add_protocol_format(tree, proto_snort, tvb, 0, -1,
+	    "Snort IDS Event");
+
+	  sh_tree = proto_item_add_subtree(ti, ett_snort);
+	}
+
+	/* if we're not referenced from any filters we dont need to worry about
+	   generating any tree items.  We must do this after we created the actual
+	   protocol above so that proto hier stat still works though.
+	*/
+	if(!proto_field_is_referenced(tree, proto_snort)){
+		tree=NULL;
+		sh_tree = NULL;
+	}
+
+       
+	if (sh_tree) {
+		snort_data = pinfo->fd->snort_data;
+		nstime_t ref_time;
+		ref_time.secs = snort_data->ref_sec;
+		ref_time.nsecs = snort_data->ref_usec;
+		/*
+		proto_tree_add_uint(sh_tree, hf_snort_sig_generator, tvb,0,0, 1);
+		proto_tree_add_uint(sh_tree, hf_snort_sig_id, tvb,0,0, 2);
+		proto_tree_add_uint(sh_tree, hf_snort_sig_rev, tvb,0,0, 3);
+		proto_tree_add_uint(sh_tree, hf_snort_classification, tvb,0,0, 4);
+		proto_tree_add_uint(sh_tree, hf_snort_priority, tvb,0,0, 5);
+		proto_tree_add_uint(sh_tree, hf_snort_event_id, tvb,0,0, 6);
+		proto_tree_add_uint(sh_tree, hf_snort_event_reference, tvb,0,0, 7);
+		proto_tree_add_time(sh_tree, hf_snort_ref_time, tvb,0,0, ref_time);
+		*/
+		proto_tree_add_uint(sh_tree, hf_snort_sig_generator, tvb,0,0, snort_data->sig_generator);
+		proto_tree_add_uint(sh_tree, hf_snort_sig_id, tvb,0,0, snort_data->sig_id);
+		proto_tree_add_uint(sh_tree, hf_snort_sig_rev, tvb,0,0, snort_data->sig_rev);
+		proto_tree_add_uint(sh_tree, hf_snort_classification, tvb,0,0, snort_data->classification);
+		proto_tree_add_uint(sh_tree, hf_snort_priority, tvb,0,0, snort_data->priority);
+		proto_tree_add_uint(sh_tree, hf_snort_event_id, tvb,0,0, snort_data->event_id);
+		proto_tree_add_uint(sh_tree, hf_snort_event_reference, tvb,0,0, snort_data->event_reference);
+		proto_tree_add_time(sh_tree, hf_snort_ref_time, tvb,0,0, &ref_time);
+	}
+
+	/* set "real" encapsulation type */
+	pinfo->fd->lnk_t = pinfo->fd->orig_lnk_t;
+
+	/* the following is what packet-frame.c does for each packet... */
+	wtap_encap_dissector_table = find_dissector_table("wtap_encap");
+	TRY {
+		if (!dissector_try_port(wtap_encap_dissector_table, pinfo->fd->lnk_t,
+					tvb, pinfo, parent_tree)) {
+	  
+			if (check_col(pinfo->cinfo, COL_PROTOCOL))
+				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
+			if (check_col(pinfo->cinfo, COL_INFO))
+				col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %u",
+					     pinfo->fd->lnk_t);
+			call_dissector(data_handle,tvb, pinfo, parent_tree);
+		}
+	}
+	CATCH_ALL {
+		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
+	}
+	ENDTRY;
+
+	/* restore snort encap type */
+	pinfo->fd->lnk_t = WTAP_ENCAP_SNORT_UNIFIED;
+}
+
+void
+proto_register_snort(void)
+{
+	module_t *snort_module;
+
+	static hf_register_info hf[] = {
+		{ &hf_snort_sig_generator, {
+			"Generator", "snort.sig_generator", FT_UINT32, BASE_DEC,
+			VALS(snort_unified_generators), 0x0,
+			"Which part of snort generated the alert?", HFILL }},
+		{ &hf_snort_sig_id, { /* TODO.mds: turn this into a VALS */
+			"Signal ID", "snort.sig_id", FT_UINT32, BASE_DEC,
+			NULL, 0x0,
+			"Signal ID for this generator.", HFILL }},
+		{ &hf_snort_sig_rev, {
+			"Revision", "snort.sig_rev", FT_UINT32, BASE_DEC, NULL,
+			0x0,
+			"Signal revision for this ID", HFILL }},
+		{ &hf_snort_classification, {
+			"Classification", "snort.classification", FT_UINT32, BASE_DEC, NULL,
+			0x0,
+			"Event classification", HFILL }},
+		{ &hf_snort_priority, {
+			"Priority", "snort.priority", FT_UINT32, BASE_DEC, NULL,
+			0x0,
+			"Event priority", HFILL }},
+		{ &hf_snort_event_id, {
+			"Event ID", "snort.event_id", FT_UINT32, BASE_DEC, NULL,
+			0x0,
+			"Event ID", HFILL }},
+		{ &hf_snort_event_reference, {
+			"Event Reference", "snort.event_ref", FT_UINT32, BASE_DEC, NULL,
+			0x0,
+			"Reference to other events that have gone off", HFILL }},
+		{ &hf_snort_ref_time, {
+			"Reference time", "snort.ref_secs", FT_ABSOLUTE_TIME, BASE_DEC, NULL,
+			0x0,
+			"Reference time for the event reference", HFILL }},
+	};
+
+	static gint *ett[] = {
+		&ett_snort,
+	};
+
+
+	proto_snort = proto_register_protocol("Snort", "Snort", "snort");
+	proto_register_field_array(proto_snort, hf, array_length(hf));
+	proto_register_subtree_array(ett, array_length(ett));
+        snort_module = prefs_register_protocol(proto_snort, proto_reg_handoff_snort);
+
+	register_dissector("snort",dissect_snort,proto_snort);
+}
+
+void
+proto_reg_handoff_snort(void)
+{
+	dissector_handle_t snort_handle;
+	snort_handle = create_dissector_handle(dissect_snort, proto_snort);
+	dissector_add("wtap_encap", WTAP_ENCAP_SNORT_UNIFIED, snort_handle);
+}
Index: epan/dissectors/packet-snort_unified.h
===================================================================
--- epan/dissectors/packet-snort_unified.h	(revision 0)
+++ epan/dissectors/packet-snort_unified.h	(revision 0)
@@ -0,0 +1,577 @@
+/* $Id: $
+**
+** Copyright (C) 2005 Mario D. Santana <mds@xxxxxxxxxxxxxxxx>
+**
+** Portions copied from snort's generators.h,
+** Copyright (C) 1998-2002 Martin Roesch <roesch@xxxxxxxxxxxxxx>
+**
+** 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.
+*/
+
+
+#define GENERATOR_SNORT_ENGINE        1
+
+#define GENERATOR_TAG                 2
+#define    TAG_LOG_PKT                1
+
+#define GENERATOR_SPP_PORTSCAN      100
+#define     PORTSCAN_SCAN_DETECT        1
+#define     PORTSCAN_INTER_INFO         2
+#define     PORTSCAN_SCAN_END           3
+
+#define GENERATOR_SPP_MINFRAG       101
+#define     MINFRAG_ALERT_ID            1
+
+#define GENERATOR_SPP_HTTP_DECODE   102
+#define     HTTP_DECODE_UNICODE_ATTACK  1
+#define     HTTP_DECODE_CGINULL_ATTACK  2
+#define     HTTP_DECODE_LARGE_METHOD    3
+#define     HTTP_DECODE_MISSING_URI     4
+#define     HTTP_DECODE_DOUBLE_ENC      5
+#define     HTTP_DECODE_ILLEGAL_HEX     6
+#define     HTTP_DECODE_OVERLONG_CHAR   7
+
+
+#define GENERATOR_SPP_DEFRAG        103
+#define     DEFRAG_FRAG_OVERFLOW        1
+#define     DEFRAG_FRAGS_DISCARDED      2
+
+#define GENERATOR_SPP_SPADE         104
+#define     SPADE_ANOM_THRESHOLD_EXCEEDED   1
+#define     SPADE_ANOM_THRESHOLD_ADJUSTED   2
+
+#define GENERATOR_SPP_BO            105
+#define     BO_TRAFFIC_DETECT           1
+
+#define GENERATOR_SPP_RPC_DECODE    106
+#define     RPC_FRAG_TRAFFIC                1
+#define     RPC_MULTIPLE_RECORD             2
+#define     RPC_LARGE_FRAGSIZE              3
+#define     RPC_INCOMPLETE_SEGMENT          4
+
+#define GENERATOR_SPP_STREAM2       107
+#define GENERATOR_SPP_STREAM3       108
+#define GENERATOR_SPP_TELNET_NEG    109
+
+#define GENERATOR_SPP_UNIDECODE     110
+#define     UNIDECODE_CGINULL_ATTACK        1
+#define     UNIDECODE_DIRECTORY_TRAVERSAL   2
+#define     UNIDECODE_UNKNOWN_MAPPING       3
+#define     UNIDECODE_INVALID_MAPPING       4
+
+#define GENERATOR_SPP_STREAM4       111
+#define     STREAM4_STEALTH_ACTIVITY            1
+#define     STREAM4_EVASIVE_RST                 2
+#define     STREAM4_EVASIVE_RETRANS             3
+#define     STREAM4_WINDOW_VIOLATION            4
+#define     STREAM4_DATA_ON_SYN                 5
+#define     STREAM4_STEALTH_FULL_XMAS           6
+#define     STREAM4_STEALTH_SAPU                7
+#define     STREAM4_STEALTH_FIN_SCAN            8
+#define     STREAM4_STEALTH_NULL_SCAN           9
+#define     STREAM4_STEALTH_NMAP_XMAS_SCAN      10
+#define     STREAM4_STEALTH_VECNA_SCAN          11
+#define     STREAM4_STEALTH_NMAP_FINGERPRINT    12
+#define     STREAM4_STEALTH_SYN_FIN_SCAN        13
+#define     STREAM4_FORWARD_OVERLAP             14
+#define     STREAM4_TTL_EVASION                 15
+#define     STREAM4_EVASIVE_RETRANS_DATA        16
+#define     STREAM4_EVASIVE_RETRANS_DATASPLIT   17
+#define     STREAM4_MULTIPLE_ACKED              18
+#define     STREAM4_EMERGENCY                   19
+#define     STREAM4_SUSPEND                     20
+
+#define GENERATOR_SPP_ARPSPOOF      112
+#define     ARPSPOOF_UNICAST_ARP_REQUEST         1
+#define     ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC  2
+#define     ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST  3
+#define     ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK   4
+
+#define GENERATOR_SPP_FRAG2         113
+#define     FRAG2_OVERSIZE_FRAG                   1
+#define     FRAG2_TEARDROP                        2
+#define     FRAG2_TTL_EVASION                     3
+#define     FRAG2_OVERLAP                         4
+#define     FRAG2_DUPFIRST                        5
+#define     FRAG2_MEM_EXCEED                      6
+#define     FRAG2_OUTOFORDER                      7
+#define     FRAG2_IPOPTIONS                       8
+#define     FRAG2_EMERGENCY                       9
+#define     FRAG2_SUSPEND                         10
+
+#define GENERATOR_SPP_FNORD         114
+#define     FNORD_NOPSLED                         1
+
+#define GENERATOR_SPP_ASN1          115
+#define     ASN1_INDEFINITE_LENGTH                1
+#define     ASN1_INVALID_LENGTH                   2
+#define     ASN1_OVERSIZED_ITEM                   3
+#define     ASN1_SPEC_VIOLATION                   4
+#define     ASN1_DATUM_BAD_LENGTH                 5
+
+
+#define GENERATOR_SNORT_DECODE      116
+#define     DECODE_NOT_IPV4_DGRAM                 1
+#define     DECODE_IPV4_INVALID_HEADER_LEN        2
+#define     DECODE_IPV4_DGRAM_LT_IPHDR            3
+#define     DECODE_IPV4OPT_BADLEN                 4
+#define     DECODE_IPV4OPT_TRUNCATED              5
+
+#define     DECODE_TCP_DGRAM_LT_TCPHDR            45
+#define     DECODE_TCP_INVALID_OFFSET             46
+#define     DECODE_TCP_LARGE_OFFSET               47
+
+#define     DECODE_TCPOPT_BADLEN                  54
+#define     DECODE_TCPOPT_TRUNCATED               55
+#define     DECODE_TCPOPT_TTCP                    56
+#define     DECODE_TCPOPT_OBSOLETE                57
+#define     DECODE_TCPOPT_EXPERIMENT              58
+
+#define     DECODE_UDP_DGRAM_LT_UDPHDR            95
+#define     DECODE_UDP_DGRAM_INVALID_LENGTH       96
+#define     DECODE_UDP_DGRAM_SHORT_PACKET         97
+
+#define     DECODE_ICMP_DGRAM_LT_ICMPHDR          105
+#define     DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR     106
+#define     DECODE_ICMP_DGRAM_LT_ADDRHDR          107
+#define     DECODE_IPV4_DGRAM_UNKNOWN             108
+
+#define     DECODE_ARP_TRUNCATED                  109
+#define     DECODE_EAPOL_TRUNCATED                110
+#define     DECODE_EAPKEY_TRUNCATED               111
+#define     DECODE_EAP_TRUNCATED                  112
+
+#define     DECODE_BAD_PPPOE                      120
+#define     DECODE_BAD_VLAN                       130
+#define     DECODE_BAD_VLAN_ETHLLC                131
+#define     DECODE_BAD_VLAN_OTHER                 132
+#define     DECODE_BAD_80211_ETHLLC               133 
+#define     DECODE_BAD_80211_OTHER                134
+
+#define     DECODE_BAD_TRH                        140
+#define     DECODE_BAD_TR_ETHLLC                  141
+#define     DECODE_BAD_TR_MR_LEN                  142
+#define     DECODE_BAD_TRHMR                      143
+
+#define GENERATOR_SPP_SCAN2         117
+#define     SCAN_TYPE                             1
+
+#define GENERATOR_SPP_CONV         118
+#define     CONV_BAD_IP_PROTOCOL                            1
+
+/*
+**  HttpInspect Generator IDs
+**
+**  IMPORTANT::
+**    Whenever events are added to the internal HttpInspect
+**    event queue, you must also add the event here.  The
+**    trick is that whatever the number is in HttpInspect,
+**    it must be +1 when you define it here.
+*/
+#define GENERATOR_SPP_HTTP_INSPECT_CLIENT           119
+#define     HI_CLIENT_ASCII                         1   /* done */
+#define     HI_CLIENT_DOUBLE_DECODE                 2   /* done */
+#define     HI_CLIENT_U_ENCODE                      3   /* done */
+#define     HI_CLIENT_BARE_BYTE                     4   /* done */
+#define     HI_CLIENT_BASE36                        5   /* done */
+#define     HI_CLIENT_UTF_8                         6   /* done */
+#define     HI_CLIENT_IIS_UNICODE                   7   /* done */
+#define     HI_CLIENT_MULTI_SLASH                   8   /* done */
+#define     HI_CLIENT_IIS_BACKSLASH                 9   /* done */
+#define     HI_CLIENT_SELF_DIR_TRAV                 10  /* done */
+#define     HI_CLIENT_DIR_TRAV                      11  /* done */
+#define     HI_CLIENT_APACHE_WS                     12  /* done */
+#define     HI_CLIENT_IIS_DELIMITER                 13  /* done */
+#define     HI_CLIENT_NON_RFC_CHAR                  14  /* done */
+#define     HI_CLIENT_OVERSIZE_DIR                  15  /* done */
+#define     HI_CLIENT_LARGE_CHUNK                   16  /* done */
+#define     HI_CLIENT_PROXY_USE                     17  /* done */
+#define     HI_CLIENT_WEBROOT_DIR                   18  /* done */
+
+#define GENERATOR_SPP_HTTP_INSPECT_ANOM_SERVER      120
+#define     HI_ANOM_SERVER_ALERT                    1   /* done */
+
+#define GENERATOR_FLOW_PORTSCAN                     121
+#define     FLOW_SCANNER_FIXED_ALERT                 1
+#define     FLOW_SCANNER_SLIDING_ALERT               2
+#define     FLOW_TALKER_FIXED_ALERT                  3
+#define     FLOW_TALKER_SLIDING_ALERT                4
+
+#define GENERATOR_PSNG                             122
+#define     PSNG_TCP_PORTSCAN                      1
+#define     PSNG_TCP_DECOY_PORTSCAN                2
+#define     PSNG_TCP_PORTSWEEP                     3
+#define     PSNG_TCP_DISTRIBUTED_PORTSCAN          4
+#define     PSNG_TCP_FILTERED_PORTSCAN             5
+#define     PSNG_TCP_FILTERED_DECOY_PORTSCAN       6
+#define     PSNG_TCP_PORTSWEEP_FILTERED            7
+#define     PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN 8
+
+#define     PSNG_IP_PORTSCAN                       9
+#define     PSNG_IP_DECOY_PORTSCAN                 10
+#define     PSNG_IP_PORTSWEEP                      11
+#define     PSNG_IP_DISTRIBUTED_PORTSCAN           12
+#define     PSNG_IP_FILTERED_PORTSCAN              13
+#define     PSNG_IP_FILTERED_DECOY_PORTSCAN        14
+#define     PSNG_IP_PORTSWEEP_FILTERED             15
+#define     PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN  16
+
+#define     PSNG_UDP_PORTSCAN                      17
+#define     PSNG_UDP_DECOY_PORTSCAN                18
+#define     PSNG_UDP_PORTSWEEP                     19
+#define     PSNG_UDP_DISTRIBUTED_PORTSCAN          20
+#define     PSNG_UDP_FILTERED_PORTSCAN             21
+#define     PSNG_UDP_FILTERED_DECOY_PORTSCAN       22
+#define     PSNG_UDP_PORTSWEEP_FILTERED            23
+#define     PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN 24
+
+#define     PSNG_ICMP_PORTSWEEP                    25
+#define     PSNG_ICMP_PORTSWEEP_FILTERED           26
+
+#define     PSNG_OPEN_PORT                         27
+
+/*  This is where all the alert messages will be archived for each
+    internal alerts */
+
+#define ARPSPOOF_UNICAST_ARP_REQUEST_STR "(spp_arpspoof) Unicast ARP request"
+#define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC_STR \
+"(spp_arpspoof) Ethernet/ARP Mismatch request for Source"
+#define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST_STR \
+"(spp_arpspoof) Ethernet/ARP Mismatch request for Destination"
+#define ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK_STR \
+"(spp_arpspoof) Attempted ARP cache overwrite attack"
+
+#define ASN1_INDEFINITE_LENGTH_STR "(spp_asn1) Indefinite ASN.1 length encoding"
+#define ASN1_INVALID_LENGTH_STR "(spp_asn1) Invalid ASN.1 length encoding"
+#define ASN1_OVERSIZED_ITEM_STR "(spp_asn1) ASN.1 oversized item, possible overflow"
+#define ASN1_SPEC_VIOLATION_STR  "(spp_asn1) ASN.1 spec violation, possible overflow"
+#define ASN1_DATUM_BAD_LENGTH_STR "(spp_asn1) ASN.1 Attack: Datum length > packet length"
+
+#define BO_TRAFFIC_DETECT_STR "(spo_bo) Back Orifice Traffic detected"
+
+#define FNORD_NOPSLED_IA32_STR "(spp_fnord) Possible Mutated IA32 NOP Sled detected"
+#define FNORD_NOPSLED_HPPA_STR "(spp_fnord) Possible Mutated HPPA NOP Sled detected"
+#define FNORD_NOPSLED_SPARC_STR "(spp_fnord) Possible Mutated SPARC NOP Sled detected"
+
+#define FRAG2_DUPFIRST_STR "(spp_frag2) Duplicate first fragments"
+#define FRAG2_IPOPTIONS_STR "(spp_frag2) IP Options on Fragmented Packet"
+#define FRAG2_OUTOFORDER_STR "(spp_frag2) Out of order fragments" 
+#define FRAG2_OVERLAP_STR "(spp_frag2) Overlapping new fragment (probable fragroute)"
+#define FRAG2_OVERSIZE_FRAG_STR "(spp_frag2) Oversized fragment, probable DoS"
+#define FRAG2_TEARDROP_STR "(spp_frag2) Teardrop attack"
+#define FRAG2_TTL_EVASION_STR "(spp_frag2) TTL Limit Exceeded (reassemble) detection"
+#define FRAG2_EMERGENCY_STR "(spp_frag2) Shifting to Emergency Session Mode"
+#define FRAG2_SUSPEND_STR "(spp_frag2) Shifting to Suspend Mode"
+
+
+
+#define HTTP_DECODE_LARGE_METHOD_STR "(spp_http_decode) A large HTTP method was received"
+#define HTTP_DECODE_MISSING_URI_STR "(spp_http_decode) HTTP request without URI"
+#define HTTP_DECODE_DOUBLE_ENC_STR  "(spp_http_decode) Double Hex Encoding Received"
+#define HTTP_DECODE_ILLEGAL_HEX_STR "(spp_http_decode) Illegal URL hex encoding"
+#define HTTP_DECODE_OVERLONG_CHAR_STR "(spp_http_decode) Overlong Unicode character received"
+
+#define STREAM4_MULTIPLE_ACKED_STR "(spp_stream4) Multiple Acked Packets (possible fragroute)"
+#define STREAM4_DATA_ON_SYN_STR  "(spp_stream4) DATA ON SYN detection"
+#define STREAM4_STEALTH_NMAP_FINGERPRINT_STR "(spp_stream4) NMAP FINGERPRINT (stateful) detection"
+#define STREAM4_STEALTH_FULL_XMAS_STR "(spp_stream4) STEALTH ACTIVITY (Full XMAS scan) detection"
+#define STREAM4_STEALTH_SAPU_STR "(spp_stream4) STEALTH ACTIVITY (SAPU scan) detection"
+#define STREAM4_STEALTH_FIN_SCAN_STR "(spp_stream4) STEALTH ACTIVITY (FIN scan) detection"
+#define STREAM4_STEALTH_SYN_FIN_SCAN_STR "(spp_stream4) STEALTH ACTIVITY (SYN FIN scan) detection"
+#define STREAM4_STEALTH_NULL_SCAN_STR "(spp_stream4) STEALTH ACTIVITY (NULL scan) detection"
+#define STREAM4_STEALTH_NMAP_XMAS_SCAN_STR "(spp_stream4) STEALTH ACTIVITY (XMAS scan) detection"
+#define STREAM4_STEALTH_VECNA_SCAN_STR "(spp_stream4) STEALTH ACTIVITY (Vecna scan) detection"
+#define STREAM4_STEALTH_ACTIVITY_STR "(spp_stream4) STEALTH ACTIVITY (unknown) detection"
+#define STREAM4_EVASIVE_RST_STR "(spp_stream4) possible EVASIVE RST detection"
+#define STREAM4_TTL_EVASION_STR "(spp_stream4) TTL LIMIT Exceeded"
+#define STREAM4_EVASIVE_RETRANS_STR "(spp_stream4) Possible RETRANSMISSION detection"
+#define STREAM4_WINDOW_VIOLATION_STR "(spp_stream4) WINDOW VIOLATION detection"
+#define STREAM4_EVASIVE_RETRANS_DATA_STR \
+ "(spp_stream4) TCP CHECKSUM CHANGED ON RETRANSMISSION (possible fragroute) detection"
+#define STREAM4_FORWARD_OVERLAP_STR "(spp_stream4) FORWARD OVERLAP detection"
+#define STREAM4_EVASIVE_RETRANS_DATASPLIT_STR \
+"(spp_stream4) TCP TOO FAST RETRANSMISSION WITH DIFFERENT DATA SIZE (possible fragroute) detection"
+#define STREAM4_EMERGENCY_STR "(spp_stream4) Shifting to Emergency Session Mode"
+#define STREAM4_SUSPEND_STR "(spp_stream4) Shifting to Suspend Mode"
+
+
+#define DECODE_NOT_IPV4_DGRAM_STR "(snort_decoder) WARNING: Not IPv4 datagram!"
+#define DECODE_IPV4_INVALID_HEADER_LEN_STR "(snort_decoder) WARNING: hlen < IP_HEADER_LEN!"
+#define DECODE_IPV4_DGRAM_LT_IPHDR_STR "(snort_decoder) WARNING: IP dgm len < IP Hdr len!"
+#define DECODE_IPV4OPT_BADLEN_STR      "(snort_decoder): Ipv4 Options found with bad lengths"
+#define DECODE_IPV4OPT_TRUNCATED_STR   "(snort_decoder): Truncated Ipv4 Options"
+
+#define DECODE_TCP_DGRAM_LT_TCPHDR_STR "(snort_decoder) TCP packet len is smaller than 20 bytes!"
+#define DECODE_TCP_INVALID_OFFSET_STR "(snort_decoder) WARNING: TCP Data Offset is less than 5!"
+#define DECODE_TCP_LARGE_OFFSET_STR "(snort_decoder) WARNING: TCP Header length exceeds packet length!"
+
+#define DECODE_TCPOPT_BADLEN_STR      "(snort_decoder): Tcp Options found with bad lengths"
+#define DECODE_TCPOPT_TRUNCATED_STR   "(snort_decoder): Truncated Tcp Options"
+#define DECODE_TCPOPT_TTCP_STR        "(snort_decoder): T/TCP Detected"
+#define DECODE_TCPOPT_OBSOLETE_STR    "(snort_decoder): Obsolete TCP Options found"
+#define DECODE_TCPOPT_EXPERIMENT_STR  "(snort_decoder): Experimental Tcp Options found"
+
+
+
+#define DECODE_UDP_DGRAM_LT_UDPHDR_STR "(snort_decoder) WARNING: Truncated UDP Header!"
+#define DECODE_UDP_DGRAM_INVALID_LENGTH_STR "(snort_decoder): Invalid UDP header, length field < 8"
+#define DECODE_UDP_DGRAM_SHORT_PACKET_STR "(snort_decoder): Short UDP packet, length field > payload length"
+
+#define DECODE_ICMP_DGRAM_LT_ICMPHDR_STR "(snort_decoder) WARNING: ICMP Header Truncated!"
+#define DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR_STR "(snort_decoder) WARNING: ICMP Timestamp Header Truncated!"
+#define DECODE_ICMP_DGRAM_LT_ADDRHDR_STR "(snort_decoder) WARNING: ICMP Address Header Truncated!"
+#define DECODE_IPV4_DGRAM_UNKNOWN_STR "(snort_decoder) Unknown Datagram decoding problem!"
+#define DECODE_ARP_TRUNCATED_STR "(snort_decoder) WARNING: Truncated ARP!"
+#define DECODE_EAPOL_TRUNCATED_STR "(snort_decoder) WARNING: Truncated EAP Header!"
+#define DECODE_EAPKEY_TRUNCATED_STR "(snort_decoder) WARNING: EAP Key Truncated!"
+#define DECODE_EAP_TRUNCATED_STR "(snort_decoder) WARNING: EAP Header Truncated!"
+#define DECODE_BAD_PPPOE_STR "(snort_decoder) WARNING: Bad PPPOE frame detected!"
+#define DECODE_BAD_VLAN_STR "(snort_decoder) WARNING: Bad VLAN Frame!"
+#define DECODE_BAD_VLAN_ETHLLC_STR "(snort_decoder) WARNING: Bad LLC header!"
+#define DECODE_BAD_VLAN_OTHER_STR "(snort_decoder) WARNING: Bad Extra LLC Info!"
+#define DECODE_BAD_80211_ETHLLC_STR "(snort_decoder) WARNING: Bad 802.11 LLC header!"
+#define DECODE_BAD_80211_OTHER_STR "(snort_decoder) WARNING: Bad 802.11 Extra LLC Info!"
+
+#define DECODE_BAD_TRH_STR "(snort_decoder) WARNING: Bad Token Ring Header!"
+#define DECODE_BAD_TR_ETHLLC_STR "(snort_decoder) WARNING: Bad Token Ring ETHLLC Header!"
+#define DECODE_BAD_TR_MR_LEN_STR "(snort_decoder) WARNING: Bad Token Ring MRLENHeader!"
+#define DECODE_BAD_TRHMR_STR "(snort_decoder) WARNING: Bad Token Ring MR Header!"
+
+
+#define SCAN2_PREFIX_STR "(spp_portscan2) Portscan detected from "
+
+#define CONV_BAD_IP_PROTOCOL_STR "(spp_conversation) Bad IP protocol!"
+
+#define RPC_FRAG_TRAFFIC_STR "(spp_rpc_decode) Fragmented RPC Records"
+#define RPC_MULTIPLE_RECORD_STR "(spp_rpc_decode) Multiple RPC Records"
+#define RPC_LARGE_FRAGSIZE_STR  "(spp_rpc_decode) Large RPC Record Fragment"
+#define RPC_INCOMPLETE_SEGMENT_STR "(spp_rpc_decode) Incomplete RPC segment"
+
+#define PSNG_TCP_PORTSCAN_STR "(portscan) TCP Portscan"
+#define PSNG_TCP_DECOY_PORTSCAN_STR "(portscan) TCP Decoy Portscan"
+#define PSNG_TCP_PORTSWEEP_STR "(portscan) TCP Portsweep"
+#define PSNG_TCP_DISTRIBUTED_PORTSCAN_STR "(portscan) TCP Distributed Portscan"
+#define PSNG_TCP_FILTERED_PORTSCAN_STR "(portscan) TCP Filtered Portscan"
+#define PSNG_TCP_FILTERED_DECOY_PORTSCAN_STR "(portscan) TCP Filtered Decoy Portscan"
+#define PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN_STR "(portscan) TCP Filtered Distributed Portscan"
+#define PSNG_TCP_PORTSWEEP_FILTERED_STR "(portscan) TCP Filtered Portsweep"
+
+#define PSNG_IP_PORTSCAN_STR "(portscan) IP Protocol Scan"
+#define PSNG_IP_DECOY_PORTSCAN_STR "(portscan) IP Decoy Protocol Scan"
+#define PSNG_IP_PORTSWEEP_STR "(portscan) IP Protocol Sweep"
+#define PSNG_IP_DISTRIBUTED_PORTSCAN_STR "(portscan) IP Distributed Protocol Scan"
+#define PSNG_IP_FILTERED_PORTSCAN_STR "(portscan) IP Filtered Protocol Scan"
+#define PSNG_IP_FILTERED_DECOY_PORTSCAN_STR "(portscan) IP Filtered Decoy Protocol Scan"
+#define PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN_STR "(portscan) IP Filtered Distributed Protocol Scan"
+#define PSNG_IP_PORTSWEEP_FILTERED_STR "(portscan) IP Filtered Protocol Sweep"
+
+#define PSNG_UDP_PORTSCAN_STR "(portscan) UDP Portscan"
+#define PSNG_UDP_DECOY_PORTSCAN_STR "(portscan) UDP Decoy Portscan"
+#define PSNG_UDP_PORTSWEEP_STR "(portscan) UDP Portsweep"
+#define PSNG_UDP_DISTRIBUTED_PORTSCAN_STR "(portscan) UDP Distributed Portscan"
+#define PSNG_UDP_FILTERED_PORTSCAN_STR "(portscan) UDP Filtered Portscan"
+#define PSNG_UDP_FILTERED_DECOY_PORTSCAN_STR "(portscan) UDP Filtered Decoy Portscan"
+#define PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN_STR "(portscan) UDP Filtered Distributed Portscan"
+#define PSNG_UDP_PORTSWEEP_FILTERED_STR "(portscan) UDP Filtered Portsweep"
+
+#define PSNG_ICMP_PORTSWEEP_STR "(portscan) ICMP Sweep"
+#define PSNG_ICMP_PORTSWEEP_FILTERED_STR "(portscan) ICMP Filtered Sweep"
+
+#define PSNG_OPEN_PORT_STR "(portscan) Open Port"
+
+/***** end generators.h *****/
+static const value_string snort_unified_generators[] = {
+	{ GENERATOR_SNORT_ENGINE, "snort engine" },
+	{ GENERATOR_TAG, "tag" },
+	{ GENERATOR_SPP_PORTSCAN, "spp portscan" },
+	{ GENERATOR_SPP_MINFRAG, "spp minfrag" },
+	{ GENERATOR_SPP_HTTP_DECODE, "spp http decode" },
+	{ GENERATOR_SPP_DEFRAG, "spp defrag" },
+	{ GENERATOR_SPP_SPADE, "spp spade" },
+	{ GENERATOR_SPP_BO, "spp bo" },
+	{ GENERATOR_SPP_RPC_DECODE, "spp rpc decode" },
+	{ GENERATOR_SPP_STREAM2, "spp stream2" },
+	{ GENERATOR_SPP_STREAM3, "spp stream3" },
+	{ GENERATOR_SPP_TELNET_NEG, "spp telnet neg" },
+	{ GENERATOR_SPP_UNIDECODE, "spp unidecode" },
+	{ GENERATOR_SPP_STREAM4, "spp stream4" },
+	{ GENERATOR_SPP_ARPSPOOF, "spp arpspoof" },
+	{ GENERATOR_SPP_FRAG2, "spp frag2" },
+	{ GENERATOR_SPP_FNORD, "spp fnord" },
+	{ GENERATOR_SPP_ASN1, "spp asn1" },
+	{ GENERATOR_SNORT_DECODE, "snort decode" },
+	{ GENERATOR_SPP_SCAN2, "spp scan2" },
+	{ GENERATOR_SPP_CONV, "spp conv" },
+	{ GENERATOR_SPP_HTTP_INSPECT_CLIENT, "spp http inspect client" },
+	{ GENERATOR_SPP_HTTP_INSPECT_ANOM_SERVER, "spp http inspect anom server" },
+	{ GENERATOR_FLOW_PORTSCAN, "flow portscan" },
+	{ GENERATOR_PSNG, "psng" },
+	{ 0, NULL },
+};
+
+static const value_string snort_unified_signals[] = {
+	{ TAG_LOG_PKT, "tag log pkt" },
+	{ PORTSCAN_SCAN_DETECT, "portscan scan detect" },
+	{ PORTSCAN_INTER_INFO, "portscan inter info" },
+	{ PORTSCAN_SCAN_END, "portscan scan end" },
+	{ MINFRAG_ALERT_ID, "minfrag alert id" },
+	{ HTTP_DECODE_UNICODE_ATTACK, "http decode unicode attack" },
+	{ HTTP_DECODE_CGINULL_ATTACK, "http decode cginull attack" },
+	{ HTTP_DECODE_LARGE_METHOD, HTTP_DECODE_LARGE_METHOD_STR },
+	{ HTTP_DECODE_MISSING_URI, HTTP_DECODE_MISSING_URI_STR },
+	{ HTTP_DECODE_DOUBLE_ENC, HTTP_DECODE_DOUBLE_ENC_STR },
+	{ HTTP_DECODE_ILLEGAL_HEX, HTTP_DECODE_ILLEGAL_HEX_STR },
+	{ HTTP_DECODE_OVERLONG_CHAR, HTTP_DECODE_OVERLONG_CHAR_STR },
+	{ DEFRAG_FRAG_OVERFLOW, "defrag frag overflow" },
+	{ DEFRAG_FRAGS_DISCARDED, "defrag frags discarded" },
+	{ SPADE_ANOM_THRESHOLD_EXCEEDED, "spade anom threshold exceeded" },
+	{ SPADE_ANOM_THRESHOLD_ADJUSTED, "spade anom threshold adjusted" },
+	{ BO_TRAFFIC_DETECT, BO_TRAFFIC_DETECT_STR },
+	{ RPC_FRAG_TRAFFIC, RPC_FRAG_TRAFFIC_STR },
+	{ RPC_MULTIPLE_RECORD, RPC_MULTIPLE_RECORD_STR },
+	{ RPC_LARGE_FRAGSIZE, RPC_LARGE_FRAGSIZE_STR },
+	{ RPC_INCOMPLETE_SEGMENT, RPC_INCOMPLETE_SEGMENT_STR },
+	{ UNIDECODE_CGINULL_ATTACK, "unidecode cginull attack" },
+	{ UNIDECODE_DIRECTORY_TRAVERSAL, "unidecode directory traversal" },
+	{ UNIDECODE_UNKNOWN_MAPPING, "unidecode unknown mapping" },
+	{ UNIDECODE_INVALID_MAPPING, "unidecode invalid mapping" },
+	{ STREAM4_STEALTH_ACTIVITY, STREAM4_STEALTH_ACTIVITY_STR },
+	{ STREAM4_EVASIVE_RST, STREAM4_EVASIVE_RST_STR },
+	{ STREAM4_EVASIVE_RETRANS, STREAM4_EVASIVE_RETRANS_STR },
+	{ STREAM4_WINDOW_VIOLATION, STREAM4_WINDOW_VIOLATION_STR },
+	{ STREAM4_DATA_ON_SYN, STREAM4_DATA_ON_SYN_STR },
+	{ STREAM4_STEALTH_FULL_XMAS, STREAM4_STEALTH_FULL_XMAS_STR },
+	{ STREAM4_STEALTH_SAPU, STREAM4_STEALTH_SAPU_STR },
+	{ STREAM4_STEALTH_FIN_SCAN, STREAM4_STEALTH_FIN_SCAN_STR },
+	{ STREAM4_STEALTH_NULL_SCAN, STREAM4_STEALTH_NULL_SCAN_STR },
+	{ STREAM4_STEALTH_NMAP_XMAS_SCAN, STREAM4_STEALTH_NMAP_XMAS_SCAN_STR },
+	{ STREAM4_STEALTH_VECNA_SCAN, STREAM4_STEALTH_VECNA_SCAN_STR },
+	{ STREAM4_STEALTH_NMAP_FINGERPRINT, STREAM4_STEALTH_NMAP_FINGERPRINT_STR },
+	{ STREAM4_STEALTH_SYN_FIN_SCAN, STREAM4_STEALTH_SYN_FIN_SCAN_STR },
+	{ STREAM4_FORWARD_OVERLAP, STREAM4_FORWARD_OVERLAP_STR },
+	{ STREAM4_TTL_EVASION, STREAM4_TTL_EVASION_STR },
+	{ STREAM4_EVASIVE_RETRANS_DATA, STREAM4_EVASIVE_RETRANS_DATA_STR },
+	{ STREAM4_EVASIVE_RETRANS_DATASPLIT, STREAM4_EVASIVE_RETRANS_DATASPLIT_STR },
+	{ STREAM4_MULTIPLE_ACKED, STREAM4_MULTIPLE_ACKED_STR },
+	{ STREAM4_EMERGENCY, STREAM4_EMERGENCY_STR },
+	{ STREAM4_SUSPEND, STREAM4_SUSPEND_STR },
+	{ ARPSPOOF_UNICAST_ARP_REQUEST, ARPSPOOF_UNICAST_ARP_REQUEST_STR },
+	{ ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC_STR },
+	{ ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST_STR },
+	{ ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK, ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK_STR },
+	{ FRAG2_OVERSIZE_FRAG, FRAG2_OVERSIZE_FRAG_STR },
+	{ FRAG2_TEARDROP, FRAG2_TEARDROP_STR },
+	{ FRAG2_TTL_EVASION, FRAG2_TTL_EVASION_STR },
+	{ FRAG2_OVERLAP, FRAG2_OVERLAP_STR },
+	{ FRAG2_DUPFIRST, FRAG2_DUPFIRST_STR },
+	{ FRAG2_MEM_EXCEED, "frag2 mem exceed" },
+	{ FRAG2_OUTOFORDER, FRAG2_OUTOFORDER_STR },
+	{ FRAG2_IPOPTIONS, FRAG2_IPOPTIONS_STR },
+	{ FRAG2_EMERGENCY, FRAG2_EMERGENCY_STR },
+	{ FRAG2_SUSPEND, FRAG2_SUSPEND_STR },
+	{ FNORD_NOPSLED, "fnord nopsled" },
+	{ ASN1_INDEFINITE_LENGTH, ASN1_INDEFINITE_LENGTH_STR },
+	{ ASN1_INVALID_LENGTH, ASN1_INVALID_LENGTH_STR },
+	{ ASN1_OVERSIZED_ITEM, ASN1_OVERSIZED_ITEM_STR },
+	{ ASN1_SPEC_VIOLATION, ASN1_SPEC_VIOLATION_STR },
+	{ ASN1_DATUM_BAD_LENGTH, ASN1_DATUM_BAD_LENGTH_STR },
+	{ DECODE_NOT_IPV4_DGRAM, DECODE_NOT_IPV4_DGRAM_STR },
+	{ DECODE_IPV4_INVALID_HEADER_LEN, DECODE_IPV4_INVALID_HEADER_LEN_STR },
+	{ DECODE_IPV4_DGRAM_LT_IPHDR, DECODE_IPV4_DGRAM_LT_IPHDR_STR },
+	{ DECODE_IPV4OPT_BADLEN, DECODE_IPV4OPT_BADLEN_STR },
+	{ DECODE_IPV4OPT_TRUNCATED, DECODE_IPV4OPT_TRUNCATED_STR },
+	{ DECODE_TCP_DGRAM_LT_TCPHDR, DECODE_TCP_DGRAM_LT_TCPHDR_STR },
+	{ DECODE_TCP_INVALID_OFFSET, DECODE_TCP_INVALID_OFFSET_STR },
+	{ DECODE_TCP_LARGE_OFFSET, DECODE_TCP_LARGE_OFFSET_STR },
+	{ DECODE_TCPOPT_BADLEN, DECODE_TCPOPT_BADLEN_STR },
+	{ DECODE_TCPOPT_TRUNCATED, DECODE_TCPOPT_TRUNCATED_STR },
+	{ DECODE_TCPOPT_TTCP, DECODE_TCPOPT_TTCP_STR },
+	{ DECODE_TCPOPT_OBSOLETE, DECODE_TCPOPT_OBSOLETE_STR },
+	{ DECODE_TCPOPT_EXPERIMENT, DECODE_TCPOPT_EXPERIMENT_STR },
+	{ DECODE_UDP_DGRAM_LT_UDPHDR, DECODE_UDP_DGRAM_LT_UDPHDR_STR },
+	{ DECODE_UDP_DGRAM_INVALID_LENGTH, DECODE_UDP_DGRAM_INVALID_LENGTH_STR },
+	{ DECODE_UDP_DGRAM_SHORT_PACKET, DECODE_UDP_DGRAM_SHORT_PACKET_STR },
+	{ DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR },
+	{ DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR, DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR_STR },
+	{ DECODE_ICMP_DGRAM_LT_ADDRHDR, DECODE_ICMP_DGRAM_LT_ADDRHDR_STR },
+	{ DECODE_IPV4_DGRAM_UNKNOWN, DECODE_IPV4_DGRAM_UNKNOWN_STR },
+	{ DECODE_ARP_TRUNCATED, DECODE_ARP_TRUNCATED_STR },
+	{ DECODE_EAPOL_TRUNCATED, DECODE_EAPOL_TRUNCATED_STR },
+	{ DECODE_EAPKEY_TRUNCATED, DECODE_EAPKEY_TRUNCATED_STR },
+	{ DECODE_EAP_TRUNCATED, DECODE_EAP_TRUNCATED_STR },
+	{ DECODE_BAD_PPPOE, DECODE_BAD_PPPOE_STR },
+	{ DECODE_BAD_VLAN, DECODE_BAD_VLAN_STR },
+	{ DECODE_BAD_VLAN_ETHLLC, DECODE_BAD_VLAN_ETHLLC_STR },
+	{ DECODE_BAD_VLAN_OTHER, DECODE_BAD_VLAN_OTHER_STR },
+	{ DECODE_BAD_80211_ETHLLC, DECODE_BAD_80211_ETHLLC_STR },
+	{ DECODE_BAD_80211_OTHER, DECODE_BAD_80211_OTHER_STR },
+	{ DECODE_BAD_TRH, DECODE_BAD_TRH_STR },
+	{ DECODE_BAD_TR_ETHLLC, DECODE_BAD_TR_ETHLLC_STR },
+	{ DECODE_BAD_TR_MR_LEN, DECODE_BAD_TR_MR_LEN_STR },
+	{ DECODE_BAD_TRHMR, DECODE_BAD_TRHMR_STR },
+	{ SCAN_TYPE, "scan type" },
+	{ CONV_BAD_IP_PROTOCOL, CONV_BAD_IP_PROTOCOL_STR },
+	{ HI_CLIENT_ASCII, "hi client ascii" },
+	{ HI_CLIENT_DOUBLE_DECODE, "hi client double decode" },
+	{ HI_CLIENT_U_ENCODE, "hi client u encode" },
+	{ HI_CLIENT_BARE_BYTE, "hi client bare byte" },
+	{ HI_CLIENT_BASE36, "hi client base36" },
+	{ HI_CLIENT_UTF_8, "hi client utf 8" },
+	{ HI_CLIENT_IIS_UNICODE, "hi client iis unicode" },
+	{ HI_CLIENT_MULTI_SLASH, "hi client multi slash" },
+	{ HI_CLIENT_IIS_BACKSLASH, "hi client iis backslash" },
+	{ HI_CLIENT_SELF_DIR_TRAV, "hi client self dir trav" },
+	{ HI_CLIENT_DIR_TRAV, "hi client dir trav" },
+	{ HI_CLIENT_APACHE_WS, "hi client apache ws" },
+	{ HI_CLIENT_IIS_DELIMITER, "hi client iis delimiter" },
+	{ HI_CLIENT_NON_RFC_CHAR, "hi client non rfc char" },
+	{ HI_CLIENT_OVERSIZE_DIR, "hi client oversize dir" },
+	{ HI_CLIENT_LARGE_CHUNK, "hi client large chunk" },
+	{ HI_CLIENT_PROXY_USE, "hi client proxy use" },
+	{ HI_CLIENT_WEBROOT_DIR, "hi client webroot dir" },
+	{ HI_ANOM_SERVER_ALERT, "hi anom server alert" },
+	{ FLOW_SCANNER_FIXED_ALERT, "flow scanner fixed alert" },
+	{ FLOW_SCANNER_SLIDING_ALERT, "flow scanner sliding alert" },
+	{ FLOW_TALKER_FIXED_ALERT, "flow talker fixed alert" },
+	{ FLOW_TALKER_SLIDING_ALERT, "flow talker sliding alert" },
+	{ PSNG_TCP_PORTSCAN, PSNG_TCP_PORTSCAN_STR },
+	{ PSNG_TCP_DECOY_PORTSCAN, PSNG_TCP_DECOY_PORTSCAN_STR },
+	{ PSNG_TCP_PORTSWEEP, PSNG_TCP_PORTSWEEP_STR },
+	{ PSNG_TCP_DISTRIBUTED_PORTSCAN, PSNG_TCP_DISTRIBUTED_PORTSCAN_STR },
+	{ PSNG_TCP_FILTERED_PORTSCAN, PSNG_TCP_FILTERED_PORTSCAN_STR },
+	{ PSNG_TCP_FILTERED_DECOY_PORTSCAN, PSNG_TCP_FILTERED_DECOY_PORTSCAN_STR },
+	{ PSNG_TCP_PORTSWEEP_FILTERED, PSNG_TCP_PORTSWEEP_FILTERED_STR },
+	{ PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN, PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN_STR },
+	{ PSNG_IP_PORTSCAN, PSNG_IP_PORTSCAN_STR },
+	{ PSNG_IP_DECOY_PORTSCAN, PSNG_IP_DECOY_PORTSCAN_STR },
+	{ PSNG_IP_PORTSWEEP, PSNG_IP_PORTSWEEP_STR },
+	{ PSNG_IP_DISTRIBUTED_PORTSCAN, PSNG_IP_DISTRIBUTED_PORTSCAN_STR },
+	{ PSNG_IP_FILTERED_PORTSCAN, PSNG_IP_FILTERED_PORTSCAN_STR },
+	{ PSNG_IP_FILTERED_DECOY_PORTSCAN, PSNG_IP_FILTERED_DECOY_PORTSCAN_STR },
+	{ PSNG_IP_PORTSWEEP_FILTERED, PSNG_IP_PORTSWEEP_FILTERED_STR },
+	{ PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN, PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN_STR },
+	{ PSNG_UDP_PORTSCAN, PSNG_UDP_PORTSCAN_STR },
+	{ PSNG_UDP_DECOY_PORTSCAN, PSNG_UDP_DECOY_PORTSCAN_STR },
+	{ PSNG_UDP_PORTSWEEP, PSNG_UDP_PORTSWEEP_STR },
+	{ PSNG_UDP_DISTRIBUTED_PORTSCAN, PSNG_UDP_DISTRIBUTED_PORTSCAN_STR },
+	{ PSNG_UDP_FILTERED_PORTSCAN, PSNG_UDP_FILTERED_PORTSCAN_STR },
+	{ PSNG_UDP_FILTERED_DECOY_PORTSCAN, PSNG_UDP_FILTERED_DECOY_PORTSCAN_STR },
+	{ PSNG_UDP_PORTSWEEP_FILTERED, PSNG_UDP_PORTSWEEP_FILTERED_STR },
+	{ PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN, PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN_STR },
+	{ PSNG_ICMP_PORTSWEEP, PSNG_ICMP_PORTSWEEP_STR },
+	{ PSNG_ICMP_PORTSWEEP_FILTERED, PSNG_ICMP_PORTSWEEP_FILTERED_STR },
+	{ PSNG_OPEN_PORT, PSNG_OPEN_PORT_STR },
+	{ 0, NULL },
+};
Index: epan/dissectors/Makefile.common
===================================================================
--- epan/dissectors/Makefile.common	(revision 14717)
+++ epan/dissectors/Makefile.common	(working copy)
@@ -528,6 +528,7 @@
 	packet-snaeth.c	\
 	packet-sndcp.c	\
 	packet-snmp.c	\
+	packet-snort_unified.c	\
 	packet-socks.c	\
 	packet-spnego.c	\
 	packet-spp.c	\
Index: wiretap/wtap.h
===================================================================
--- wiretap/wtap.h	(revision 14717)
+++ wiretap/wtap.h	(working copy)
@@ -169,9 +169,10 @@
 #define WTAP_GCOM_TIE1				78
 #define WTAP_GCOM_SERIAL			79
 #define WTAP_ENCAP_NETTL_X25			80
-#define WTAP_ENCAP_K12					81
+#define WTAP_ENCAP_K12				81
+#define WTAP_ENCAP_SNORT_UNIFIED		82
 /* last WTAP_ENCAP_ value + 1 */
-#define WTAP_NUM_ENCAP_TYPES			82
+#define WTAP_NUM_ENCAP_TYPES			83
 
 /* File types that can be read by wiretap.
    We support writing some many of these file types, too, so we
@@ -217,9 +218,10 @@
 #define WTAP_FILE_AIROPEEK_V9			38
 #define WTAP_FILE_EYESDN			39
 #define WTAP_FILE_K12				40
+#define WTAP_FILE_SNORT_UNIFIED			41
 
 /* last WTAP_FILE_ value + 1 */
-#define WTAP_NUM_FILE_TYPES			41
+#define WTAP_NUM_FILE_TYPES			42
 
 /*
  * Maximum packet size we'll support.
@@ -495,6 +497,8 @@
 	guint32	caplen;
 	guint32 len;
 	int pkt_encap;
+	int orig_pkt_encap;
+	void *snort_data;
 };
 
 struct wtap;
Index: wiretap/libpcap.c
===================================================================
--- wiretap/libpcap.c	(revision 14717)
+++ wiretap/libpcap.c	(working copy)
@@ -103,7 +103,7 @@
     union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
     int *err, gchar **err_info);
 static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
-    struct pcaprec_ss990915_hdr *hdr);
+    union pcaprec_hdr_u *hdr);
 static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
 static void libpcap_get_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr,
     union wtap_pseudo_header *pseudo_header);
@@ -377,6 +377,9 @@
 	{ 172,		WTAP_GCOM_TIE1 },
 	{ 173,		WTAP_GCOM_SERIAL },
 
+	/* TODO.mds: register this value at tcpdump-workers */
+	{ 174,		WTAP_ENCAP_SNORT_UNIFIED },
+
 	/*
 	 * To repeat:
 	 *
@@ -597,6 +600,7 @@
 	struct pcap_hdr hdr;
 	gboolean byte_swapped;
 	gboolean modified;
+	gboolean snort;
 	gboolean aix;
 	int file_encap;
 
@@ -618,13 +622,23 @@
 		   a program using either standard or ss990417 libpcap. */
 		byte_swapped = FALSE;
 		modified = FALSE;
+		snort = FALSE;
 		break;
 
+	case PCAP_SNORT_UNIFIED_MAGIC:
+		/* Host that wrote it has our byte order, and this is a
+		   snort unified log file */
+		byte_swapped = FALSE;
+		modified = FALSE;
+		snort = TRUE;
+		break;
+
 	case PCAP_MODIFIED_MAGIC:
 		/* Host that wrote it has our byte order, and was running
 		   a program using either ss990915 or ss991029 libpcap. */
 		byte_swapped = FALSE;
 		modified = TRUE;
+		snort = FALSE;
 		break;
 
 	case PCAP_SWAPPED_MAGIC:
@@ -633,14 +647,24 @@
 		   ss990417 libpcap. */
 		byte_swapped = TRUE;
 		modified = FALSE;
+		snort = FALSE;
 		break;
 
+	case PCAP_SWAPPED_SNORT_UNIFIED_MAGIC:
+		/* Host that wrote it has a byte order opposite to ours,
+		   and this is a snort unified log file */
+		byte_swapped = TRUE;
+		modified = FALSE;
+		snort = TRUE;
+		break;
+
 	case PCAP_SWAPPED_MODIFIED_MAGIC:
 		/* Host that wrote it out has a byte order opposite to
 		   ours, and was running a program using either ss990915
 		   or ss991029 libpcap. */
 		byte_swapped = TRUE;
 		modified = TRUE;
+		snort = FALSE;
 		break;
 
 	default:
@@ -648,7 +672,7 @@
 		return 0;
 	}
 
-	/* Read the rest of the header. */
+	/* Read the rest of the libpcap file-header. */
 	errno = WTAP_ERR_CANT_READ;
 	bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
 	if (bytes_read != sizeof hdr) {
@@ -666,7 +690,13 @@
 		hdr.snaplen = BSWAP32(hdr.snaplen);
 		hdr.network = BSWAP32(hdr.network);
 	}
-	if (hdr.version_major < 2) {
+ 	if ( hdr.version_major == 1 && hdr.version_minor == 2 &&
+	     (magic == PCAP_SWAPPED_SNORT_UNIFIED_MAGIC ||
+	      magic == PCAP_SNORT_UNIFIED_MAGIC) ) {
+		/* Snort's unified log uses major 1, minor 2.  I'm not
+		   quite sure what to do, but this seems to work... */
+		hdr.version_major = 2;
+	} else if (hdr.version_major < 2) {
 		/* We only support version 2.0 and later. */
 		*err = WTAP_ERR_UNSUPPORTED;
 		*err_info = g_strdup_printf("pcap: major version %u unsupported",
@@ -762,6 +792,8 @@
 	wth->subtype_seek_read = libpcap_seek_read;
 	wth->subtype_close = libpcap_close;
 	wth->file_encap = file_encap;
+	wth->phdr.orig_pkt_encap = file_encap; /* used by Snort dissector to restore
+						  the *real* encapsulation */
 	wth->snapshot_length = hdr.snaplen;
 
 	/* In file format version 2.3, the order of the "incl_len" and
@@ -794,7 +826,7 @@
 	case 543:
 		wth->capture.pcap->lengths_swapped = SWAPPED;
 		break;
-
+		
 	default:
 		wth->capture.pcap->lengths_swapped = NOT_SWAPPED;
 		break;
@@ -844,8 +876,58 @@
 	 * be a Nokia libpcap file, so we may need to try that if
 	 * neither normal nor ss990417 headers work.
 	 */
-	if (modified) {
+	if (snort) {
 		/*
+		 * Well, we have the magic number from snort's
+		 * unified log file.
+		 *
+		 * Read through a couple of records for sanity.
+		 */
+		wth->file_type = WTAP_FILE_SNORT_UNIFIED;
+		switch (libpcap_try(wth, err)) {
+
+		case BAD_READ:
+			/*
+			 * Well, we couldn't even read it.
+			 * Give up.
+			 */
+			g_free(wth->capture.pcap);
+			return -1;
+
+		case THIS_FORMAT:
+			/*
+			 * Well, it looks as if it might be Snort
+			 * unified.  Put the seek pointer back, set
+			 * the encapsulation, and return success.
+			 */
+			if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
+				g_free(wth->capture.pcap);
+				return -1;
+			}
+			wth->file_encap = WTAP_ENCAP_SNORT_UNIFIED;
+			return 1;
+
+		case OTHER_FORMAT:
+			/*
+			 * Try the next format.
+			 */
+			break;
+		}
+
+		/*
+		 * Well, it's not completely unreadable,
+		 * but it's not ss991029.  Try ss990915;
+		 * there are no other types to try after that,
+		 * so we put the seek pointer back and treat
+		 * it as 990915.
+		 */
+		wth->file_type = WTAP_FILE_PCAP_SS990915;
+		if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
+			g_free(wth->capture.pcap);
+			return -1;
+		}
+	} else if (modified) {
+		/*
 		 * Well, we have the magic number from Alexey's
 		 * later two patches.
 		 *
@@ -1004,10 +1086,12 @@
 static libpcap_try_t libpcap_try(wtap *wth, int *err)
 {
 	/*
-	 * pcaprec_ss990915_hdr is the largest header type.
+	 * pcaprec_hdr_u is the size of the largest header type.
 	 */
-	struct pcaprec_ss990915_hdr first_rec_hdr, second_rec_hdr;
+	union pcaprec_hdr_u first_rec_hdr, second_rec_hdr;
+	guint32	data_len;
 
+
 	/*
 	 * Attempt to read the first record's header.
 	 */
@@ -1044,7 +1128,11 @@
 	 * Now skip over the first record's data, under the assumption
 	 * that the header is sane.
 	 */
-	if (file_seek(wth->fh, first_rec_hdr.hdr.incl_len, SEEK_CUR, err) == -1)
+	if (wth->file_type == WTAP_FILE_SNORT_UNIFIED)
+		data_len = first_rec_hdr.snort.hdr.incl_len;
+	else
+		data_len = first_rec_hdr.std.hdr.incl_len;
+	if (file_seek(wth->fh, data_len, SEEK_CUR, err) == -1)
 		return BAD_READ;
 
 	/*
@@ -1091,13 +1179,14 @@
 static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
     long *data_offset)
 {
-	struct pcaprec_ss990915_hdr hdr;
+	union pcaprec_hdr_u base_hdr;
+	struct pcaprec_hdr hdr;
 	guint packet_size;
 	guint orig_size;
 	int bytes_read;
 	guchar fddi_padding[3];
 
-	bytes_read = libpcap_read_header(wth, err, err_info, &hdr);
+	bytes_read = libpcap_read_header(wth, err, err_info, &base_hdr);
 	if (bytes_read == -1) {
 		/*
 		 * We failed to read the header.
@@ -1105,9 +1194,18 @@
 		return FALSE;
 	}
 
+	if (wth->file_type == WTAP_FILE_SNORT_UNIFIED) {
+		hdr = base_hdr.snort.hdr;
+		/* TODO.mds: this needs to be g_free()d at some point? */
+		wth->phdr.snort_data = g_malloc(sizeof(struct pcaprec_snort_unified_hdr));
+		memcpy(wth->phdr.snort_data,&(base_hdr.snort),sizeof(struct pcaprec_snort_unified_hdr));
+	} else {
+		hdr = base_hdr.std.hdr;
+		wth->phdr.snort_data = NULL;
+	}
 	wth->data_offset += bytes_read;
-	packet_size = hdr.hdr.incl_len;
-	orig_size = hdr.hdr.orig_len;
+	packet_size = hdr.incl_len;
+	orig_size = hdr.orig_len;
 
 	/*
 	 * AIX appears to put 3 bytes of padding in front of FDDI
@@ -1266,11 +1364,19 @@
 		return FALSE;	/* Read error */
 	wth->data_offset += packet_size;
 
-	wth->phdr.ts.tv_sec = hdr.hdr.ts_sec;
-	wth->phdr.ts.tv_usec = hdr.hdr.ts_usec;
+	wth->phdr.ts.tv_sec = hdr.ts_sec;
+	wth->phdr.ts.tv_usec = hdr.ts_usec;
 	wth->phdr.caplen = packet_size;
 	wth->phdr.len = orig_size;
 
+	if (wth->file_encap == WTAP_ENCAP_SNORT_UNIFIED) {
+		/* Check for special Snort packet indicating a port-scan */
+		char *ptr = buffer_start_ptr(wth->frame_buffer);
+		if (!strncmp(ptr,"MACDADMACDAD",12)) {
+			/* TODO.mds: snort's reference time is fubar'd in this case */
+			wth->phdr.orig_pkt_encap = WTAP_ENCAP_ETHERNET;
+		}
+	}
 	if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
 		if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
 			/*
@@ -1400,9 +1506,10 @@
 
    Return -1 on an error, or the number of bytes of header read on success. */
 static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
-    struct pcaprec_ss990915_hdr *hdr)
+    union pcaprec_hdr_u *hdr_u)
 {
 	int	bytes_to_read, bytes_read;
+	struct pcaprec_hdr *hdr;
 
 	/* Read record header. */
 	errno = WTAP_ERR_CANT_READ;
@@ -1422,6 +1529,10 @@
 		bytes_to_read = sizeof (struct pcaprec_ss990915_hdr);
 		break;
 
+	case WTAP_FILE_SNORT_UNIFIED:
+		bytes_to_read = sizeof (struct pcaprec_snort_unified_hdr);
+		break;
+
 	case WTAP_FILE_PCAP_NOKIA:
 		bytes_to_read = sizeof (struct pcaprec_nokia_hdr);
 		break;
@@ -1430,7 +1541,7 @@
 		g_assert_not_reached();
 		bytes_to_read = 0;
 	}
-	bytes_read = file_read(hdr, 1, bytes_to_read, wth->fh);
+	bytes_read = file_read(hdr_u, 1, bytes_to_read, wth->fh);
 	if (bytes_read != bytes_to_read) {
 		*err = file_error(wth->fh);
 		if (*err == 0 && bytes_read != 0) {
@@ -1439,9 +1550,13 @@
 		return -1;
 	}
 
-	adjust_header(wth, &hdr->hdr);
+	if (wth->file_type == WTAP_FILE_SNORT_UNIFIED)
+		hdr = &(hdr_u->snort.hdr);
+	else
+		hdr = &(hdr_u->std.hdr);
+	adjust_header(wth, hdr);
 
-	if (hdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
+	if (hdr->incl_len > WTAP_MAX_PACKET_SIZE) {
 		/*
 		 * Probably a corrupt capture file; return an error,
 		 * so that our caller doesn't blow up trying to allocate
@@ -1453,12 +1568,12 @@
 		*err = WTAP_ERR_BAD_RECORD;
 		if (err_info != NULL) {
 			*err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
-			    hdr->hdr.incl_len, WTAP_MAX_PACKET_SIZE);
+			    hdr->incl_len, WTAP_MAX_PACKET_SIZE);
 		}
 		return -1;
 	}
 
-	if (hdr->hdr.orig_len > WTAP_MAX_PACKET_SIZE) {
+	if (hdr->orig_len > WTAP_MAX_PACKET_SIZE) {
 		/*
 		 * Probably a corrupt capture file; return an error,
 		 * so that our caller doesn't blow up trying to
@@ -1470,7 +1585,7 @@
 		*err = WTAP_ERR_BAD_RECORD;
 		if (err_info != NULL) {
 			*err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
-			    hdr->hdr.orig_len, WTAP_MAX_PACKET_SIZE);
+			    hdr->orig_len, WTAP_MAX_PACKET_SIZE);
 		}
 		return -1;
 	}
@@ -1945,8 +2060,10 @@
 		magic = PCAP_MODIFIED_MAGIC;
 		break;
 
+	case WTAP_FILE_SNORT_UNIFIED: /* no support for writing this format */
+
 	default:
-		/* We should never get here - our open routine
+		/* This case should never trigger - our open routine
 		   should only get called for the types above. */
 		*err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
 		return FALSE;
Index: wiretap/libpcap.h
===================================================================
--- wiretap/libpcap.h	(revision 14717)
+++ wiretap/libpcap.h	(working copy)
@@ -42,6 +42,8 @@
 #define	PCAP_SWAPPED_MAGIC		0xd4c3b2a1
 #define	PCAP_MODIFIED_MAGIC		0xa1b2cd34
 #define	PCAP_SWAPPED_MODIFIED_MAGIC	0x34cdb2a1
+#define	PCAP_SNORT_UNIFIED_MAGIC	0xdead1080
+#define	PCAP_SWAPPED_SNORT_UNIFIED_MAGIC 0x8010adde
 
 /* "libpcap" file header (minus magic number). */
 struct pcap_hdr {
@@ -72,6 +74,24 @@
 	guint8 pad;		/* pad to a 4-byte boundary */
 };
 
+/* This is what the snort unified log record header actually looks
+ * like in the file. */
+struct pcaprec_snort_unified_hdr {
+	guint32 sig_generator;   /* which part of snort generated the alert? */
+	guint32 sig_id;          /* sig id for this generator */
+	guint32 sig_rev;         /* sig revision for this id */
+	guint32 classification;  /* event classification */
+	guint32 priority;        /* event priority */
+	guint32 event_id;        /* event ID */
+	guint32 event_reference; /* reference to other events that have gone off,
+                                  * such as in the case of tagged packets...
+                                  */
+	guint32	ref_sec;         /* reference time for the event */
+	guint32	ref_usec;	 /* reference */
+	guint32 flags;           /* bitmap for interesting flags */
+	struct pcaprec_hdr hdr;  /* the regular header */
+};
+
 /* "libpcap" record header for Alexey's patched version in its ss990915
    incarnation; this version shows up in SuSE Linux 6.3. */
 struct pcaprec_ss990915_hdr {
@@ -85,6 +105,14 @@
 	guint8 pad[3];		/* pad to a 4-byte boundary */
 };
 
+/* This union only contains two types, because it's used only during
+   reading, and the ss990915 format works for everything but the snort
+   format. */
+union pcaprec_hdr_u {
+	struct pcaprec_snort_unified_hdr snort;
+	struct pcaprec_ss990915_hdr std;
+};
+
 /* "libpcap" record header for version used on some Nokia boxes (firewalls?) */
 struct pcaprec_nokia_hdr {
 	struct pcaprec_hdr hdr;	/* the regular header */
Index: file.c
===================================================================
--- file.c	(revision 14717)
+++ file.c	(working copy)
@@ -883,6 +883,10 @@
   fdata->flags.marked = 0;
   fdata->flags.ref_time = 0;
 
+  /* the following 2 are used by the snort dissector */
+  fdata->orig_lnk_t = phdr->orig_pkt_encap;
+  fdata->snort_data = phdr->snort_data;
+
   passed = TRUE;
   if (cf->rfcode) {
     edt = epan_dissect_new(TRUE, FALSE);