--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 .PHONY: libpcap openvpn
 
-all: openvpn libpcap
+all: openvpn libpcap snort
 
 libpcap: odp
 	make -C libpcap ODP_DIR=$(PWD)/odp.git
@@ -8,10 +8,15 @@ libpcap: odp
 openvpn: odp
 	make -C openvpn
 
+snort: odp
+	make -C snort
+
 odp:
 	if [ ! -d odp.git ]; \
 		then git clone http://git.linaro.org/git/lng/odp.git odp.git; \
 	fi
+	cd odp.git; git reset --hard HEAD
+	cd odp.git; patch -N -p1 < ../snort/odp-patches/0001-implement-odp_timer_disarm_all.patch
 	cd odp.git; make libs_install  CFLAGS="-fPIC"
 
 distclean:
--- /dev/null
+++ b/snort/Makefile
@@ -0,0 +1,65 @@
+.PHONY: all odp daq snort odpsnort
+all: snort
+
+DAQ="daq-2.0.2"
+daqprep:
+	rm -rf ${DAQ}
+	tar xpvfz ./download/daq-2.0.2.tar.gz
+	cd ${DAQ}; patch -p1 < ../daq-patches/0001-implement-odp-daq-module.patch
+
+
+daq: daqprep libdnet
+	cd ${DAQ}; autoreconf
+	cd ${DAQ}; ./configure CFLAGS="-I${PWD}/../odp.git/build/include -g -O0" LDFLAGS="-g -L${PWD}/../odp.git/build/lib"
+	cd ${DAQ}; make
+	cd ${DAQ}; make install
+
+
+snortprep:
+	rm -rf snort-2.9.6.0
+	tar xpfz download/snort-2.9.6.0.tar.gz
+
+SNORT="snort-2.9.6.1-odp"
+snort: snortprep daq
+	rm -rf $(SNORT)
+	cp -a snort-2.9.6.0 $(SNORT)
+	cd ${SNORT}; patch -p2 < ../snort-patches/0001-add-dependancy-for-lrt.patch
+	cd ${SNORT}; ./configure --disable-static-daq LDFLAGS="-lrt"
+	cd ${SNORT}; make
+	cd ${SNORT}; make install
+
+LIBDNET="libdnet-1.11"
+libdnet:
+	#wget http://prdownloads.sourceforge.net/libdnet/libdnet-1.11.tar.gz
+	tar xpfz ./download/libdnet-1.11.tar.gz
+	cd ${LIBDNET}; ./configure
+	cd ${LIBDNET}; make
+	cd ${LIBDNET}; make install
+
+run:
+	export LD_LIBRARY_PATH="/usr/local/lib"; snort --daq-dir=${PWD}/daq-2.0.2/os-daq-modules/.libs/ --daq=odp -i eth0 -n 10
+
+SNORT-lib="snort-2.9.6.0-lib"
+snortlib: snortprep daq
+	rm -rf ${SNORT-lib}
+	cp -a snort-2.9.6.0 ${SNORT-lib}
+	cd ${SNORT-lib}; patch -p2 <  ../snort-patches/0001-add-dependancy-for-lrt.patch
+	cd ${SNORT-lib}; patch -p1 <  ../lib-patches/0001-Compile-Snort-as-static-library.patch
+	cd ${SNORT-lib}; patch -p1 <  ../lib-patches/0002-remove-static-from-needed-functions.patch
+	cd ${SNORT-lib}; autoreconf
+	cd ${SNORT-lib}; ./configure --disable-static-daq LDFLAGS="-lrt"
+	cd ${SNORT-lib}; make
+
+odpsnort: snortlib
+	cd odpsnort; make
+
+all: libdnet daq snort odpsnort
+
+distclean:
+	rm -rf ${DAQ}
+	rm -rf ${SNORT}
+	rm -rf ${SNORT-lib}
+	rm -rf snort-2.9.6.1
+	rm -rf snort-2.9.6.0
+	rm -rf libdnet-1.11
+	make -C odpsnort clean
--- /dev/null
+++ b/snort/README
@@ -0,0 +1,37 @@
+--- Snort on Open Data Plane ---
+
+Directory has 2 different demos:
+
+1. Data Acquisition Module (DAQ) with ODP support.
+
+All magic happens inside shared library daq-odp.so which provides packet I/O to Snort application. DAQ module loaded as plug-in so no snort modification is needed.
+(Because of odp uses lib rt I added librt to dependencies.).
+
+Compile:
+make
+Run:
+make run
+
+Make run will execute following command (odp daq module, interface eth0, and 10 packets to capture):
+snort --daq-dir=${PWD}/daq-2.0.2/os-daq-modules/.libs/ --daq=odp -i eth0 -n 10
+
+2. Snort analyze function used in Open Data Plane applications.
+
+This example is opposite to the first one. I.e. it adds snort functionality to odp apps. For that Snort was built as static library with exported needed functions.
+As base test/packet_io example was taken. Main thread does snort initialization then it starts several odp threads which do packet processing and feed Snort.
+So this test has to scale across number of cpus and have some performance benefits according to regular single threaded snort.
+
+Compile:
+make odpsnort
+Run:
+odpsnort/odp-snort
+
+Configuration:
+Selection of number of threads and interfaces can be done in source code:
+odpsnort/odp_pktio.c
+    args->appl.core_count = 1;
+    args->appl.if_count = 1;
+    args->appl.if_names = calloc(args->appl.if_count, sizeof(char *));
+    args->appl.if_names[0] = strdup("eth0");
+
+
--- /dev/null
+++ b/snort/daq-patches/0001-implement-odp-daq-module.patch
@@ -0,0 +1,477 @@
+From 98f7d2a6eb53a17c855a40573300437ec8a3fe83 Mon Sep 17 00:00:00 2001
+From: root <maxim.uvarov@linaro.org>
+Date: Mon, 19 May 2014 18:04:58 +0400
+Subject: [PATCH] implement odp daq module
+
+Signed-off-by: root <maxim.uvarov@linaro.org>
+---
+ configure.ac               |   7 +
+ os-daq-modules/Makefile.am |  12 ++
+ os-daq-modules/daq_odp.c   | 409 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 428 insertions(+)
+ create mode 100644 os-daq-modules/daq_odp.c
+
+diff --git a/configure.ac b/configure.ac
+index ae4f77f..5689dd3 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -107,6 +107,12 @@ else
+     DEFAULT_ENABLE=no
+ fi
+ 
++# OpenDataPlane
++AC_ARG_ENABLE(odp-module,
++              AC_HELP_STRING([--disable-odp-module],[don't build the bundled OpenDataPlane module]),
++              [enable_odp_module="$enableval"], [enable_odp_module="$DEFAULT_ENABLE"])
++AM_CONDITIONAL([BUILD_ODP_MODULE], [test "$enable_odp_module" = yes])
++
+ # AFPacket Module
+ AC_ARG_ENABLE(afpacket-module,
+               AC_HELP_STRING([--disable-afpacket-module],[don't build the bundled AFPacket module]),
+@@ -276,4 +282,5 @@ echo "Build IPFW DAQ module...... : $enable_ipfw_module"
+ echo "Build IPQ DAQ module....... : $enable_ipq_module"
+ echo "Build NFQ DAQ module....... : $enable_nfq_module"
+ echo "Build PCAP DAQ module...... : $enable_pcap_module"
++echo "Build ODP DAQ module......  : $enable_odp_module"
+ echo
+diff --git a/os-daq-modules/Makefile.am b/os-daq-modules/Makefile.am
+index 37d6df3..cc61354 100644
+--- a/os-daq-modules/Makefile.am
++++ b/os-daq-modules/Makefile.am
+@@ -14,6 +14,18 @@ libdaq_static_modules_la_CFLAGS =
+ libdaq_static_modules_la_LDFLAGS = -static -avoid-version
+ libdaq_static_modules_la_LIBADD =
+ 
++if BUILD_ODP_MODULE
++if BUILD_SHARED_MODULES
++    pkglib_LTLIBRARIES += daq_odp.la
++    daq_odp_la_SOURCES = daq_odp.c
++    daq_odp_la_CFLAGS = -DBUILDING_SO
++    daq_odp_la_LDFLAGS = -module -export-dynamic -avoid-version -lrt -lodp -shared @XCCFLAGS@
++    daq_odp_la_LIBADD = $(top_builddir)/sfbpf/libsfbpf.la
++endif
++    libdaq_static_modules_la_SOURCES += daq_odp.c
++    libdaq_static_modules_la_CFLAGS += -DBUILD_ODP_MODULE
++endif
++
+ if BUILD_AFPACKET_MODULE
+ if BUILD_SHARED_MODULES
+     pkglib_LTLIBRARIES += daq_afpacket.la
+diff --git a/os-daq-modules/daq_odp.c b/os-daq-modules/daq_odp.c
+new file mode 100644
+index 0000000..aa6639e
+--- /dev/null
++++ b/os-daq-modules/daq_odp.c
+@@ -0,0 +1,409 @@
++/*
++ ** Copyright (c) 2014, Linaro Limited
++ ** All rights reserved.
++ **
++ ** SPDX-License-Identifier:      BSD-3-Clause
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <errno.h>
++#include <linux/if_ether.h>
++#include <linux/if_packet.h>
++#include <net/if.h>
++#include <net/if_arp.h>
++#include <netinet/in.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/ioctl.h>
++#include <sys/mman.h>
++#include <sys/poll.h>
++#include <sys/socket.h>
++#include <unistd.h>
++
++#include "daq_api.h"
++#include "sfbpf.h"
++
++#include <odp.h>
++#include <helper/odp_linux.h>
++#include <helper/odp_packet_helper.h>
++#include <helper/odp_eth.h>
++#include <helper/odp_ip.h>
++
++#define MAX_WORKERS            1
++#define SHM_PKT_POOL_SIZE      (512*2048)
++#define SHM_PKT_POOL_BUF_SIZE  1856
++#define MAX_PKT_BURST          16
++#define ODP_DEBUG		1
++
++static unsigned long debug_cnt = 0;
++
++typedef struct _odp_context
++{
++    volatile int break_loop;
++    DAQ_Stats_t stats;
++    DAQ_State state;
++    odp_queue_t inq_def;
++    odp_pktio_t pktio;
++    int snaplen;
++    char *device;
++    char errbuf[256];
++} ODP_Context_t;
++
++static int odp_daq_initialize(const DAQ_Config_t *config, void **ctxt_ptr, char *errbuf, size_t errlen)
++{
++	ODP_Context_t *odpc;
++	int rval = DAQ_ERROR;
++	int thr_id;
++	int i;
++
++	odp_buffer_pool_t pkt_pool;
++	odp_buffer_pool_t pool;
++	odp_pktio_t pktio;
++	odp_pktio_params_t params;
++	socket_params_t *sock_params = &params.sock_params;
++	odp_queue_param_t qparam;
++	char inq_name[ODP_QUEUE_NAME_LEN];
++	odp_packet_t pkt;
++	odp_buffer_t buf;
++	int ret;
++	void *pool_base;
++
++	rval = DAQ_ERROR;
++
++	printf("%s()\n", __func__);
++	odpc = calloc(1, sizeof(ODP_Context_t));
++	if (!odpc)
++	{
++		snprintf(errbuf, errlen, "%s: Couldn't allocate memory for the new ODP context!", __FUNCTION__);
++		rval = DAQ_ERROR_NOMEM;
++		goto err;
++	}
++
++	odpc->device = strdup(config->name);
++	if (!odpc->device)
++	{
++		snprintf(errbuf, errlen, "%s: Couldn't allocate memory for the device string!", __FUNCTION__);
++		rval = DAQ_ERROR_NOMEM;
++		goto err;
++	}
++
++	*ctxt_ptr = odpc;
++
++	/* Init ODP before calling anything else */
++	if (odp_init_global()) {
++		ODP_ERR("Error: ODP global init failed.\n");
++		goto err;
++	}
++
++	/* Init this thread */
++	thr_id = odp_thread_create(0);
++	odp_init_local(thr_id);
++
++	/* Create packet pool */
++	pool_base = odp_shm_reserve("shm_packet_pool",
++				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE);
++	if (pool_base == NULL) {
++		ODP_ERR("Error: packet pool mem alloc failed.\n");
++		goto err;
++	}
++
++	pool = odp_buffer_pool_create("packet_pool", pool_base,
++				      SHM_PKT_POOL_SIZE,
++				      SHM_PKT_POOL_BUF_SIZE,
++				      ODP_CACHE_LINE_SIZE,
++				      ODP_BUFFER_TYPE_PACKET);
++	if (pool == ODP_BUFFER_POOL_INVALID) {
++		ODP_ERR("Error: packet pool create failed.\n");
++		exit(EXIT_FAILURE);
++	}
++	odpc->snaplen = SHM_PKT_POOL_BUF_SIZE;
++	odp_buffer_pool_print(pool);
++
++	/* Open a packet IO instance for this thread */
++	sock_params->type = ODP_PKTIO_TYPE_SOCKET_MMAP;
++	sock_params->fanout = 0;
++
++	odpc->pktio = odp_pktio_open(odpc->device, pool, &params);
++	if (odpc->pktio == ODP_PKTIO_INVALID) {
++		ODP_ERR("  [%02i] Error: pktio create failed\n", 1 /*thr*/);
++		goto err;
++	}
++
++	/*
++	 * Create and set the default INPUT queue associated with the 'pktio'
++	 * resource
++	 */
++	qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
++	qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
++	qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
++	snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)odpc->pktio);
++	inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
++
++	odpc->inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
++	if (odpc->inq_def == ODP_QUEUE_INVALID) {
++		ODP_ERR("  [%02i] Error: pktio queue creation failed\n", 1 /*thr*/);
++		goto err;
++	}
++
++	ret = odp_pktio_inq_setdef(odpc->pktio, odpc->inq_def);
++	if (ret != 0) {
++		ODP_ERR("  [%02i] Error: default input-Q setup\n", 1 /*thr*/);
++		goto err;
++	}
++
++        odpc->state = DAQ_STATE_INITIALIZED;
++
++	printf("%s() DAQ_SUCCESS.\n\n", __func__);
++	return DAQ_SUCCESS;
++err:
++
++	return rval;
++}
++
++static int odp_daq_set_filter(void *handle, const char *filter)
++{
++	printf("%s()\n", __func__);
++	return DAQ_SUCCESS;
++}
++
++static int odp_daq_start(void *handle)
++{
++    ODP_Context_t *odpc = (ODP_Context_t *) handle;
++    if (!odpc)
++	    return DAQ_ERROR_NOCTX;
++
++    odpc->state = DAQ_STATE_STARTED;
++    return DAQ_SUCCESS;
++}
++
++static const DAQ_Verdict verdict_translation_table[MAX_DAQ_VERDICT] = {
++    DAQ_VERDICT_PASS,       /* DAQ_VERDICT_PASS */
++    DAQ_VERDICT_BLOCK,      /* DAQ_VERDICT_BLOCK */
++    DAQ_VERDICT_PASS,       /* DAQ_VERDICT_REPLACE */
++    DAQ_VERDICT_PASS,       /* DAQ_VERDICT_WHITELIST */
++    DAQ_VERDICT_BLOCK,      /* DAQ_VERDICT_BLACKLIST */
++    DAQ_VERDICT_PASS        /* DAQ_VERDICT_IGNORE */
++};
++
++static int odp_daq_acquire(void *handle, int cnt, DAQ_Analysis_Func_t callback, DAQ_Meta_Func_t metaback, void *user)
++{
++    	ODP_Context_t *odpc;
++	DAQ_PktHdr_t daqhdr;
++	DAQ_Verdict verdict;
++	const uint8_t *data;
++
++	int thr_id;
++	odp_packet_t pkt;
++	odp_buffer_t buf;
++	int ret;
++	odp_buffer_pool_t pkt_pool;
++	odp_pktio_params_t params;
++	odp_pktio_t pktio;
++
++	int i;
++	odp_packet_t pkt_tbl[MAX_PKT_BURST];
++	int pkts;
++
++	odpc = (ODP_Context_t *) handle;
++	if (!odpc)
++		return 0;
++
++	if (odpc->state != DAQ_STATE_STARTED)
++		return 0;
++
++	while (1)
++	{
++		/* Has breakloop() been called? */
++		if (odpc->break_loop)
++		{
++			odpc->break_loop = 0;
++			printf("%s() BREAK LOOP\n", __func__);
++			return 0;
++		}
++
++		pkts = odp_pktio_recv(odpc->pktio, pkt_tbl, MAX_PKT_BURST);
++		if (pkts <= 0) {
++			return;
++		}
++
++		printf("got %d packets\n", pkts);
++
++		for (i = 0; i < pkts; ++i) {
++			pkt = pkt_tbl[i];
++
++			data = odp_packet_l2(pkt);
++			if (!data) {
++				printf("no l2 offset, packet dropped\n");
++				continue;
++			}
++
++			verdict = DAQ_VERDICT_PASS;
++
++			gettimeofday(&daqhdr.ts, NULL);
++			daqhdr.caplen = odp_buffer_size(pkt);
++
++			printf("%s() odp recieved packet len %d.\n", __func__, odp_packet_get_len(pkt));
++
++			daqhdr.pktlen = odp_packet_get_len(pkt);
++			daqhdr.ingress_index = 0;
++			daqhdr.egress_index =  DAQ_PKTHDR_UNKNOWN;
++			daqhdr.ingress_group = DAQ_PKTHDR_UNKNOWN;
++			daqhdr.egress_group = DAQ_PKTHDR_UNKNOWN;
++			daqhdr.flags = 0;
++			daqhdr.opaque = 0;
++			daqhdr.priv_ptr = NULL;
++			daqhdr.address_space_id = 0;
++
++			if (callback)
++			{
++				verdict = callback(user, &daqhdr, data); // call back with pointer to data and daqhdr
++				if (verdict >= MAX_DAQ_VERDICT)
++					verdict = DAQ_VERDICT_PASS;
++				odpc->stats.verdicts[verdict]++;
++				verdict = verdict_translation_table[verdict];
++				printf("opd processed packet %ld\n", odpc->stats.verdicts[verdict]);
++			}
++		}
++
++		if (pkts > 0) {
++			printf("pkts > 0, return\n");
++		       return 0;
++		}
++	}
++	return 0;
++}
++
++static int odp_daq_inject(void *handle, const DAQ_PktHdr_t *hdr, const uint8_t *packet_data, uint32_t len, int reverse)
++{
++    return DAQ_SUCCESS;
++}
++
++static int odp_daq_breakloop(void *handle)
++{
++    ODP_Context_t *odpc = (ODP_Context_t *) handle;
++
++    odpc->break_loop = 1;
++    return DAQ_SUCCESS;
++}
++
++static int odp_daq_stop(void *handle)
++{
++    ODP_Context_t *odpc = (ODP_Context_t *) handle;
++
++    odpc->break_loop = 1;
++    odp_timer_disarm_all();
++
++    return DAQ_SUCCESS;
++}
++
++static void odp_daq_shutdown(void *handle)
++{
++	odp_timer_disarm_all();
++}
++
++static DAQ_State odp_daq_check_status(void *handle)
++{
++	ODP_Context_t *odpc = (ODP_Context_t *) handle;
++
++	if (!odpc) {
++		printf("%s() odpc is not allocated\n");
++		return DAQ_STATE_UNINITIALIZED;
++	}
++
++    	//printf("%s()\n", __func__);
++	return odpc->state;
++}
++
++static int odp_daq_get_stats(void *handle, DAQ_Stats_t *stats)
++{
++	ODP_Context_t *odpc = (ODP_Context_t *) handle;
++
++	memcpy(stats, &odpc->stats, sizeof(DAQ_Stats_t));
++	return DAQ_SUCCESS;
++}
++
++static void odp_daq_reset_stats(void *handle)
++{
++    //ODP_Context_t *odpc = (ODP_Context_t *) handle;
++}
++
++static int odp_daq_get_snaplen(void *handle)
++{
++    ODP_Context_t *odpc = (ODP_Context_t *) handle;
++
++    if (odpc)
++	return odpc->snaplen;
++
++    return 1500;
++}
++
++static uint32_t odp_daq_get_capabilities(void *handle)
++{
++    return DAQ_CAPA_BLOCK | DAQ_CAPA_REPLACE | DAQ_CAPA_INJECT | /*DAQ_CAPA_UNPRIV_START |*/ DAQ_CAPA_BREAKLOOP | DAQ_CAPA_BPF | DAQ_CAPA_DEVICE_INDEX;
++}
++
++static int odp_daq_get_datalink_type(void *handle)
++{
++    return DLT_EN10MB;
++}
++
++static const char *odp_daq_get_errbuf(void *handle)
++{
++	ODP_Context_t *odpc = (ODP_Context_t *) handle;
++
++	return odpc->errbuf;
++}
++
++static void odp_daq_set_errbuf(void *handle, const char *string)
++{
++    ODP_Context_t *odpc = (ODP_Context_t *) handle;
++
++    if (!string)
++        return;
++
++    DPE(odpc->errbuf, "%s", string);
++    return;
++}
++
++static int odp_daq_get_device_index(void *handle, const char *string)
++{
++    return DAQ_ERROR_NOTSUP;
++}
++
++#ifdef BUILDING_SO
++DAQ_SO_PUBLIC const DAQ_Module_t DAQ_MODULE_DATA =
++#else
++const DAQ_Module_t afpacket_daq_module_data =
++#endif
++{
++    .api_version = DAQ_API_VERSION,
++    .module_version = 1,
++    .name = "odp",
++    .type = DAQ_TYPE_INTF_CAPABLE | DAQ_TYPE_INLINE_CAPABLE | DAQ_TYPE_MULTI_INSTANCE,
++    .initialize = odp_daq_initialize,
++    .set_filter = odp_daq_set_filter,
++    .start = odp_daq_start,
++    .acquire = odp_daq_acquire,
++    .inject = odp_daq_inject,
++    .breakloop = odp_daq_breakloop,
++    .stop = odp_daq_stop,
++    .shutdown = odp_daq_shutdown,
++    .check_status = odp_daq_check_status,
++    .get_stats = odp_daq_get_stats,
++    .reset_stats = odp_daq_reset_stats,
++    .get_snaplen = odp_daq_get_snaplen,
++    .get_capabilities = odp_daq_get_capabilities,
++    .get_datalink_type = odp_daq_get_datalink_type,
++    .get_errbuf = odp_daq_get_errbuf,
++    .set_errbuf = odp_daq_set_errbuf,
++    .get_device_index = odp_daq_get_device_index,
++    .modify_flow = NULL,
++    .hup_prep = NULL,
++    .hup_apply = NULL,
++    .hup_post = NULL,
++};
+-- 
+1.8.5.1.163.gd7aced9
+
--- /dev/null
+++ b/snort/download/daq-2.0.2.tar.gz.md5
@@ -0,0 +1 @@
+865bf9b750a2a2ca632591a3c70b0ea0
\ No newline at end of file
--- /dev/null
+++ b/snort/lib-patches/0001-Compile-Snort-as-static-library.patch
@@ -0,0 +1,114 @@
+From 3e23b5c31acc1759b1ed2aabd518964390f16c89 Mon Sep 17 00:00:00 2001
+From: Maxim Uvarov <maxim.uvarov@linaro.org>
+Date: Wed, 16 Apr 2014 18:15:29 +0400
+Subject: [PATCH 1/2] Compile Snort as static library
+
+Compile Snort as static library to use it's analyze functions
+in other applications.
+Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
+---
+ src/Makefile.am |   40 +++++++++++++++++++++-------------------
+ src/snort.c     |    8 ++------
+ 2 files changed, 23 insertions(+), 25 deletions(-)
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 1c1f826..f683dee 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -1,13 +1,13 @@
+ ## $Id$
+ AUTOMAKE_OPTIONS=foreign no-dependencies
+ 
+-bin_PROGRAMS = snort
++noinst_LIBRARIES = libsnort.a
+ 
+ if BUILD_SNPRINTF
+ SNPRINTF_SOURCES = snprintf.c snprintf.h
+ endif
+ 
+-snort_SOURCES = cdefs.h \
++libsnort_a_SOURCES = cdefs.h \
+ event.h \
+ generators.h \
+ sf_protocols.h \
+@@ -62,20 +62,6 @@ rule_option_types.h \
+ sfdaq.c sfdaq.h \
+ idle_processing.c idle_processing.h idle_processing_funcs.h
+ 
+-snort_LDADD = output-plugins/libspo.a \
+-detection-plugins/libspd.a            \
+-dynamic-plugins/libdynamic.a            \
+-dynamic-output/plugins/liboutput.a      \
+-preprocessors/libspp.a                \
+-parser/libparser.a \
+-target-based/libtarget_based.a \
+-preprocessors/HttpInspect/libhttp_inspect.a \
+-preprocessors/Stream5/libstream5.a \
+-sfutil/libsfutil.a \
+-control/libsfcontrol.a \
+-file-process/libfileAPI.a \
+-file-process/libs/libfile.a
+-
+ if BUILD_DYNAMIC_EXAMPLES
+ EXAMPLES_DIR = dynamic-examples
+ endif
+@@ -85,9 +71,25 @@ SUBDIRS = sfutil win32 output-plugins detection-plugins dynamic-plugins preproce
+ 
+ INCLUDES = @INCLUDES@
+ 
++libsnort_a_LIBADD = $(wildcard output-plugins/*.o) \
++$(wildcard detection-plugins/*.o)            \
++$(wildcard dynamic-plugins/*.o)            \
++$(wildcard dynamic-output/plugins/*.o)      \
++$(wildcard dynamic-output/*/*.o)      \
++$(wildcard preprocessors/*.o)                \
++$(wildcard parser/*.o) \
++$(wildcard target-based/*.o) \
++$(wildcard preprocessors/HttpInspect/*/*.o) \
++$(wildcard preprocessors/Stream5/*.o) \
++$(wildcard sfutil/*.o) \
++$(wildcard control/*.o) \
++$(wildcard file-process/*.o) \
++$(wildcard file-process/libs/*.o)
++
++
+ if BUILD_SIDE_CHANNEL
+-snort_LDADD += \
+-side-channel/libsidechannel.a \
+-side-channel/plugins/libsscm.a
++libsnort_a_LIBADD += \
++$(wildcard side-channel/*.o) \
++$(wildcard side-channel/plugins/*.o)
+ SUBDIRS += side-channel
+ endif
+diff --git a/src/snort.c b/src/snort.c
+index 0280107..ce5c52e 100644
+--- a/src/snort.c
++++ b/src/snort.c
+@@ -775,14 +775,9 @@ static int InlineFailOpen (void)
+  * Returns: 0 => normal exit, 1 => exit on error
+  *
+  */
++#if 0
+ int main(int argc, char *argv[])
+ {
+-	/* hack to add deps to -lrt for timer_create() and friends from odp */
+-	static volatile int link_rt = 0;
+-	timer_t timerid = 0;
+-	if (link_rt)
+-		timer_settime(timerid, 0, NULL, NULL);
+-
+ #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
+     /* Do some sanity checking, because some people seem to forget to
+      * put spaces between their parameters
+@@ -808,6 +803,7 @@ int main(int argc, char *argv[])
+ 
+     return SnortMain(argc, argv);
+ }
++#endif
+ 
+ /*
+  *
+-- 
+1.7.9.5
+
--- /dev/null
+++ b/snort/lib-patches/0002-remove-static-from-needed-functions.patch
@@ -0,0 +1,73 @@
+From 71aeb1a6bbda6464b717565aa4a1e3126cb59f1c Mon Sep 17 00:00:00 2001
+From: Maxim Uvarov <maxim.uvarov@linaro.org>
+Date: Wed, 16 Apr 2014 18:16:57 +0400
+Subject: [PATCH 2/2] remove static from needed functions
+
+Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
+---
+ src/snort.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/src/snort.c b/src/snort.c
+index ce5c52e..5e5060a 100644
+--- a/src/snort.c
++++ b/src/snort.c
+@@ -485,7 +485,7 @@ static void InitProtoNames(void);
+ static const char* GetPacketSource(char**);
+ 
+ static void CleanExit(int);
+-static void SnortInit(int, char **);
++void SnortInit(int, char **);
+ static void InitPidChrootAndPrivs(pid_t);
+ static void ParseCmdLine(int, char **);
+ static int ShowUsage(char *);
+@@ -515,8 +515,8 @@ static void FreeReferences(ReferenceSystemNode *);
+ static void FreePlugins(SnortConfig *);
+ static void FreePreprocessors(SnortConfig *);
+ 
+-static void SnortUnprivilegedInit(void);
+-static int SetPktProcessor(void);
++void SnortUnprivilegedInit(void);
++int SetPktProcessor(void);
+ static void PacketLoop(void);
+ #if 0
+ static char * ConfigFileSearch(void);
+@@ -1618,7 +1618,7 @@ static Packet s_packet;
+ static DAQ_PktHdr_t s_pkth;
+ static uint8_t s_data[65536];
+ 
+-static DAQ_Verdict PacketCallback(
++/*static*/ DAQ_Verdict PacketCallback(
+     void* user, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt)
+ {
+     int inject = 0;
+@@ -1779,7 +1779,7 @@ static DAQ_Verdict PacketCallback(
+     return verdict;
+ }
+ 
+-static void PrintPacket(Packet *p)
++void PrintPacket(Packet *p)
+ {
+     if (p->iph != NULL)
+     {
+@@ -2989,7 +2989,7 @@ static void ParseCmdLine(int argc, char **argv)
+  */
+ // TBD add GetDecoder(dlt) to decode module and hide all
+ // protocol decoder functions.
+-static int SetPktProcessor(void)
++int SetPktProcessor(void)
+ {
+     const char* slink = NULL;
+     const char* extra = NULL;
+@@ -5162,7 +5162,7 @@ static DAQ_Verdict IgnoreCallback (
+ // packet passing is done by the driver/hardware.  the goal then is to put as
+ // much initialization stuff in SnortInit() as possible and to restrict this
+ // function to those things that depend on DAQ startup or non-root user/group.
+-static void SnortUnprivilegedInit(void)
++void SnortUnprivilegedInit(void)
+ {
+ #ifdef ACTIVE_RESPONSE
+     // this depends on instantiated daq capabilities
+-- 
+1.7.9.5
+
--- /dev/null
+++ b/snort/odp-patches/0001-implement-odp_timer_disarm_all.patch
@@ -0,0 +1,63 @@
+From 943e815797f886580354f050e7316306c032335c Mon Sep 17 00:00:00 2001
+From: Maxim Uvarov <maxim.uvarov@linaro.org>
+Date: Wed, 9 Apr 2014 20:38:13 +0400
+Subject: [ODP/PATCH] implement odp_timer_disarm_all()
+
+Implement function to disarm all timers. Needed in case of
+normal exit from application.
+Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
+---
+ platform/linux-generic/include/odp_internal.h |  1 +
+ platform/linux-generic/source/odp_timer.c     | 24 ++++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
+index fb3be79..9b0769e 100644
+--- a/platform/linux-generic/include/odp_internal.h
++++ b/platform/linux-generic/include/odp_internal.h
+@@ -38,6 +38,7 @@ int odp_schedule_init_global(void);
+ int odp_schedule_init_local(void);
+ 
+ int odp_timer_init_global(void);
++int odp_timer_disarm_all(void);
+ 
+ #ifdef __cplusplus
+ }
+diff --git a/platform/linux-generic/source/odp_timer.c b/platform/linux-generic/source/odp_timer.c
+index 6fb5025..98ffde3 100644
+--- a/platform/linux-generic/source/odp_timer.c
++++ b/platform/linux-generic/source/odp_timer.c
+@@ -217,6 +217,30 @@ int odp_timer_init_global(void)
+ 	return 0;
+ }
+ 
++int odp_timer_disarm_all(void)
++{
++	int timers;
++	struct itimerspec ispec;
++
++	timers = odp_atomic_load_int(&odp_timer.num_timers);
++
++	ispec.it_interval.tv_sec  = 0;
++	ispec.it_interval.tv_nsec = 0;
++	ispec.it_value.tv_sec     = 0;
++	ispec.it_value.tv_nsec    = 0;
++
++	for (; timers >= 0; timers--) {
++		if (timer_settime(odp_timer.timer[timers].timerid,
++				  0, &ispec, NULL)) {
++			ODP_DBG("Timer reset failed\n");
++			return -1;
++		}
++		odp_atomic_fetch_sub_int(&odp_timer.num_timers, 1);
++	}
++
++	return 0;
++}
++
+ odp_timer_t odp_timer_create(const char *name, odp_buffer_pool_t pool,
+ 			     uint64_t resolution, uint64_t min_tmo,
+ 			     uint64_t max_tmo)
+-- 
+1.8.5.1.163.gd7aced9
+
--- /dev/null
+++ b/snort/odpsnort/Makefile
@@ -0,0 +1,47 @@
+SNORT=$(PWD)/../snort-2.9.6.0-lib
+CFLAGS += -I/$(SNORT)/src
+LDFLAGS += -L/$(SNORT)/src
+LDFLAGS += -L/$(SNORT)/src/dynamic-plugins
+
+DAQ=$(PWD)/../daq-2.0.2
+DAQ_LIB_DIR = "$(DAQ)/api/.libs"
+LDFLAGS += "-L$(DAQ_LIB_DIR)"
+
+DAQ_LIB = "$(DAQ)/api/.libs/libdaq.a"
+
+DNET_LIB_DIR = "/usr/local/lib"
+LDFLAGS += "-L$(DNET_LIB_DIR)"
+
+INC = "-I$(SNORT)/src/sfutil"
+INC += "-I$(SNORT)/src/preprocessors"
+INC += "-I$(SNORT)/src/dynamic-preprocessors/include"
+INC += "-I$(SNORT)/src/detection-plugins"
+INC += "-I$(SNORT)/src/target-based"
+INC += "-I$(SNORT)/src/control"
+INC += "-I$(SNORT)/src/file-process"
+INC += "-I$(SNORT)/src/file-process/libs"
+INC += "-I$(SNORT)/src/preprocessors/Stream5"
+INC += "-I$(SNORT)"
+
+ODP_DIR = $(PWD)/../../odp.git
+ODP_LIB = $(ODP_DIR)/build/lib/libodp.a
+ODP_CFLAGS += -I$(ODP_DIR)/include
+ODP_CFLAGS += -I$(ODP_DIR)/platform/linux-generic/include
+ODP_CFLAGS += -I$(ODP_DIR)/platform/linux-generic/include/api
+
+LDFLAGS += $(ODP_LIB)
+
+DAQ = $(PWD)/../daq-2.0.2
+ODP_CFLAGS += -I$(DAQ)
+
+all:
+	gcc -c -O0 -g snort.c ${CFLAGS} ${LDFLAGS} $(INC) -o snort.o
+	gcc -c -O0 -g -pthread $(ODP_CFLAGS)  odp_pktio.c -o odp_pktio.o
+	gcc snort.o odp_pktio.o ${CFLAGS} ${LDFLAGS} $(INC) -g -O0 -lsnort -lz -lpcap -pthread -lpcre -lssl -lcrypto -lm -ldnet ${DAQ_LIB} -lrt -o odp-snort
+
+clean:
+	rm -rf odp-snort *.o
+run:
+	export LD_LIBRARY_PATH="/usr/local/lib";./odp-snort -i eth0
+
+
--- /dev/null
+++ b/snort/odpsnort/odp_pktio.c
@@ -0,0 +1,673 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * @example odp_example_pktio.c  ODP basic packet IO loopback test application
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#include <odp.h>
+#include <helper/odp_linux.h>
+#include <helper/odp_packet_helper.h>
+#include <helper/odp_eth.h>
+#include <helper/odp_ip.h>
+
+/* Snort */
+#include <api/daq_common.h>
+
+#define MAX_WORKERS            32
+#define SHM_PKT_POOL_SIZE      (512*2048)
+#define SHM_PKT_POOL_BUF_SIZE  1856
+#define MAX_PKT_BURST          16
+
+#define APPL_MODE_PKT_BURST    0
+#define APPL_MODE_PKT_QUEUE    1
+
+#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x))
+
+/** Get rid of path in filename - only for unix-type paths using '/' */
+#define NO_PATH(file_name) (strrchr((file_name), '/') ? \
+			    strrchr((file_name), '/') + 1 : (file_name))
+/**
+ * Parsed command line application arguments
+ */
+typedef struct {
+	int core_count;
+	int if_count;		/**< Number of interfaces to be used */
+	char **if_names;	/**< Array of pointers to interface names */
+	int mode;		/**< Packet IO mode */
+	int type;		/**< Packet IO type */
+	int fanout;		/**< Packet IO fanout */
+	odp_buffer_pool_t pool;	/**< Buffer pool for packet IO */
+} appl_args_t;
+
+/**
+ * Thread specific arguments
+ */
+typedef struct {
+	char *pktio_dev;	/**< Interface name to use */
+	odp_buffer_pool_t pool;	/**< Buffer pool for packet IO */
+	int mode;		/**< Thread mode */
+	int type;		/**< Thread i/o type */
+	int fanout;		/**< Thread i/o fanout */
+} thread_args_t;
+
+/**
+ * Grouping of both parsed CL args and thread specific args - alloc together
+ */
+typedef struct {
+	/** Application (parsed) arguments */
+	appl_args_t appl;
+	/** Thread specific arguments */
+	thread_args_t thread[MAX_WORKERS];
+} args_t;
+
+/** Global pointer to args */
+static args_t *args;
+
+/* helper funcs */
+static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
+static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len);
+static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
+static void print_info(char *progname, appl_args_t *appl_args);
+static void usage(char *progname);
+
+static void analyze_packet_in_snort(odp_packet_t pkt, int thr)
+{
+	DAQ_PktHdr_t daqhdr;
+	const uint8_t *data;
+	DAQ_Verdict verd;
+
+	data = odp_packet_l2(pkt);
+	if (!data) {
+		printf("no l2 offset, packet dropped\n");
+		return;
+	}
+
+	gettimeofday(&daqhdr.ts, NULL);
+	daqhdr.caplen = odp_buffer_size(pkt);
+	printf("%s() odp recieved packet len %d. thread %d\n", __func__, odp_packet_get_len(pkt), thr);
+	daqhdr.pktlen = odp_packet_get_len(pkt);
+	daqhdr.ingress_index = 0;
+	daqhdr.egress_index =  DAQ_PKTHDR_UNKNOWN;
+	daqhdr.ingress_group = DAQ_PKTHDR_UNKNOWN;
+	daqhdr.egress_group = DAQ_PKTHDR_UNKNOWN;
+	daqhdr.flags = 0;
+	daqhdr.opaque = 0;
+	daqhdr.priv_ptr = NULL;
+	daqhdr.address_space_id = 0;
+
+	/* Pass packet to Snort */
+	verd = PacketCallback( "NULL", daqhdr, data);
+	return;
+}
+
+/**
+ * Packet IO loopback worker thread using ODP queues
+ *
+ * @param arg  thread arguments of type 'thread_args_t *'
+ */
+static void *pktio_queue_thread(void *arg)
+{
+	int thr;
+	odp_buffer_pool_t pkt_pool;
+	odp_pktio_t pktio;
+	thread_args_t *thr_args;
+	odp_queue_t outq_def;
+	odp_queue_t inq_def;
+	char inq_name[ODP_QUEUE_NAME_LEN];
+	odp_queue_param_t qparam;
+	odp_packet_t pkt;
+	odp_buffer_t buf;
+	int ret;
+	unsigned long pkt_cnt = 0;
+	unsigned long err_cnt = 0;
+	odp_pktio_params_t params;
+	socket_params_t *sock_params = &params.sock_params;
+
+	thr = odp_thread_id();
+	thr_args = arg;
+
+	printf("Pktio thread [%02i] starts, pktio_dev:%s\n", thr,
+	       thr_args->pktio_dev);
+
+	/* Lookup the packet pool */
+	pkt_pool = odp_buffer_pool_lookup("packet_pool");
+	if (pkt_pool == ODP_BUFFER_POOL_INVALID) {
+		ODP_ERR("  [%02i] Error: pkt_pool not found\n", thr);
+		return NULL;
+	}
+
+	/* Open a packet IO instance for this thread */
+	sock_params->type = ODP_PKTIO_TYPE_SOCKET_BASIC;
+	sock_params->fanout = 0;
+	pktio = odp_pktio_open(thr_args->pktio_dev, pkt_pool, &params);
+	if (pktio == ODP_PKTIO_INVALID) {
+		ODP_ERR("  [%02i] Error: pktio create failed\n", thr);
+		return NULL;
+	}
+
+	/*
+	 * Create and set the default INPUT queue associated with the 'pktio'
+	 * resource
+	 */
+	qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
+	qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
+	qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
+	snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio);
+	inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
+
+	inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
+	if (inq_def == ODP_QUEUE_INVALID) {
+		ODP_ERR("  [%02i] Error: pktio queue creation failed\n", thr);
+		return NULL;
+	}
+
+	ret = odp_pktio_inq_setdef(pktio, inq_def);
+	if (ret != 0) {
+		ODP_ERR("  [%02i] Error: default input-Q setup\n", thr);
+		return NULL;
+	}
+
+	printf("  [%02i] created pktio:%02i, queue mode (ATOMIC queues)\n"
+	       "          default pktio%02i-INPUT queue:%u\n",
+		thr, pktio, pktio, inq_def);
+
+	/* Loop packets */
+	for (;;) {
+		odp_pktio_t pktio_tmp;
+
+#if 1
+		/* Use schedule to get buf from any input queue */
+		buf = odp_schedule(NULL, ODP_SCHED_WAIT);
+#else
+		/* Always dequeue from the same input queue */
+		buf = odp_queue_deq(inq_def);
+#endif
+
+		if (!odp_buffer_is_valid(buf))
+			continue;
+
+		pkt = odp_packet_from_buffer(buf);
+
+		analyze_packet_in_snort(pkt, thr);
+
+#if 0
+		/* Print packet counts every once in a while */
+		if (odp_unlikely(pkt_cnt++ % 100000 == 0)) {
+			printf("  [%02i] pkt_cnt:%lu\n", thr, pkt_cnt);
+			fflush(NULL);
+		}
+#endif
+	}
+
+/* unreachable */
+}
+
+/**
+ * Packet IO loopback worker thread using bursts from/to IO resources
+ *
+ * @param arg  thread arguments of type 'thread_args_t *'
+ */
+static void *pktio_ifburst_thread(void *arg)
+{
+	int thr;
+	odp_buffer_pool_t pkt_pool;
+	odp_pktio_t pktio;
+	thread_args_t *thr_args;
+	int pkts, pkts_ok;
+	odp_packet_t pkt_tbl[MAX_PKT_BURST];
+	unsigned long pkt_cnt = 0;
+	unsigned long err_cnt = 0;
+	unsigned long tmp = 0;
+	odp_pktio_params_t params;
+	socket_params_t *sock_params = &params.sock_params;
+
+	thr = odp_thread_id();
+	thr_args = arg;
+
+	printf("Pktio thread [%02i] starts, pktio_dev:%s\n", thr,
+	       thr_args->pktio_dev);
+
+	/* Lookup the packet pool */
+	pkt_pool = odp_buffer_pool_lookup("packet_pool");
+	if (pkt_pool == ODP_BUFFER_POOL_INVALID || pkt_pool != thr_args->pool) {
+		ODP_ERR("  [%02i] Error: pkt_pool not found\n", thr);
+		return NULL;
+	}
+
+	/* Open a packet IO instance for this thread */
+	sock_params->type = thr_args->type;
+	sock_params->fanout = thr_args->fanout;
+	pktio = odp_pktio_open(thr_args->pktio_dev, pkt_pool, &params);
+	if (pktio == ODP_PKTIO_INVALID) {
+		ODP_ERR("  [%02i] Error: pktio create failed.\n", thr);
+		return NULL;
+	}
+
+	printf("  [%02i] created pktio:%02i, burst mode\n",
+	       thr, pktio);
+
+	/* Loop packets */
+	for (;;) {
+		pkts = odp_pktio_recv(pktio, pkt_tbl, MAX_PKT_BURST);
+		if (pkts > 0) {
+			/* Drop packets with errors */
+			pkts_ok = drop_err_pkts(pkt_tbl, pkts);
+			if (pkts_ok > 0) {
+				/* Swap Eth MACs and IP-addrs */
+				swap_pkt_addrs(pkt_tbl, pkts_ok);
+				odp_pktio_send(pktio, pkt_tbl, pkts_ok);
+			}
+
+			if (odp_unlikely(pkts_ok != pkts))
+				ODP_ERR("Dropped frames:%u - err_cnt:%lu\n",
+					pkts-pkts_ok, ++err_cnt);
+
+			/* Print packet counts every once in a while */
+			tmp += pkts_ok;
+			if (odp_unlikely((tmp >= 100000) || /* OR first print:*/
+			    ((pkt_cnt == 0) && ((tmp-1) < MAX_PKT_BURST)))) {
+				pkt_cnt += tmp;
+				printf("  [%02i] pkt_cnt:%lu\n", thr, pkt_cnt);
+				fflush(NULL);
+				tmp = 0;
+			}
+		}
+	}
+
+/* unreachable */
+}
+
+/**
+ * ODP packet example main function
+ */
+int do_odp_init(int argc, char *argv[])
+{
+
+	odp_buffer_pool_t pool;
+	int thr_id;
+	void *pool_base;
+	int i;
+	int first_core;
+
+
+	/* Init ODP before calling anything else */
+	if (odp_init_global()) {
+		ODP_ERR("Error: ODP global init failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	/* Reserve memory for args from shared mem */
+	args = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE);
+	if (args == NULL) {
+		ODP_ERR("Error: shared mem alloc failed.\n");
+		exit(EXIT_FAILURE);
+	}
+	memset(args, 0, sizeof(*args));
+
+	/* Parse and store the application arguments */
+	//parse_args(argc, argv, &args->appl);
+	args->appl.core_count = 1;
+	args->appl.if_count = 1;
+	args->appl.if_names = calloc(args->appl.if_count, sizeof(char *));
+	args->appl.if_names[0] = strdup("eth0");
+
+	args->appl.fanout = 0;
+	args->appl.mode = APPL_MODE_PKT_QUEUE; 
+
+	/* Print both system and application information */
+	print_info(NO_PATH(argv[0]), &args->appl);
+
+	/* Init this thread */
+	thr_id = odp_thread_create(0);
+	odp_init_local(thr_id);
+
+	/* Create packet pool */
+	pool_base = odp_shm_reserve("shm_packet_pool",
+				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE);
+	if (pool_base == NULL) {
+		ODP_ERR("Error: packet pool mem alloc failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	pool = odp_buffer_pool_create("packet_pool", pool_base,
+				      SHM_PKT_POOL_SIZE,
+				      SHM_PKT_POOL_BUF_SIZE,
+				      ODP_CACHE_LINE_SIZE,
+				      ODP_BUFFER_TYPE_PACKET);
+	if (pool == ODP_BUFFER_POOL_INVALID) {
+		ODP_ERR("Error: packet pool create failed.\n");
+		exit(EXIT_FAILURE);
+	}
+	odp_buffer_pool_print(pool);
+
+	return 0;
+}
+
+void odp_snort_run_threads(void)
+{
+	odp_linux_pthread_t thread_tbl[MAX_WORKERS];
+	int i;
+	int core_count;
+	int num_workers;
+	int first_core;
+
+	core_count  = odp_sys_core_count();
+	num_workers = core_count;
+
+	/*
+	 * By default core #0 runs Linux kernel background tasks.
+	 * Start mapping thread from core #1
+	 */
+	first_core = 1;
+
+	if (core_count == 1)
+		first_core = 0;
+
+	printf("First core:         %i\n\n", first_core);
+
+	if (args->appl.core_count)
+		num_workers = args->appl.core_count;
+
+	if (num_workers > MAX_WORKERS)
+		num_workers = MAX_WORKERS;
+
+	printf("Num worker threads: %i\n", num_workers);
+
+	/* Create and init worker threads */
+	memset(thread_tbl, 0, sizeof(thread_tbl));
+	for (i = 0; i < num_workers; ++i) {
+		void *(*thr_run_func) (void *);
+		int core;
+		int if_idx;
+
+		core = (first_core + i) % core_count;
+
+		if_idx = i % args->appl.if_count;
+
+		args->thread[i].pktio_dev = args->appl.if_names[if_idx];
+		args->thread[i].mode = args->appl.mode;
+		args->thread[i].type = args->appl.type;
+		args->thread[i].fanout = args->appl.fanout;
+
+		if (args->appl.mode == APPL_MODE_PKT_BURST)
+			thr_run_func = pktio_ifburst_thread;
+		else /* APPL_MODE_PKT_QUEUE */
+			thr_run_func = pktio_queue_thread;
+		/*
+		 * Create threads one-by-one instead of all-at-once,
+		 * because each thread might get different arguments.
+		 * Calls odp_thread_create(cpu) for each thread
+		 */
+		odp_linux_pthread_create(thread_tbl, 1, core, thr_run_func,
+					 &args->thread[i]);
+	}
+
+	/* Master thread waits for other threads to exit */
+	odp_linux_pthread_join(thread_tbl, num_workers);
+	printf("Exit\n\n");
+}
+
+
+/**
+ * Drop packets which input parsing marked as containing errors.
+ *
+ * Frees packets with error and modifies pkt_tbl[] to only contain packets with
+ * no detected errors.
+ *
+ * @param pkt_tbl  Array of packet
+ * @param len      Length of pkt_tbl[]
+ *
+ * @return Number of packets with no detected error
+ */
+static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len)
+{
+	odp_packet_t pkt;
+	unsigned pkt_cnt = len;
+	unsigned i, j;
+
+	for (i = 0, j = 0; i < len; ++i) {
+		pkt = pkt_tbl[i];
+
+		if (odp_unlikely(odp_packet_error(pkt))) {
+			odp_packet_free(pkt); /* Drop */
+			pkt_cnt--;
+		} else if (odp_unlikely(i != j++)) {
+			pkt_tbl[j] = pkt;
+		}
+	}
+
+	return pkt_cnt;
+}
+
+/**
+ * Swap eth src<->dst and IP src<->dst addresses
+ *
+ * @param pkt_tbl  Array of packets
+ * @param len      Length of pkt_tbl[]
+ */
+
+static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len)
+{
+	odp_packet_t pkt;
+	odp_ethhdr_t *eth;
+	odp_ethaddr_t tmp_addr;
+	odp_ipv4hdr_t *ip;
+	uint32be_t ip_tmp_addr; /* tmp ip addr */
+	unsigned i;
+
+	for (i = 0; i < len; ++i) {
+		pkt = pkt_tbl[i];
+		if (odp_packet_inflag_eth(pkt)) {
+			eth = (odp_ethhdr_t *)odp_packet_l2(pkt);
+
+			tmp_addr = eth->dst;
+			eth->dst = eth->src;
+			eth->src = tmp_addr;
+
+			if (odp_packet_inflag_ipv4(pkt)) {
+				/* IPv4 */
+				ip = (odp_ipv4hdr_t *)odp_packet_l3(pkt);
+
+				ip_tmp_addr  = ip->src_addr;
+				ip->src_addr = ip->dst_addr;
+				ip->dst_addr = ip_tmp_addr;
+			}
+		}
+	}
+}
+
+/**
+ * Parse and store the command line arguments
+ *
+ * @param argc       argument count
+ * @param argv[]     argument vector
+ * @param appl_args  Store application arguments here
+ */
+static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
+{
+	int opt;
+	int long_index;
+	char *names, *str, *token, *save;
+	size_t len;
+	int i;
+	static struct option longopts[] = {
+		{"count", required_argument, NULL, 'c'},
+		{"interface", required_argument, NULL, 'i'},	/* return 'i' */
+		{"mode", required_argument, NULL, 'm'},		/* return 'm' */
+		{"help", no_argument, NULL, 'h'},		/* return 'h' */
+		{NULL, 0, NULL, 0}
+	};
+
+	appl_args->mode = -1; /* Invalid, must be changed by parsing */
+	appl_args->type = 3;  /* 3: ODP_PKTIO_TYPE_SOCKET_MMAP */
+	appl_args->fanout = 1; /* turn off fanout by default for mmap */
+
+	for (i = 0; i < argc; i++)
+		printf("argv %s\n", argv[i]);
+
+	while (1) {
+		opt = getopt_long(argc, argv, "+c:i:m:t:f:h",
+				  longopts, &long_index);
+
+		printf("opt %d\n", opt);
+		if (opt == -1)
+			break;	/* No more options */
+
+		switch (opt) {
+		case 'c':
+			appl_args->core_count = atoi(optarg);
+			break;
+			/* parse packet-io interface names */
+		case 'i':
+			len = strlen(optarg);
+			if (len == 0) {
+				usage(argv[0]);
+				exit(EXIT_FAILURE);
+			}
+			len += 1;	/* add room for '\0' */
+
+			names = malloc(len);
+			if (names == NULL) {
+				usage(argv[0]);
+				exit(EXIT_FAILURE);
+			}
+
+			/* count the number of tokens separated by ',' */
+			strcpy(names, optarg);
+			for (str = names, i = 0;; str = NULL, i++) {
+				token = strtok_r(str, ",", &save);
+				if (token == NULL)
+					break;
+			}
+			appl_args->if_count = i;
+
+			if (appl_args->if_count == 0) {
+				usage(argv[0]);
+				exit(EXIT_FAILURE);
+			}
+
+			/* allocate storage for the if names */
+			appl_args->if_names =
+			    calloc(appl_args->if_count, sizeof(char *));
+
+			/* store the if names (reset names string) */
+			strcpy(names, optarg);
+			for (str = names, i = 0;; str = NULL, i++) {
+				token = strtok_r(str, ",", &save);
+				if (token == NULL)
+					break;
+				appl_args->if_names[i] = token;
+			}
+			break;
+
+		case 'm':
+			i = atoi(optarg);
+			if (i == 0)
+				appl_args->mode = APPL_MODE_PKT_BURST;
+			else
+				appl_args->mode = APPL_MODE_PKT_QUEUE;
+			break;
+
+		case 't':
+			appl_args->type = atoi(optarg);
+			break;
+
+		case 'f':
+			appl_args->fanout = atoi(optarg);
+			break;
+
+		case 'h':
+			usage(argv[0]);
+			exit(EXIT_SUCCESS);
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (appl_args->if_count == 0 || appl_args->mode == -1) {
+		usage(argv[0]);
+		printf("unable to parse odp args if_count %d mode %d\n", 
+				appl_args->if_count, appl_args->mode);
+		exit(EXIT_FAILURE);
+	}
+
+	optind = 1;		/* reset 'extern optind' from the getopt lib */
+}
+
+/**
+ * Print system and application info
+ */
+static void print_info(char *progname, appl_args_t *appl_args)
+{
+	int i;
+
+	printf("\n"
+	       "ODP system info\n"
+	       "---------------\n"
+	       "ODP API version: %s\n"
+	       "CPU model:       %s\n"
+	       "CPU freq (hz):   %"PRIu64"\n"
+	       "Cache line size: %i\n"
+	       "Core count:      %i\n"
+	       "\n",
+	       odp_version_api_str(), odp_sys_cpu_model_str(), odp_sys_cpu_hz(),
+	       odp_sys_cache_line_size(), odp_sys_core_count());
+
+	printf("Running ODP appl: \"%s\"\n"
+	       "-----------------\n"
+	       "IF-count:        %i\n"
+	       "Using IFs:      ",
+	       progname, appl_args->if_count);
+	for (i = 0; i < appl_args->if_count; ++i)
+		printf(" %s", appl_args->if_names[i]);
+	printf("\n"
+	       "Mode:            ");
+	if (appl_args->mode == APPL_MODE_PKT_BURST)
+		PRINT_APPL_MODE(APPL_MODE_PKT_BURST);
+	else
+		PRINT_APPL_MODE(APPL_MODE_PKT_QUEUE);
+	printf("\n\n");
+	fflush(NULL);
+}
+
+/**
+ * Prinf usage information
+ */
+static void usage(char *progname)
+{
+	printf("\n"
+	       "Usage: %s OPTIONS\n"
+	       "  E.g. %s -i eth1,eth2,eth3 -m 0\n"
+	       "\n"
+	       "OpenDataPlane example application.\n"
+	       "\n"
+	       "Mandatory OPTIONS:\n"
+	       "  -i, --interface Eth interfaces (comma-separated, no spaces)\n"
+	       "  -m, --mode      0: Burst send&receive packets (no queues)\n"
+	       "                  1: Send&receive packets through ODP queues.\n"
+	       " -t, --type   1: ODP_PKTIO_TYPE_SOCKET_BASIC\n"
+	       "	      2: ODP_PKTIO_TYPE_SOCKET_MMSG\n"
+	       "	      3: ODP_PKTIO_TYPE_SOCKET_MMAP\n"
+	       "	      4: ODP_PKTIO_TYPE_NETMAP\n"
+	       "	 Default: 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n"
+	       " -f, --fanout 0: off 1: on (Default 1: on)\n"
+	       "\n"
+	       "Optional OPTIONS\n"
+	       "  -c, --count <number> Core count.\n"
+	       "  -h, --help           Display help and exit.\n"
+	       "\n", NO_PATH(progname), NO_PATH(progname)
+	    );
+}
--- /dev/null
+++ b/snort/odpsnort/odp_pktio.h
@@ -0,0 +1 @@
+int do_odp_init(int argc, char *argv[]);
--- /dev/null
+++ b/snort/odpsnort/snort.c
@@ -0,0 +1,5095 @@
+/* $Id$ */
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+** Copyright (C) 2002-2013 Sourcefire, Inc.
+** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+/*
+ *
+ * Program: Snort
+ *
+ * Purpose: Check out the README file for info on what you can do
+ *          with Snort.
+ *
+ * Author: Martin Roesch (roesch@clark.net)
+ *
+ * Comments: Ideas and code stolen liberally from Mike Borella's IP Grab
+ *           program. Check out his stuff at http://www.borella.net.  I
+ *           also have ripped some util functions from TCPdump, plus Mike's
+ *           prog is derived from it as well.  All hail TCPdump....
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <pcap.h>
+#ifdef HAVE_MALLOC_TRIM
+#include <malloc.h>
+#endif
+
+#ifndef WIN32
+#include <netdb.h>
+#else
+#include <Iphlpapi.h>
+#endif
+
+#ifdef HAVE_GETOPT_LONG
+//#define _GNU_SOURCE
+/* A GPL copy of getopt & getopt_long src code is now in sfutil */
+# undef HAVE_GETOPT_LONG
+#endif
+#include <getopt.h>
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifndef WIN32
+# include <grp.h>
+# include <pwd.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif  /* !WIN32 */
+
+#if !defined(CATCH_SEGV) && !defined(WIN32)
+# include <sys/resource.h>
+#endif
+#include <pthread.h>
+
+#include "decode.h"
+#include "encode.h"
+#include "sfdaq.h"
+#include "active.h"
+#include "snort.h"
+#include "rules.h"
+#include "treenodes.h"
+#include "plugbase.h"
+#include "snort_debug.h"
+#include "util.h"
+#include "parser.h"
+#include "tag.h"
+#include "log.h"
+#include "detect.h"
+#include "mstring.h"
+#include "fpcreate.h"
+#include "fpdetect.h"
+#include "sfthreshold.h"
+#include "rate_filter.h"
+#include "packet_time.h"
+#include "detection-plugins/sp_flowbits.h"
+#include "preprocessors/spp_perfmonitor.h"
+#include "preprocessors/perf-base.h"
+#include "preprocessors/perf.h"
+#include "mempool.h"
+#include "strlcpyu.h"
+#include "sflsq.h"
+#include "sp_replace.h"
+#include "output-plugins/spo_log_tcpdump.h"
+#include "event_queue.h"
+#include "asn1.h"
+#include "mpse.h"
+#include "generators.h"
+#include "ppm.h"
+#include "profiler.h"
+#include "dynamic-plugins/sp_dynamic.h"
+#include "dynamic-plugins/sf_dynamic_define.h"
+#include "dynamic-output/plugins/output.h"
+#include "sfutil/strvec.h"
+#include "detection_util.h"
+#include "sfcontrol_funcs.h"
+#include "idle_processing_funcs.h"
+#include "file_service.h"
+#ifdef SIDE_CHANNEL
+# include "sidechannel.h"
+#endif
+
+#include "dynamic-plugins/sf_dynamic_engine.h"
+#include "dynamic-plugins/sf_dynamic_detection.h"
+#define PROFILE_PREPROCS_NOREDEF
+#include "dynamic-plugins/sf_dynamic_preprocessor.h"
+#include "dynamic-plugins/sp_preprocopt.h"
+#ifdef SIDE_CHANNEL
+# include "dynamic-plugins/sf_dynamic_side_channel.h"
+#endif
+
+#ifdef TARGET_BASED
+# include "target-based/sftarget_reader.h"
+#endif
+
+#ifdef EXIT_CHECK
+# include "cpuclock.h"
+#endif
+#include "sfActionQueue.h"
+
+#ifdef INTEL_SOFT_CPM
+#include "sfutil/intel-soft-cpm.h"
+#endif
+
+#include "stream5_common.h"
+#include "stream5_ha.h"
+
+#include "odp_pktio.h"
+
+/* Macros *********************************************************************/
+#ifndef DLT_LANE8023
+/*
+ * Old OPEN BSD Log format is 17.
+ * Define DLT_OLDPFLOG unless DLT_LANE8023 (Suse 6.3) is already
+ * defined in bpf.h.
+ */
+# define DLT_OLDPFLOG 17
+#endif
+
+#define ALERT_MODE_OPT__NONE       "none"
+#define ALERT_MODE_OPT__PKT_CNT    "packet-count"
+#define ALERT_MODE_OPT__FULL       "full"
+#define ALERT_MODE_OPT__FAST       "fast"
+#define ALERT_MODE_OPT__CONSOLE    "console"
+#define ALERT_MODE_OPT__CMG        "cmg"
+#define ALERT_MODE_OPT__JH         "jh"
+#define ALERT_MODE_OPT__DJR        "djr"
+#define ALERT_MODE_OPT__AJK        "ajk"
+#define ALERT_MODE_OPT__UNIX_SOCK  "unsock"
+#define ALERT_MODE_OPT__TEST       "test"
+
+#define LOG_MODE_OPT__NONE    "none"
+#define LOG_MODE_OPT__PCAP    "pcap"
+#define LOG_MODE_OPT__ASCII   "ascii"
+
+#ifdef MPLS
+# define MPLS_PAYLOAD_OPT__IPV4      "ipv4"
+# define MPLS_PAYLOAD_OPT__IPV6      "ipv6"
+# define MPLS_PAYLOAD_OPT__ETHERNET  "ethernet"
+#endif
+
+#define DEFAULT_PAF_MAX  16384
+
+/* Data types *****************************************************************/
+
+typedef enum _GetOptArgType
+{
+    LONGOPT_ARG_NONE = 0,
+    LONGOPT_ARG_REQUIRED,
+    LONGOPT_ARG_OPTIONAL
+
+} GetOptArgType;
+
+/* Externs *******************************************************************/
+extern void PrintPacket(Packet *p);
+
+/* Undefine the one from sf_dynamic_preprocessor.h */
+#ifdef PERF_PROFILING
+extern PreprocStats detectPerfStats, decodePerfStats, metaPerfStats,
+       totalPerfStats, eventqPerfStats, rulePerfStats, mpsePerfStats;
+extern PreprocStats ruleCheckBitPerfStats, ruleSetBitPerfStats, ruleFailedFlowbitsPerfStats;
+extern PreprocStats ruleRTNEvalPerfStats, ruleOTNEvalPerfStats, ruleHeaderNoMatchPerfStats;
+extern PreprocStats ruleAddEventQPerfStats, ruleNQEventQPerfStats;
+extern PreprocStats preprocRuleOptionPerfStats;
+#endif
+
+/* for getopt */
+extern char *optarg;
+extern int optind;
+extern int opterr;
+extern int optopt;
+
+extern ListHead *head_tmp;
+
+/* Globals/Public *************************************************************/
+extern PacketCount pc;  /* packet count information */
+extern uint32_t *netmasks;   /* precalculated netmask array */
+extern char **protocol_names;
+extern char *snort_conf_file;   /* -c */
+extern char *snort_conf_dir;
+
+extern SnortConfig *snort_cmd_line_conf;
+extern SnortConfig *snort_conf;
+extern tSfPolicyId runtimePolicyId;
+extern tSfPolicyId parserPolicyId;
+
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+SnortConfig *snort_conf_new = NULL;
+SnortConfig *snort_conf_old = NULL;
+#endif
+
+extern tSfActionQueueId decoderActionQ;
+extern MemPool decoderAlertMemPool;
+
+extern VarNode *cmd_line_var_list;
+
+#ifdef TARGET_BASED
+pthread_t attribute_reload_thread_id;
+pid_t attribute_reload_thread_pid;
+volatile int attribute_reload_thread_running = 0;
+volatile int attribute_reload_thread_stop = 0;
+int reload_attribute_table_flags = 0;
+#endif
+
+extern volatile bool snort_initializing;
+static volatile int snort_exiting = 0;
+static pid_t snort_main_thread_pid = 0;
+#ifndef WIN32
+static pthread_t snort_main_thread_id = 0;
+#endif
+
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+static volatile int snort_reload = 0;
+static volatile int snort_swapped = 0;
+static volatile int snort_reload_thread_created = 0;
+static pthread_t snort_reload_thread_id;
+static pid_t snort_reload_thread_pid;
+#ifdef CONTROL_SOCKET
+static volatile int reloadInProgress = 0;
+#endif
+#endif
+
+extern const struct timespec thread_sleep;
+#ifdef OPENBSD
+const struct timespec packet_sleep = { 0, 1 };
+#endif
+
+#ifdef HAVE_PCAP_LEX_DESTROY
+extern void pcap_lex_destroy(void);
+#endif
+
+extern PreprocConfigFuncNode *preproc_config_funcs;
+extern OutputConfigFuncNode *output_config_funcs;
+extern RuleOptConfigFuncNode *rule_opt_config_funcs;
+extern RuleOptOverrideInitFuncNode *rule_opt_override_init_funcs;
+extern RuleOptParseCleanupNode *rule_opt_parse_cleanup_list;
+extern RuleOptByteOrderFuncNode *rule_opt_byte_order_funcs;
+
+extern PreprocSignalFuncNode *preproc_clean_exit_funcs;
+extern PreprocSignalFuncNode *preproc_shutdown_funcs;
+extern PreprocSignalFuncNode *preproc_reset_funcs;
+extern PreprocSignalFuncNode *preproc_reset_stats_funcs;
+extern PreprocStatsFuncNode *preproc_stats_funcs;
+
+extern PluginSignalFuncNode *plugin_shutdown_funcs;
+extern PluginSignalFuncNode *plugin_clean_exit_funcs;
+#ifdef SNORT_RELOAD
+PostConfigFuncNode *plugin_reload_funcs = NULL;
+#endif
+
+extern OutputFuncNode *AlertList;   /* Alert function list */
+extern OutputFuncNode *LogList;     /* Log function list */
+
+extern PeriodicCheckFuncNode *periodic_check_funcs;
+extern DynamicRuleNode *dynamic_rules;
+extern grinder_t grinder;
+
+#ifdef SIDE_CHANNEL
+pthread_mutex_t snort_process_lock;
+static bool snort_process_lock_held = false;
+#endif
+
+/* Locals/Private ************************************************************/
+static long int pcap_loop_count = 0;
+static SF_QUEUE *pcap_save_queue = NULL;
+
+#if defined(INLINE_FAILOPEN) && !defined(WIN32)
+static pthread_t inline_failopen_thread_id;
+static pid_t inline_failopen_thread_pid;
+static volatile int inline_failopen_thread_running = 0;
+static volatile int inline_failopen_initialized = 0;
+static int inline_failopen_pass_pkt_cnt = 0;
+static void * SnortPostInitThread(void *);
+static DAQ_Verdict IgnoreCallback (void*, const DAQ_PktHdr_t*, const uint8_t*);
+#endif
+
+static char signal_error_msg[STD_BUF];
+static int exit_signal = 0;
+static bool dump_stats_signal = false;
+static bool rotate_stats_signal = false;
+#ifdef TARGET_BASED
+static bool no_attr_table_signal = false;
+#endif
+
+#ifndef SNORT_RELOAD
+static volatile bool reload_signal = false;
+#else
+/* reload_signal is incremented in the signal handler for SIGNAL_SNORT_RELOAD
+ * which is handled in the main thread.  The reload thread compares the
+ * reload_signal count to reload_total which it increments after an equality
+ * test between reload_signal and reload_total fails (which means we got a new
+ *  SIGNAL_SNORT_RELOAD).  They need to be the same type and size to do this
+ *  comparison.  See ReloadConfigThread() */
+typedef uint32_t snort_reload_t;
+static volatile snort_reload_t reload_signal = 0;
+static snort_reload_t reload_total = 0;
+#endif
+
+static int done_processing = 0;
+static int exit_logged = 0;
+
+static SF_LIST *pcap_object_list = NULL;
+static SF_QUEUE *pcap_queue = NULL;
+static char* pcap_filter = NULL;
+
+static int snort_argc = 0;
+static char **snort_argv = NULL;
+
+/* command line options for getopt */
+static char *valid_options =
+    "?A:bB:c:CdDeEfF:"
+#ifndef WIN32
+    "g:"
+#endif
+    "G:h:Hi:Ik:K:l:L:"
+#ifndef WIN32
+    "m:"
+#endif
+    "Mn:NOpP:q"
+#ifndef WIN32
+    "Q"
+#endif
+    "r:R:sS:"
+#ifndef WIN32
+    "t:"
+#endif
+    "T"
+#ifndef WIN32
+    "u:"
+#endif
+    "UvVw:"
+#ifdef WIN32
+    "W"
+#endif
+    "XxyZ:"
+;
+
+static struct option long_options[] =
+{
+   {"logid", LONGOPT_ARG_REQUIRED, NULL, 'G'},
+   {"perfmon-file", LONGOPT_ARG_REQUIRED, NULL, 'Z'},
+   {"snaplen", LONGOPT_ARG_REQUIRED, NULL, 'P'},
+   {"version", LONGOPT_ARG_NONE, NULL, 'V'},
+   {"help", LONGOPT_ARG_NONE, NULL, '?'},
+   {"conf-error-out", LONGOPT_ARG_NONE, NULL,'x'},
+   {"dynamic-engine-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_ENGINE_FILE},
+   {"dynamic-engine-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_ENGINE_DIRECTORY},
+   {"dynamic-detection-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_LIBRARY_FILE},
+   {"dynamic-detection-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_LIBRARY_DIRECTORY},
+   {"dump-dynamic-rules", LONGOPT_ARG_REQUIRED, NULL, DUMP_DYNAMIC_RULES},
+   {"dynamic-preprocessor-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_PREPROC_FILE},
+   {"dynamic-preprocessor-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_PREPROC_DIRECTORY},
+   {"dynamic-output-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_OUTPUT_FILE},
+   {"dynamic-output-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_OUTPUT_DIRECTORY},
+   {"alert-before-pass", LONGOPT_ARG_NONE, NULL, ALERT_BEFORE_PASS},
+   {"treat-drop-as-alert", LONGOPT_ARG_NONE, NULL, TREAT_DROP_AS_ALERT},
+   {"treat-drop-as-ignore", LONGOPT_ARG_NONE, NULL, TREAT_DROP_AS_IGNORE},
+   {"process-all-events", LONGOPT_ARG_NONE, NULL, PROCESS_ALL_EVENTS},
+   {"pid-path", LONGOPT_ARG_REQUIRED, NULL, PID_PATH},
+   {"create-pidfile", LONGOPT_ARG_NONE, NULL, CREATE_PID_FILE},
+   {"nolock-pidfile", LONGOPT_ARG_NONE, NULL, NOLOCK_PID_FILE},
+   {"no-interface-pidfile", LONGOPT_ARG_NONE, NULL, NO_IFACE_PID_FILE},
+
+#ifdef INLINE_FAILOPEN
+   {"disable-inline-init-failopen", LONGOPT_ARG_NONE, NULL, DISABLE_INLINE_FAILOPEN},
+#endif
+
+   {"nostamps", LONGOPT_ARG_NONE, NULL, NO_LOGGING_TIMESTAMPS},
+
+#ifdef TARGET_BASED
+   {"disable-attribute-reload-thread", LONGOPT_ARG_NONE, NULL, DISABLE_ATTRIBUTE_RELOAD},
+#endif
+
+   {"pcap-single", LONGOPT_ARG_REQUIRED, NULL, PCAP_SINGLE},
+   {"pcap-file", LONGOPT_ARG_REQUIRED, NULL, PCAP_FILE_LIST},
+   {"pcap-list", LONGOPT_ARG_REQUIRED, NULL, PCAP_LIST},
+
+#ifndef WIN32
+   {"pcap-dir", LONGOPT_ARG_REQUIRED, NULL, PCAP_DIR},
+   {"pcap-filter", LONGOPT_ARG_REQUIRED, NULL, PCAP_FILTER},
+   {"pcap-no-filter", LONGOPT_ARG_NONE, NULL, PCAP_NO_FILTER},
+#endif
+
+   {"pcap-loop", LONGOPT_ARG_REQUIRED, NULL, PCAP_LOOP},
+   {"pcap-reload", LONGOPT_ARG_NONE, NULL, PCAP_RELOAD},
+   {"pcap-reset", LONGOPT_ARG_NONE, NULL, PCAP_RESET},
+   {"pcap-show", LONGOPT_ARG_NONE, NULL, PCAP_SHOW},
+
+#ifdef EXIT_CHECK
+   {"exit-check", LONGOPT_ARG_REQUIRED, NULL, ARG_EXIT_CHECK},
+#endif
+
+   {"search-method", LONGOPT_ARG_REQUIRED, NULL, DETECTION_SEARCH_METHOD},
+   {"man", LONGOPT_ARG_REQUIRED, NULL, DETECTION_SEARCH_METHOD},
+
+#ifdef MPLS
+   {"enable-mpls-multicast", LONGOPT_ARG_NONE, NULL, ENABLE_MPLS_MULTICAST},
+   {"enable-mpls-overlapping-ip", LONGOPT_ARG_NONE, NULL, ENABLE_OVERLAPPING_IP},
+   {"max-mpls-labelchain-len", LONGOPT_ARG_REQUIRED, NULL, MAX_MPLS_LABELCHAIN_LEN},
+   {"mpls-payload-type", LONGOPT_ARG_REQUIRED, NULL, MPLS_PAYLOAD_TYPE},
+#endif
+
+   {"require-rule-sid", LONGOPT_ARG_NONE, NULL, REQUIRE_RULE_SID},
+
+   {"daq", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_TYPE},
+   {"daq-mode", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_MODE},
+   {"daq-var", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_VAR},
+   {"daq-dir", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_DIR},
+   {"daq-list", LONGOPT_ARG_OPTIONAL, NULL, ARG_DAQ_LIST},
+   {"dirty-pig", LONGOPT_ARG_NONE, NULL, ARG_DIRTY_PIG},
+
+   {"enable-inline-test", LONGOPT_ARG_NONE, NULL, ENABLE_INLINE_TEST},
+
+   {"cs-dir", LONGOPT_ARG_REQUIRED, NULL, ARG_CS_DIR},
+   {"ha-peer", LONGOPT_ARG_NONE, NULL, ARG_HA_PEER},
+   {"ha-out", LONGOPT_ARG_REQUIRED, NULL, ARG_HA_OUT},
+   {"ha-in", LONGOPT_ARG_REQUIRED, NULL, ARG_HA_IN},
+
+   {0, 0, 0, 0}
+};
+
+typedef void (*log_func_t)(Packet*);
+static void LogPacket (Packet* p)
+{
+    pc.log_pkts++;
+    CallLogPlugins(p, NULL, NULL);
+}
+static void IgnorePacket (Packet* p) { }
+static log_func_t log_func = IgnorePacket;
+
+/* Private function prototypes ************************************************/
+static void InitNetmasks(void);
+static void InitProtoNames(void);
+static const char* GetPacketSource(char**);
+
+static void CleanExit(int);
+//static void SnortInit(int, char **);
+static void InitPidChrootAndPrivs(pid_t);
+static void ParseCmdLine(int, char **);
+static int ShowUsage(char *);
+static void PrintVersion(void);
+static void SetSnortConfDir(void);
+static void InitGlobals(void);
+static SnortConfig * MergeSnortConfs(SnortConfig *, SnortConfig *);
+static void InitSignals(void);
+#if defined(NOCOREFILE) && !defined(WIN32)
+static void SetNoCores(void);
+#endif
+static void SnortCleanup(int);
+
+static void ParseCmdLineDynamicLibInfo(SnortConfig *, int, char *);
+static DynamicLibInfo * DupDynamicLibInfo(DynamicLibInfo *);
+static void FreeDynamicLibInfo(DynamicLibInfo *);
+static void FreeDynamicLibInfos(SnortConfig *);
+
+static void FreeOutputConfigs(OutputConfig *);
+#ifdef SIDE_CHANNEL
+static void FreeSideChannelModuleConfigs(SideChannelModuleConfig *);
+#endif
+static void FreePreprocConfigs(SnortConfig *);
+static void FreeRuleStateList(RuleState *);
+static void FreeClassifications(ClassType *);
+static void FreeReferences(ReferenceSystemNode *);
+static void FreePlugins(SnortConfig *);
+static void FreePreprocessors(SnortConfig *);
+
+extern void SnortUnprivilegedInit(void);
+static int SetPktProcessor(void);
+static void PacketLoop(void);
+extern void odp_snort_run_threads(void);
+#if 0
+static char * ConfigFileSearch(void);
+#endif
+static void SnortReset(void);
+
+static void LoadDynamicPlugins(SnortConfig *);
+
+static void SnortIdle(void);
+#ifndef WIN32
+static void SnortStartThreads(void);
+#endif
+
+/* Signal handler declarations ************************************************/
+static void SigDumpStatsHandler(int);
+static void SigExitHandler(int);
+static void SigReloadHandler(int);
+static void SigRotateStatsHandler(int);
+#ifdef CONTROL_SOCKET
+static void SigPipeHandler(int);
+#endif
+static void SigOopsHandler(int);
+
+#ifdef TARGET_BASED
+static void SigNoAttributeTableHandler(int);
+#endif
+
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+static SnortConfig * ReloadConfig(void);
+static void * ReloadConfigThread(void *);
+static int VerifyReload(SnortConfig *);
+static int VerifyOutputs(SnortConfig *, SnortConfig *);
+static int VerifyLibInfos(DynamicLibInfo *, DynamicLibInfo *);
+#endif  /* SNORT_RELOAD */
+
+static int IsProcessingPackets(uint16_t type, const uint8_t *data, uint32_t length, void **new_config,
+                               char *statusBuf, int statusBuf_len)
+{
+    return (!snort_initializing && !snort_exiting && !exit_signal) ? 0 : -1;
+}
+
+#if defined(SNORT_RELOAD) && !defined(WIN32) && defined(CONTROL_SOCKET)
+
+static pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int ControlSocketReloadConfig(uint16_t type, const uint8_t *data, uint32_t length, void **new_config,
+                                     char *statusBuf, int statusBuf_len)
+{
+    SnortConfig *new_sc;
+
+    pthread_mutex_lock(&reload_mutex);
+    while (reloadInProgress)
+    {
+        sleep(1);
+    }
+    reloadInProgress = 1;
+    pthread_mutex_unlock(&reload_mutex);
+
+    LogMessage("\n");
+    LogMessage("        --== Reloading Snort ==--\n");
+    LogMessage("\n");
+
+    new_sc = ReloadConfig();
+    if (new_sc == NULL)
+    {
+        reloadInProgress = 0;
+        return -1;
+    }
+    *new_config = (void *)new_sc;
+    return 0;
+}
+
+static int ControlSocketReloadSwap(uint16_t type, void *new_config, void **old_config)
+{
+    PostConfigFuncNode *idxPlugin = NULL;
+
+    *old_config = (void *)snort_conf;
+    snort_conf = (SnortConfig *)new_config;
+    SwapPreprocConfigurations(snort_conf);
+
+    FreeSwappedPreprocConfigurations(snort_conf);
+
+#ifdef INTEL_SOFT_CPM
+    if (snort_conf->fast_pattern_config->search_method == MPSE_INTEL_CPM)
+        IntelPmActivate(snort_conf);
+#endif
+
+    /* Do any reload for plugin data */
+    idxPlugin = plugin_reload_funcs;
+    while(idxPlugin)
+    {
+        idxPlugin->func(snort_conf, SIGHUP, idxPlugin->arg);
+        idxPlugin = idxPlugin->next;
+    }
+    return 0;
+}
+
+static void ControlSocketReloadFree(uint16_t type, void *old_config, struct _THREAD_ELEMENT *te, ControlDataSendFunc f)
+{
+    SnortConfig *old_sc = (SnortConfig *)old_config;
+
+    SnortConfFree(old_sc);
+
+#ifdef INTEL_SOFT_CPM
+    if (snort_conf->fast_pattern_config->search_method != MPSE_INTEL_CPM)
+        IntelPmStopInstance();
+#endif
+
+    LogMessage("\n");
+    LogMessage("        --== Reload Complete ==--\n");
+    LogMessage("\n");
+
+    reloadInProgress = 0;
+}
+#endif
+
+static inline void CheckForReload(void)
+{
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+    /* Check for a new configuration */
+    if (snort_reload)
+    {
+        PostConfigFuncNode *idxPlugin = NULL;
+        snort_reload = 0;
+
+        /* There was an error reloading.  A non-reloadable configuration
+         * option changed */
+        if (snort_conf_new == NULL)
+        {
+#ifdef RELOAD_ERROR_FATAL
+            CleanExit(1);
+#else
+            Restart();
+#endif
+        }
+
+        snort_conf_old = snort_conf;
+        snort_conf = snort_conf_new;
+        snort_conf_new = NULL;
+        SwapPreprocConfigurations(snort_conf);
+
+        /* Need to do this here because there is potentially outstanding
+         * state data pointing to the previous configuration.  A race
+         * condition is created if these are free'd in the reload thread
+         * where a double free could occur. */
+        FreeSwappedPreprocConfigurations(snort_conf);
+
+#ifdef INTEL_SOFT_CPM
+        if (snort_conf->fast_pattern_config->search_method == MPSE_INTEL_CPM)
+            IntelPmActivate(snort_conf);
+#endif
+
+        snort_swapped = 1;
+
+        /* Do any reload for plugin data */
+        idxPlugin = plugin_reload_funcs;
+        while(idxPlugin)
+        {
+            idxPlugin->func(snort_conf, SIGHUP, idxPlugin->arg);
+            idxPlugin = idxPlugin->next;
+        }
+    }
+#endif
+}
+
+/*  F U N C T I O N   D E F I N I T I O N S  **********************************/
+
+static int InlineFailOpen (void)
+{
+#if defined(INLINE_FAILOPEN) && !defined(WIN32)
+    if (ScAdapterInlineMode() &&
+        !ScReadMode() && !ScDisableInlineFailopen())
+    {
+        /* If in inline mode, start a thread to handle the rest of snort
+         * initialization, then dispatch packets until that initialization
+         * is complete. */
+        LogMessage("Fail Open Thread starting..\n");
+
+	printf("%s()%d chreate new thread\n", __func__, __LINE__);
+        if (pthread_create(&inline_failopen_thread_id, NULL, SnortPostInitThread, NULL))
+        {
+            ErrorMessage("Failed to start Fail Open Thread.  "
+                         "Starting normally\n");
+        }
+        else
+        {
+            while (!inline_failopen_thread_running)
+                nanosleep(&thread_sleep, NULL);
+
+            LogMessage("Fail Open Thread started tid=%p (pid=%u)\n",
+                    (void*)inline_failopen_thread_id, inline_failopen_thread_pid);
+
+# ifdef DEBUG
+            {
+                FILE *tmp = fopen("/var/tmp/fo_threadid", "w");
+                if ( tmp )
+                {
+                    fprintf(tmp, "Fail Open Thread PID: %u\n", inline_failopen_thread_pid);
+                    fclose(tmp);
+                }
+            }
+# endif
+            DAQ_Start();
+            SetPktProcessor();
+            inline_failopen_initialized = 1;
+
+            /* Passing packets is in the main thread because some systems
+             * may have to refer to packet passing thread via process id
+             * (linuxthreads) */
+            while (snort_initializing)
+            {
+                int error = DAQ_Acquire(1, IgnoreCallback, NULL);
+
+                if (error)
+                    break;
+            }
+
+            pthread_join(inline_failopen_thread_id, NULL);
+            inline_failopen_thread_running = 0;
+
+            LogMessage("Fail Open Thread terminated, passed %d packets.\n",
+                       inline_failopen_pass_pkt_cnt);
+
+            return 1;
+        }
+    }
+#endif
+    return 0;
+}
+
+/*
+ *
+ * Function: main(int, char *)
+ *
+ * Purpose:  Handle program entry and exit, call main prog sections
+ *           This can handle both regular (command-line) style
+ *           startup, as well as Win32 Service style startup.
+ *
+ * Arguments: See command line args in README file
+ *
+ * Returns: 0 => normal exit, 1 => exit on error
+ *
+ */
+int main(int argc, char *argv[])
+{
+	/* hack to add deps to -lrt for timer_create() and friends from odp */
+	static volatile int link_rt = 0;
+	timer_t timerid = 0;
+	if (link_rt)
+		timer_settime(timerid, 0, NULL, NULL);
+
+#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
+    /* Do some sanity checking, because some people seem to forget to
+     * put spaces between their parameters
+     */
+    if ((argc > 1) &&
+        ((_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_INSTALL_CMDLINE_PARAM)) == 0) ||
+         (_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_UNINSTALL_CMDLINE_PARAM)) == 0) ||
+         (_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_SHOW_CMDLINE_PARAM)) == 0)))
+    {
+        FatalError("You must have a space after the '%s' command-line parameter\n",
+                   SERVICE_CMDLINE_PARAM);
+    }
+
+    /* If the first parameter is "/SERVICE", then start Snort as a Win32 service */
+    if((argc > 1) && (_stricmp(argv[1],SERVICE_CMDLINE_PARAM) == 0))
+    {
+        return SnortServiceMain(argc, argv);
+    }
+#endif /* WIN32 && ENABLE_WIN32_SERVICE */
+
+    snort_argc = argc;
+    snort_argv = argv;
+
+    return ODP_SnortMain(argc, argv);
+}
+
+/*
+ *
+ * Function: SnortMain(int, char *)
+ *
+ * Purpose:  The real place that the program handles entry and exit.  Called
+ *           called by main(), or by SnortServiceMain().
+ *
+ * Arguments: See command line args in README file
+ *
+ * Returns: 0 => normal exit, 1 => exit on error
+ *
+ */
+int ODP_SnortMain(int argc, char *argv[])
+{
+    char* tmp_ptr = NULL;
+    const char* intf;
+    int daqInit;
+
+
+    do_odp_init(argc, argv);
+
+#ifndef WIN32
+    // must be done now in case of fatal error
+    // and again after daemonization
+    snort_main_thread_id = pthread_self();
+#endif
+
+    SnortInit(argc, argv);
+
+    intf = GetPacketSource(&tmp_ptr);
+    daqInit = intf || snort_conf->daq_type;
+
+    if ( daqInit )
+    {
+        //DAQ_Init(snort_conf);
+        //DAQ_New(snort_conf, intf);
+    }
+    if ( tmp_ptr )
+        free(tmp_ptr);
+
+    if ( ScDaemonMode() )
+    {
+        GoDaemon();
+    }
+
+    // this must follow daemonization
+    snort_main_thread_pid = gettid();
+#ifndef WIN32
+    snort_main_thread_id = pthread_self();
+#endif
+
+#ifndef WIN32
+    /* Change groups */
+    InitGroups(ScUid(), ScGid());
+#endif
+
+#if !defined(HAVE_LINUXTHREADS) && !defined(WIN32)
+    // this could be moved to linux threads location
+    // and only done there
+    SnortStartThreads();
+#endif
+
+#if defined(SNORT_RELOAD) && !defined(WIN32) && defined(CONTROL_SOCKET)
+    if (ControlSocketRegisterHandler(CS_TYPE_RELOAD, &ControlSocketReloadConfig, &ControlSocketReloadSwap, &ControlSocketReloadFree))
+    {
+        LogMessage("Failed to register the reload control handler.\n");
+    }
+#endif
+
+    if (ControlSocketRegisterHandler(CS_TYPE_IS_PROCESSING, &IsProcessingPackets, NULL, NULL))
+    {
+        LogMessage("Failed to register the is processing control handler.\n");
+    }
+
+    if ( ScTestMode() )
+    {
+        if ( daqInit && DAQ_UnprivilegedStart() )
+            SetPktProcessor();
+        SnortUnprivilegedInit();
+    }
+    else if ( DAQ_UnprivilegedStart() )
+    {
+        SnortUnprivilegedInit();
+        SetPktProcessor();
+        //DAQ_Start();
+    }
+    else if ( !InlineFailOpen() )
+    {
+        //DAQ_Start();
+        SetPktProcessor();
+        SnortUnprivilegedInit();
+    }
+
+    printf("going to packet loop\n");
+    odp_snort_run_threads();
+
+    //PacketLoop();
+
+    // DAQ is shutdown in CleanExit() since we don't always return here
+    CleanExit(0);
+
+    return 0;
+}
+
+#ifndef WIN32
+/* All threads need to be created after daemonizing.  If created in
+ * the parent thread, when it goes away, so will all of the threads.
+ * The child does not "inherit" threads created in the parent. */
+static void SnortStartThreads(void)
+{
+# ifdef SNORT_RELOAD
+    if (ScIdsMode())
+    {
+        LogMessage("Reload thread starting...\n");
+	printf("%s()%d chreate new thread\n", __func__, __LINE__);
+        if (pthread_create(&snort_reload_thread_id, NULL, ReloadConfigThread, NULL) != 0)
+        {
+            ErrorMessage("Could not create configuration reload thread.\n");
+            CleanExit(1);
+        }
+
+        while (!snort_reload_thread_created)
+            nanosleep(&thread_sleep, NULL);
+
+        LogMessage("Reload thread started, thread %p (%u)\n",
+                (void*)snort_reload_thread_id, snort_reload_thread_pid);
+    }
+# endif
+
+# ifdef TARGET_BASED
+    SFAT_StartReloadThread();
+# endif
+}
+#else   /* WIN32 */
+//------------------------------------------------------------------------------
+// interface stuff
+//------------------------------------------------------------------------------
+
+static void PrintAllInterfaces (void)
+{
+    char errorbuf[PCAP_ERRBUF_SIZE];
+    pcap_if_t *alldevs;
+    pcap_if_t *dev;
+    int j = 1;
+    MIB_IFTABLE *iftable = NULL;
+    unsigned int len = 0;
+    unsigned int ret, i;
+
+    if (pcap_findalldevs(&alldevs, errorbuf) == -1)
+        FatalError("Could not get device list: %s.", errorbuf);
+
+    /* max of two iterations here -- first to get the
+     * correct length if not big enough. Second to
+     * get the data. */
+    for (len = sizeof(iftable[0]); ; ) {
+        if (iftable)
+            free(iftable);
+        iftable = SnortAlloc(len);
+        ret = GetIfTable(iftable, &len, TRUE);
+        if (ret == NO_ERROR)
+            break;
+        else if (ret != ERROR_INSUFFICIENT_BUFFER)
+            FatalError("Could not get device list: %s.", errorbuf);;
+    }
+
+    printf("Index\tPhysical Address\tIP Address\tDevice Name\tDescription\n");
+    printf("-----\t----------------\t----------\t-----------\t-----------\n");
+
+    for (dev = alldevs; dev != NULL; dev = dev->next, j++)
+    {
+        uint8_t *mac_addr = NULL;
+        for (i = 0; i<iftable->dwNumEntries; i++)
+        {
+            if (strncmp(dev->description, iftable->table[i].bDescr, iftable->table[i].dwDescrLen) == 0)
+            {
+                mac_addr = iftable->table[i].bPhysAddr;
+                break;
+            }
+        }
+        printf("%5d\t", j);
+        if (mac_addr)
+        {
+            printf("%02X:%02X:%02X:%02X:%02X:%02X\t",
+                mac_addr[0], mac_addr[1], mac_addr[2],
+                mac_addr[3], mac_addr[4], mac_addr[5]);
+        }
+        else
+        {
+            printf("00:00:00:00:00:00\t");
+        }
+        if (dev->addresses)
+        {
+            struct sockaddr_in* saddr = (struct sockaddr_in*)dev->addresses->addr;
+            sfip_t dev_ip;
+            if ((saddr->sin_family == AF_INET) || (saddr->sin_family == AF_INET6))
+            {
+                sfip_set_raw(&dev_ip, &saddr->sin_addr, saddr->sin_family);
+                printf("%s\t", inet_ntoa(&dev_ip));
+            }
+            else
+            {
+                printf("disabled\t");
+            }
+            printf("%s\t%s\n", dev->name, dev->description);
+        }
+        else
+        {
+            printf("disabled\t%s\t%s\n", dev->name, dev->description);
+        }
+
+    }
+    pcap_freealldevs(alldevs);
+    free(iftable);
+}
+#endif  /* WIN32 */
+
+// pcap list stuff ...
+
+static void PQ_SetFilter (const char* f)
+{
+    if (pcap_filter != NULL)
+        free(pcap_filter);
+
+    pcap_filter = f ? SnortStrdup(f) : NULL;
+}
+
+static void PQ_Single (const char* pcap)
+{
+    PcapReadObject* pro;
+
+    if (pcap_object_list == NULL)
+    {
+        pcap_object_list = sflist_new();
+        if (pcap_object_list == NULL)
+            FatalError("Could not allocate list to store pcap\n");
+    }
+
+    pro = (PcapReadObject *)SnortAlloc(sizeof(PcapReadObject));
+    pro->type = PCAP_SINGLE;
+    pro->arg = SnortStrdup(pcap);
+    pro->filter = NULL;
+
+    if (sflist_add_tail(pcap_object_list, (NODE_DATA)pro) == -1)
+        FatalError("Could not add pcap object to list: %s\n", pcap);
+}
+
+static void PQ_Multi (char type, const char* list)
+{
+    PcapReadObject* pro;
+
+    if (pcap_object_list == NULL)
+    {
+        pcap_object_list = sflist_new();
+        if (pcap_object_list == NULL)
+            FatalError("Could not allocate list to store pcaps\n");
+    }
+
+    pro = (PcapReadObject *)SnortAlloc(sizeof(PcapReadObject));
+    pro->type = type;
+    pro->arg = SnortStrdup(list);
+    if (pcap_filter != NULL)
+        pro->filter = SnortStrdup(pcap_filter);
+    else
+        pro->filter = NULL;
+
+    if (sflist_add_tail(pcap_object_list, (NODE_DATA)pro) == -1)
+        FatalError("Could not add pcap object to list: %s\n", list);
+}
+
+static void PQ_SetUp (void)
+{
+    if (pcap_object_list != NULL)
+    {
+        if (sflist_count(pcap_object_list) == 0)
+        {
+            sflist_free_all(pcap_object_list, NULL);
+            FatalError("No pcaps specified.\n");
+        }
+
+        pcap_queue = sfqueue_new();
+        pcap_save_queue = sfqueue_new();
+        if ((pcap_queue == NULL) || (pcap_save_queue == NULL))
+            FatalError("Could not allocate pcap queues.\n");
+
+        if (GetPcaps(pcap_object_list, pcap_queue) == -1)
+            FatalError("Error getting pcaps.\n");
+
+        if (sfqueue_count(pcap_queue) == 0)
+            FatalError("No pcaps found.\n");
+
+        /* free pcap list used to get params */
+        while (sflist_count(pcap_object_list) > 0)
+        {
+            PcapReadObject *pro = (PcapReadObject *)sflist_remove_head(pcap_object_list);
+            if (pro == NULL)
+                FatalError("Failed to remove pcap item from list.\n");
+
+            if (pro->arg != NULL)
+                free(pro->arg);
+
+            if (pro->filter != NULL)
+                free(pro->filter);
+
+            free(pro);
+        }
+
+        sflist_free_all(pcap_object_list, NULL);
+        pcap_object_list = NULL;
+    }
+    if (pcap_filter != NULL)
+    {
+        free(pcap_filter);
+        pcap_filter = NULL;
+    }
+}
+
+static int PQ_CleanUp (void)
+{
+    /* clean up pcap queues */
+    if (pcap_queue != NULL)
+        sfqueue_free_all(pcap_queue, free);
+
+    if (pcap_save_queue != NULL)
+        sfqueue_free_all(pcap_save_queue, free);
+
+    return 0;
+}
+
+static void PQ_Show (const char* pcap)
+{
+    if ( !ScPcapShow() )
+        return;
+
+    if ( !strcmp(pcap, "-") ) pcap = "stdin";
+
+    fprintf(stdout,
+        "Reading network traffic from \"%s\" with snaplen = %d\n",
+        pcap, DAQ_GetSnapLen());
+}
+
+static const char* PQ_First (void)
+{
+    const char* pcap = (char*)sfqueue_remove(pcap_queue);
+
+    if ( !pcap )
+        return pcap;
+
+    if ( sfqueue_add(pcap_save_queue, (NODE_DATA)pcap) == -1 )
+        FatalError("Could not add pcap to saved list\n");
+
+    return pcap;
+}
+
+// this must follow 2nd or later start and not stop because we force a
+// reset when the dlt changes even if not enabled with --pcap-reset to
+// avoid eventually flushing stream packets through a different grinder
+// than the one they were queued with.
+static void PQ_Reset ()
+{
+    static int dlt = -1;
+    int new_dlt = DAQ_GetBaseProtocol();
+
+    if ( ScPcapReset() || ((dlt != new_dlt) && (dlt != -1)) )
+        SnortReset();
+
+    dlt = new_dlt;
+
+    /* open a new tcpdump file - necessary because the snaplen and
+     * datalink could be different between pcaps */
+    if (snort_conf->log_tcpdump)
+    {
+        /* this sleep is to ensure we get a new log file since it has a
+         * time stamp with resolution to the second */
+#ifdef WIN32
+        Sleep(1000);
+#else
+        sleep(1);
+#endif
+        LogTcpdumpReset();
+    }
+}
+
+static int PQ_Next (void)
+{
+    char reopen_pcap = 0;
+
+    if (sfqueue_count(pcap_queue) > 0)
+    {
+        reopen_pcap = 1;
+    }
+    else if (pcap_loop_count)
+    {
+        if (pcap_loop_count > 0)
+            pcap_loop_count--;
+
+        if (pcap_loop_count != 0)
+        {
+            SF_QUEUE *tmp;
+
+            /* switch pcap lists */
+            tmp = pcap_queue;
+            pcap_queue = pcap_save_queue;
+            pcap_save_queue = tmp;
+
+            reopen_pcap = 1;
+        }
+    }
+
+    if (reopen_pcap)
+    {
+        /* reinitialize pcap */
+        const char* pcap = PQ_First();
+
+        if ( !pcap )
+            FatalError("Could not get pcap from list\n");
+
+        DAQ_Stop();
+        DAQ_Delete();
+
+        DAQ_New(snort_conf, pcap);
+        DAQ_Start();
+
+        PQ_Reset();
+        PQ_Show(pcap);
+        SetPktProcessor();
+
+        SetSampleTime(perfmon_config, NULL);
+
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+        if ( snort_conf->run_flags & RUN_FLAG__PCAP_RELOAD && ScIdsMode())
+        {
+            /* Awaiting user confirmation */
+            printf("Hit return to continue.\n");
+            fflush(stdout);
+            while(getc(stdin) != '\n');
+
+            SigReloadHandler(SIGNAL_SNORT_RELOAD);
+
+            while (!snort_reload)
+                sleep(1);
+        }
+#endif
+
+        return 1;
+    }
+    return 0;
+}
+
+static char* GetFirstInterface (void)
+{
+    char *iface = NULL;
+    char errorbuf[PCAP_ERRBUF_SIZE];
+#ifdef WIN32
+    pcap_if_t *alldevs;
+
+    if ( (pcap_findalldevs(&alldevs, errorbuf) == -1) || !alldevs )
+    {
+        FatalError( "Failed to lookup interface: %s. "
+            "Please specify one with -i switch\n", errorbuf);
+    }
+
+    /* Pick first interface */
+    iface = SnortStrdup(alldevs->name);
+    pcap_freealldevs(alldevs);
+#else
+    DEBUG_WRAP(DebugMessage(
+        DEBUG_INIT, "interface is NULL, looking up interface...."););
+
+    /* look up the device and get the handle */
+    iface = pcap_lookupdev(errorbuf);
+
+    if ( !iface )
+    {
+        FatalError( "Failed to lookup interface: %s. "
+            "Please specify one with -i switch\n", errorbuf);
+    }
+
+    DEBUG_WRAP(DebugMessage(DEBUG_INIT, "found interface %s\n",
+                            PRINT_INTERFACE(iface)););
+
+    iface = SnortStrdup(iface);
+#endif
+    return iface;
+}
+
+static const char* GetPacketSource (char** sptr)
+{
+    const char* intf = "other";
+
+    if ( ScReadMode() )
+    {
+        intf = PQ_First();
+        PQ_Show(intf);
+    }
+    else if ( !ScVersionMode() && !ScRuleDumpMode() )
+    {
+        intf = snort_conf->interface;
+
+        // don't get interface if daq is explicitly configured
+        // since we can't assume that an interface is compatible
+        if ( !intf && !ScTestMode() &&
+            (!snort_conf->daq_type ||
+            // but we make execptions for these:
+            // TBD make selection based on DAQ_TYPE_XXX
+            !strcasecmp(snort_conf->daq_type, "afpacket") ||
+            !strcasecmp(snort_conf->daq_type, "pcap") ||
+            !strcasecmp(snort_conf->daq_type, "dump")) )
+        {
+            intf = GetFirstInterface();
+            *sptr = (char*)intf;
+        }
+    }
+    return intf;
+}
+
+static void InitPidChrootAndPrivs(pid_t pid)
+{
+    /* create the PID file */
+    if ( !ScReadMode() &&
+        (ScDaemonMode() || *snort_conf->pidfile_suffix || ScCreatePidFile()))
+    {
+        CreatePidFile(DAQ_GetInterfaceSpec(), pid);
+    }
+
+#ifndef WIN32
+    /* Drop the Chrooted Settings */
+    if (snort_conf->chroot_dir)
+        SetChroot(snort_conf->chroot_dir, &snort_conf->log_dir);
+#endif
+
+#ifndef WIN32
+    /* Drop privileges if requested, when initialization is done */
+    SetUidGid(ScUid(), ScGid());
+#endif
+}
+
+static void LoadDynamicPlugins(SnortConfig *sc)
+{
+    unsigned i;
+
+    if (sc == NULL)
+        return;
+
+    if (sc->dyn_engines != NULL)
+    {
+        /* Load the dynamic engines */
+        for (i = 0; i < sc->dyn_engines->count; i++)
+        {
+            switch (sc->dyn_engines->lib_paths[i]->ptype)
+            {
+                case PATH_TYPE__FILE:
+                    LoadDynamicEngineLib(sc->dyn_engines->lib_paths[i]->path, 0);
+                    break;
+
+                case PATH_TYPE__DIRECTORY:
+                    LoadAllDynamicEngineLibs(sc->dyn_engines->lib_paths[i]->path);
+                    break;
+            }
+        }
+    }
+
+    if (sc->dyn_rules != NULL)
+    {
+        /* Load the dynamic detection libs */
+        for (i = 0; i < sc->dyn_rules->count; i++)
+        {
+            switch (sc->dyn_rules->lib_paths[i]->ptype)
+            {
+                case PATH_TYPE__FILE:
+                    LoadDynamicDetectionLib(sc->dyn_rules->lib_paths[i]->path, 0);
+                    break;
+
+                case PATH_TYPE__DIRECTORY:
+                    LoadAllDynamicDetectionLibs(sc->dyn_rules->lib_paths[i]->path);
+                    break;
+            }
+        }
+    }
+
+    if (sc->dyn_preprocs != NULL)
+    {
+        /* Load the dynamic preprocessors */
+        for (i = 0; i < sc->dyn_preprocs->count; i++)
+        {
+            switch (sc->dyn_preprocs->lib_paths[i]->ptype)
+            {
+                case PATH_TYPE__FILE:
+                    LoadDynamicPreprocessor(sc->dyn_preprocs->lib_paths[i]->path, 0);
+                    break;
+
+                case PATH_TYPE__DIRECTORY:
+                    LoadAllDynamicPreprocessors(sc->dyn_preprocs->lib_paths[i]->path);
+                    break;
+            }
+        }
+    }
+
+# ifdef SIDE_CHANNEL
+    if (sc->dyn_side_channels != NULL)
+    {
+        /* Load the dynamic side channels */
+        for (i = 0; i < sc->dyn_side_channels->count; i++)
+        {
+            switch (sc->dyn_side_channels->lib_paths[i]->ptype)
+            {
+                case PATH_TYPE__FILE:
+                    LoadDynamicSideChannelLib(sc->dyn_side_channels->lib_paths[i]->path, 0);
+                    break;
+
+                case PATH_TYPE__DIRECTORY:
+                    LoadAllDynamicSideChannelLibs(sc->dyn_side_channels->lib_paths[i]->path);
+                    break;
+            }
+        }
+    }
+# endif /* SIDE_CHANNEL */
+
+    ValidateDynamicEngines();
+}
+
+static void DisplayDynamicPluginVersions(void)
+{
+    void *lib = NULL;
+    DynamicPluginMeta *meta;
+
+    RemoveDuplicateEngines();
+    RemoveDuplicateDetectionPlugins();
+    RemoveDuplicatePreprocessorPlugins();
+#ifdef SIDE_CHANNEL
+    RemoveDuplicateSideChannelPlugins();
+#endif /* SIDE_CHANNEL */
+
+    lib = GetNextEnginePluginVersion(NULL);
+    while ( lib != NULL )
+    {
+        meta = GetDetectionPluginMetaData(lib);
+
+        LogMessage("           Rules Engine: %s  Version %d.%d  <Build %d>\n",
+                   meta->uniqueName, meta->major, meta->minor, meta->build);
+        lib = GetNextEnginePluginVersion(lib);
+    }
+
+    lib = GetNextDetectionPluginVersion(NULL);
+    while ( lib != NULL )
+    {
+        meta = GetEnginePluginMetaData(lib);
+
+        LogMessage("           Rules Object: %s  Version %d.%d  <Build %d>\n",
+                   meta->uniqueName, meta->major, meta->minor, meta->build);
+        lib = GetNextDetectionPluginVersion(lib);
+    }
+
+    lib = GetNextPreprocessorPluginVersion(NULL);
+    while ( lib != NULL )
+    {
+        meta = GetPreprocessorPluginMetaData(lib);
+
+        LogMessage("           Preprocessor Object: %s  Version %d.%d  <Build %d>\n",
+                   meta->uniqueName, meta->major, meta->minor, meta->build);
+        lib = GetNextPreprocessorPluginVersion(lib);
+    }
+
+#ifdef SIDE_CHANNEL
+    lib = GetNextSideChannelPluginVersion(NULL);
+    while ( lib != NULL )
+    {
+        meta = GetSideChannelPluginMetaData(lib);
+
+        LogMessage("           Side Channel Object: %s  Version %d.%d  <Build %d>\n",
+                   meta->uniqueName, meta->major, meta->minor, meta->build);
+        lib = GetNextSideChannelPluginVersion(lib);
+    }
+#endif /* SIDE_CHANNEL */
+
+    lib = GetNextOutputModule(NULL);
+    while ( lib != NULL )
+    {
+        LogMessage("           Output Module: %s  Version %u\n",
+            GetOutputModuleName(lib), GetOutputModuleVersion(lib));
+        lib = GetNextOutputModule(lib);
+    }
+}
+
+/*
+ * This function will print versioning information regardless of whether or
+ * not the quiet flag is set.  If the quiet flag has been set and we want
+ * to honor it, check it before calling this function.
+ */
+static void PrintVersion(void)
+{
+    /* Unset quiet flag so LogMessage will print, then restore just
+     * in case anything other than exiting after this occurs */
+    int save_quiet_flag = snort_conf->logging_flags & LOGGING_FLAG__QUIET;
+
+    snort_conf->logging_flags &= ~LOGGING_FLAG__QUIET;
+    DisplayBanner();
+
+    //  Get and print out library versions
+    DisplayDynamicPluginVersions();
+
+    snort_conf->logging_flags |= save_quiet_flag;
+}
+
+static void PrintDaqModules (SnortConfig* sc, char* dir)
+{
+    if ( dir )
+        ConfigDaqDir(sc, dir);
+
+    DAQ_Load(snort_conf);
+    DAQ_PrintTypes(stdout);
+    DAQ_Unload();
+}
+
+#ifdef EXIT_CHECK
+static uint64_t exitTime = 0;
+
+static void ExitCheckStart (void)
+{
+    if ( exitTime )
+    {
+        return;
+    }
+    LogMessage("Exit Check: signaling at " STDu64 "callback\n", (long long unsigned int)pc.total_from_daq);
+    get_clockticks(exitTime);
+#ifndef WIN32
+    kill(0, SIGINT);  // send to all processes in my process group
+#else
+    raise(SIGINT);
+#endif
+}
+
+static void ExitCheckEnd (void)
+{
+    uint64_t now = 0;
+    double usecs = 0.0;
+
+    if ( !exitTime )
+    {
+        LogMessage(
+            "Exit Check: callbacks = " STDu64 "(limit not reached)\n",
+            (long long unsigned int)pc.total_from_daq
+        );
+        return;
+    }
+    get_clockticks(now);
+    exitTime = now - exitTime;
+    usecs = exitTime / get_ticks_per_usec();
+
+    LogMessage("Exit Check: usecs = %f\n", usecs);
+}
+#endif
+
+#ifdef HAVE_DAQ_ACQUIRE_WITH_META
+static int MetaCallback(
+    void* user, const DAQ_MetaHdr_t *metahdr, const uint8_t* data)
+{
+    tSfPolicyId policy_id = getDefaultPolicy();
+    SnortPolicy *policy;
+    PreprocMetaEvalFuncNode *idx;
+    PROFILE_VARS;
+
+#ifdef SIDE_CHANNEL
+    if (ScSideChannelEnabled() && !snort_process_lock_held)
+    {
+        pthread_mutex_lock(&snort_process_lock);
+        snort_process_lock_held = true;
+    }
+#endif
+
+    /* First thing we do is process a Usr signal that we caught */
+    if (SignalCheck())
+    {
+#ifndef SNORT_RELOAD
+        /* Got SIGNAL_SNORT_RELOAD */
+        Restart();
+#endif
+    }
+
+    CheckForReload();
+
+    PREPROC_PROFILE_START(metaPerfStats);
+
+    policy = snort_conf->targeted_policies[policy_id];
+    idx = policy->preproc_meta_eval_funcs;
+    while (idx != NULL)
+    {
+        idx->func(metahdr->type, data);
+        idx = idx->next;
+    }
+
+    PREPROC_PROFILE_END(metaPerfStats);
+
+#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
+    if (ScTerminateService() || ScPauseService())
+    {
+        return 0;  // time to go
+    }
+#endif
+
+    ControlSocketDoWork(0);
+#ifdef SIDE_CHANNEL
+    SideChannelDrainRX(0);
+#endif
+
+    return 0;
+}
+#endif
+
+// non-local for easy access from core
+static Packet s_packet;
+static DAQ_PktHdr_t s_pkth;
+static uint8_t s_data[65536];
+
+static DAQ_Verdict PacketCallback(
+    void* user, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt)
+{
+    int inject = 0;
+    DAQ_Verdict verdict = DAQ_VERDICT_PASS;
+    PROFILE_VARS;
+
+    PREPROC_PROFILE_START(totalPerfStats);
+
+#ifdef SIDE_CHANNEL
+    if (ScSideChannelEnabled() && !snort_process_lock_held)
+    {
+        pthread_mutex_lock(&snort_process_lock);
+        snort_process_lock_held = true;
+    }
+#endif
+
+#ifdef EXIT_CHECK
+    if (snort_conf->exit_check && (pc.total_from_daq >= snort_conf->exit_check))
+        ExitCheckStart();
+#endif
+
+    /* First thing we do is process a Usr signal that we caught */
+    if (SignalCheck())
+    {
+#ifndef SNORT_RELOAD
+        /* Got SIGNAL_SNORT_RELOAD */
+        PREPROC_PROFILE_END(totalPerfStats);
+        Restart();
+#endif
+    }
+
+    pc.total_from_daq++;
+
+    /* Increment counter that we're evaling rules for caching results */
+    rule_eval_pkt_count++;
+
+#ifdef TARGET_BASED
+    /* Load in a new attribute table if we need to... */
+    AttributeTableReloadCheck();
+#endif
+
+    CheckForReload();
+
+    /* Save off the time of each and every packet */
+    packet_time_update(&pkthdr->ts);
+
+#ifdef REG_TEST
+    if ( snort_conf->pkt_skip && pc.total_from_daq <= snort_conf->pkt_skip )
+    {
+        PREPROC_PROFILE_END(totalPerfStats);
+        return verdict;
+    }
+#endif
+
+#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
+    if (ScTerminateService() || ScPauseService())
+    {
+        PREPROC_PROFILE_END(totalPerfStats);
+        return verdict;  // time to go
+    }
+#endif
+
+    /* reset the thresholding subsystem checks for this packet */
+    sfthreshold_reset();
+
+    PREPROC_PROFILE_START(eventqPerfStats);
+    SnortEventqReset();
+    Replace_ResetQueue();
+#ifdef ACTIVE_RESPONSE
+    Active_ResetQueue();
+#endif
+    PREPROC_PROFILE_END(eventqPerfStats);
+
+    verdict = ProcessPacket(&s_packet, pkthdr, pkt, NULL);
+
+#ifdef ACTIVE_RESPONSE
+    if ( Active_ResponseQueued() )
+    {
+        Active_SendResponses(&s_packet);
+    }
+#endif
+    if ( Active_PacketWasDropped() )
+    {
+        if ( verdict == DAQ_VERDICT_PASS )
+            verdict = DAQ_VERDICT_BLOCK;
+    }
+    else
+    {
+        Replace_ModifyPacket(&s_packet);
+
+        if ( s_packet.packet_flags & PKT_MODIFIED )
+        {
+            // this packet was normalized and/or has replacements
+            Encode_Update(&s_packet);
+            verdict = DAQ_VERDICT_REPLACE;
+        }
+#ifdef NORMALIZER
+        else if ( s_packet.packet_flags & PKT_RESIZED )
+        {
+            // we never increase, only trim, but
+            // daq doesn't support resizing wire packet
+            if ( !DAQ_Inject(s_packet.pkth, 0, s_packet.pkt, s_packet.pkth->pktlen) )
+            {
+                verdict = DAQ_VERDICT_BLOCK;
+                inject = 1;
+            }
+        }
+#endif
+        else
+        {
+            if ((s_packet.packet_flags & PKT_IGNORE) ||
+                (stream_api && (stream_api->get_ignore_direction(s_packet.ssnptr) == SSN_DIR_BOTH)))
+            {
+                if ( !Active_GetTunnelBypass() )
+                {
+                    verdict = DAQ_VERDICT_WHITELIST;
+                }
+                else
+                {
+                    verdict = DAQ_VERDICT_PASS;
+                    pc.internal_whitelist++;
+                }
+            }
+            else if ( s_packet.packet_flags & PKT_TRUST )
+            {
+                if (stream_api)
+                    stream_api->set_ignore_direction(s_packet.ssnptr, SSN_DIR_BOTH);
+
+                verdict = DAQ_VERDICT_WHITELIST;
+            }
+            else
+            {
+                verdict = DAQ_VERDICT_PASS;
+            }
+        }
+    }
+#ifdef ENABLE_HA
+    // This needs to be called here since the session could
+    // have been updated anywhere up to this point. :( 
+    if (stream_api)
+        stream_api->process_ha(s_packet.ssnptr);
+#endif
+
+    /* Collect some "on the wire" stats about packet size, etc */
+    UpdateWireStats(&sfBase, pkthdr->caplen, Active_PacketWasDropped(), inject);
+    Active_Reset();
+    Encode_Reset();
+
+    checkLWSessionTimeout(4, pkthdr->ts.tv_sec);
+    ControlSocketDoWork(0);
+#ifdef SIDE_CHANNEL
+    SideChannelDrainRX(0);
+#endif
+
+    s_packet.pkth = NULL;  // no longer avail on segv
+
+    PREPROC_PROFILE_END(totalPerfStats);
+    return verdict;
+}
+
+/*
+ * Function: ShowUsage(char *)
+ *
+ * Purpose:  Display the program options and exit
+ *
+ * Arguments: argv[0] => name of the program (argv[0])
+ *
+ * Returns: 0 => success
+ */
+static int ShowUsage(char *program_name)
+{
+    fprintf(stdout, "USAGE: %s [-options] <filter options>\n", program_name);
+#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
+    fprintf(stdout, "       %s %s %s [-options] <filter options>\n", program_name
+                                                                   , SERVICE_CMDLINE_PARAM
+                                                                   , SERVICE_INSTALL_CMDLINE_PARAM);
+    fprintf(stdout, "       %s %s %s\n", program_name
+                                       , SERVICE_CMDLINE_PARAM
+                                       , SERVICE_UNINSTALL_CMDLINE_PARAM);
+    fprintf(stdout, "       %s %s %s\n", program_name
+                                       , SERVICE_CMDLINE_PARAM
+                                       , SERVICE_SHOW_CMDLINE_PARAM);
+#endif
+
+#ifdef WIN32
+# define FPUTS_WIN32(msg) fputs(msg,stdout)
+# define FPUTS_UNIX(msg)  NULL
+# define FPUTS_BOTH(msg)  fputs(msg,stdout)
+#else
+# define FPUTS_WIN32(msg)
+# define FPUTS_UNIX(msg)  fputs(msg,stdout)
+# define FPUTS_BOTH(msg)  fputs(msg,stdout)
+#endif
+
+    FPUTS_BOTH ("Options:\n");
+    FPUTS_BOTH ("        -A         Set alert mode: fast, full, console, test or none "
+                                  " (alert file alerts only)\n");
+    FPUTS_UNIX ("                   \"unsock\" enables UNIX socket logging (experimental).\n");
+    FPUTS_BOTH ("        -b         Log packets in tcpdump format (much faster!)\n");
+    FPUTS_BOTH ("        -B <mask>  Obfuscated IP addresses in alerts and packet dumps using CIDR mask\n");
+    FPUTS_BOTH ("        -c <rules> Use Rules File <rules>\n");
+    FPUTS_BOTH ("        -C         Print out payloads with character data only (no hex)\n");
+    FPUTS_BOTH ("        -d         Dump the Application Layer\n");
+    FPUTS_UNIX ("        -D         Run Snort in background (daemon) mode\n");
+    FPUTS_BOTH ("        -e         Display the second layer header info\n");
+    FPUTS_WIN32("        -E         Log alert messages to NT Eventlog. (Win32 only)\n");
+    FPUTS_BOTH ("        -f         Turn off fflush() calls after binary log writes\n");
+    FPUTS_BOTH ("        -F <bpf>   Read BPF filters from file <bpf>\n");
+    FPUTS_UNIX ("        -g <gname> Run snort gid as <gname> group (or gid) after initialization\n");
+    FPUTS_BOTH ("        -G <0xid>  Log Identifier (to uniquely id events for multiple snorts)\n");
+    FPUTS_BOTH ("        -h <hn>    Set home network = <hn>\n"
+                "                   (for use with -l or -B, does NOT change $HOME_NET in IDS mode)\n");
+    FPUTS_BOTH ("        -H         Make hash tables deterministic.\n");
+    FPUTS_BOTH ("        -i <if>    Listen on interface <if>\n");
+    FPUTS_BOTH ("        -I         Add Interface name to alert output\n");
+    FPUTS_BOTH ("        -k <mode>  Checksum mode (all,noip,notcp,noudp,noicmp,none)\n");
+    FPUTS_BOTH ("        -K <mode>  Logging mode (pcap[default],ascii,none)\n");
+    FPUTS_BOTH ("        -l <ld>    Log to directory <ld>\n");
+    FPUTS_BOTH ("        -L <file>  Log to this tcpdump file\n");
+    FPUTS_UNIX ("        -M         Log messages to syslog (not alerts)\n");
+    FPUTS_UNIX ("        -m <umask> Set umask = <umask>\n");
+    FPUTS_BOTH ("        -n <cnt>   Exit after receiving <cnt> packets\n");
+    FPUTS_BOTH ("        -N         Turn off logging (alerts still work)\n");
+    FPUTS_BOTH ("        -O         Obfuscate the logged IP addresses\n");
+    FPUTS_BOTH ("        -p         Disable promiscuous mode sniffing\n");
+    printf     ("        -P <snap>  Set explicit snaplen of packet (default: %d)\n",
+                                    DAQ_GetSnapLen());
+    FPUTS_BOTH ("        -q         Quiet. Don't show banner and status report\n");
+#ifndef WIN32
+    FPUTS_BOTH ("        -Q         Enable inline mode operation.\n");
+#endif
+    FPUTS_BOTH ("        -r <tf>    Read and process tcpdump file <tf>\n");
+    FPUTS_BOTH ("        -R <id>    Include 'id' in snort_intf<id>.pid file name\n");
+    FPUTS_BOTH ("        -s         Log alert messages to syslog\n");
+    FPUTS_BOTH ("        -S <n=v>   Set rules file variable n equal to value v\n");
+    FPUTS_UNIX ("        -t <dir>   Chroots process to <dir> after initialization\n");
+    FPUTS_BOTH ("        -T         Test and report on the current Snort configuration\n");
+    FPUTS_UNIX ("        -u <uname> Run snort uid as <uname> user (or uid) after initialization\n");
+    FPUTS_BOTH ("        -U         Use UTC for timestamps\n");
+    FPUTS_BOTH ("        -v         Be verbose\n");
+    FPUTS_BOTH ("        -V         Show version number\n");
+    FPUTS_WIN32("        -W         Lists available interfaces. (Win32 only)\n");
+#if defined(NON_ETHER_DECODER) && defined(DLT_IEEE802_11)
+    FPUTS_BOTH ("        -w         Dump 802.11 management and control frames\n");
+#endif
+    FPUTS_BOTH ("        -X         Dump the raw packet data starting at the link layer\n");
+    FPUTS_BOTH ("        -x         Exit if Snort configuration problems occur\n");
+    FPUTS_BOTH ("        -y         Include year in timestamp in the alert and log files\n");
+    FPUTS_BOTH ("        -Z <file>  Set the performonitor preprocessor file path and name\n");
+    FPUTS_BOTH ("        -?         Show this information\n");
+    FPUTS_BOTH ("<Filter Options> are standard BPF options, as seen in TCPDump\n");
+
+    FPUTS_BOTH ("Longname options and their corresponding single char version\n");
+    FPUTS_BOTH ("   --logid <0xid>                  Same as -G\n");
+    FPUTS_BOTH ("   --perfmon-file <file>           Same as -Z\n");
+    FPUTS_BOTH ("   --pid-path <dir>                Specify the directory for the Snort PID file\n");
+    FPUTS_BOTH ("   --snaplen <snap>                Same as -P\n");
+    FPUTS_BOTH ("   --help                          Same as -?\n");
+    FPUTS_BOTH ("   --version                       Same as -V\n");
+    FPUTS_BOTH ("   --alert-before-pass             Process alert, drop, sdrop, or reject before pass, default is pass before alert, drop,...\n");
+    FPUTS_BOTH ("   --treat-drop-as-alert           Converts drop, sdrop, and reject rules into alert rules during startup\n");
+    FPUTS_BOTH ("   --treat-drop-as-ignore          Use drop, sdrop, and reject rules to ignore session traffic when not inline.\n");
+    FPUTS_BOTH ("   --process-all-events            Process all queued events (drop, alert,...), default stops after 1st action group\n");
+    FPUTS_BOTH ("   --enable-inline-test            Enable Inline-Test Mode Operation\n");
+    FPUTS_BOTH ("   --dynamic-engine-lib <file>     Load a dynamic detection engine\n");
+    FPUTS_BOTH ("   --dynamic-engine-lib-dir <path> Load all dynamic engines from directory\n");
+    FPUTS_BOTH ("   --dynamic-detection-lib <file>  Load a dynamic rules library\n");
+    FPUTS_BOTH ("   --dynamic-detection-lib-dir <path> Load all dynamic rules libraries from directory\n");
+    FPUTS_BOTH ("   --dump-dynamic-rules <path>     Creates stub rule files of all loaded rules libraries\n");
+    FPUTS_BOTH ("   --dynamic-preprocessor-lib <file>  Load a dynamic preprocessor library\n");
+    FPUTS_BOTH ("   --dynamic-preprocessor-lib-dir <path> Load all dynamic preprocessor libraries from directory\n");
+    FPUTS_BOTH ("   --dynamic-output-lib <file>  Load a dynamic output library\n");
+    FPUTS_BOTH ("   --dynamic-output-lib-dir <path> Load all dynamic output libraries from directory\n");
+    FPUTS_UNIX ("   --create-pidfile                Create PID file, even when not in Daemon mode\n");
+    FPUTS_UNIX ("   --nolock-pidfile                Do not try to lock Snort PID file\n");
+    FPUTS_UNIX ("   --no-interface-pidfile          Do not include the interface name in Snort PID file\n");
+#ifdef INLINE_FAILOPEN
+    FPUTS_UNIX ("   --disable-inline-init-failopen  Do not fail open and pass packets while initializing with inline mode.\n");
+#endif
+#ifdef TARGET_BASED
+    FPUTS_UNIX ("   --disable-attribute-reload-thread Do not create a thread to reload the attribute table\n");
+#endif
+    FPUTS_BOTH ("   --pcap-single <tf>              Same as -r.\n");
+    FPUTS_BOTH ("   --pcap-file <file>              file that contains a list of pcaps to read - read mode is implied.\n");
+    FPUTS_BOTH ("   --pcap-list \"<list>\"            a space separated list of pcaps to read - read mode is implied.\n");
+    FPUTS_UNIX ("   --pcap-dir <dir>                a directory to recurse to look for pcaps - read mode is implied.\n");
+    FPUTS_UNIX ("   --pcap-filter <filter>          filter to apply when getting pcaps from file or directory.\n");
+    FPUTS_UNIX ("   --pcap-no-filter                reset to use no filter when getting pcaps from file or directory.\n");
+    FPUTS_BOTH ("   --pcap-loop <count>             this option will read the pcaps specified on command line continuously.\n"
+                "                                   for <count> times.  A value of 0 will read until Snort is terminated.\n");
+    FPUTS_BOTH ("   --pcap-reset                    if reading multiple pcaps, reset snort to post-configuration state before reading next pcap.\n");
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+    FPUTS_BOTH ("   --pcap-reload                   if reading multiple pcaps, reload snort config between pcaps.\n");
+#endif
+    FPUTS_BOTH ("   --pcap-show                     print a line saying what pcap is currently being read.\n");
+    FPUTS_BOTH ("   --exit-check <count>            Signal termination after <count> callbacks from DAQ_Acquire(), showing the time it\n"
+                "                                   takes from signaling until DAQ_Stop() is called.\n");
+    FPUTS_BOTH ("   --conf-error-out                Same as -x\n");
+#ifdef MPLS
+    FPUTS_BOTH ("   --enable-mpls-multicast         Allow multicast MPLS\n");
+    FPUTS_BOTH ("   --enable-mpls-overlapping-ip    Handle overlapping IPs within MPLS clouds\n");
+    FPUTS_BOTH ("   --max-mpls-labelchain-len       Specify the max MPLS label chain\n");
+    FPUTS_BOTH ("   --mpls-payload-type             Specify the protocol (ipv4, ipv6, ethernet) that is encapsulated by MPLS\n");
+#endif
+    FPUTS_BOTH ("   --require-rule-sid              Require that all snort rules have SID specified.\n");
+    FPUTS_BOTH ("   --daq <type>                    Select packet acquisition module (default is pcap).\n");
+    FPUTS_BOTH ("   --daq-mode <mode>               Select the DAQ operating mode.\n");
+    FPUTS_BOTH ("   --daq-var <name=value>          Specify extra DAQ configuration variable.\n");
+    FPUTS_BOTH ("   --daq-dir <dir>                 Tell snort where to find desired DAQ.\n");
+    FPUTS_BOTH ("   --daq-list[=<dir>]              List packet acquisition modules available in dir.  Default is static modules only.\n");
+    FPUTS_BOTH ("   --dirty-pig                     Don't flush packets and release memory on shutdown.\n");
+    FPUTS_BOTH ("   --cs-dir <dir>                  Directory to use for control socket.\n");
+    FPUTS_BOTH ("   --ha-peer                       Activate live high-availability state sharing with peer.\n");
+    FPUTS_BOTH ("   --ha-out <file>                 Write high-availability events to this file.\n");
+    FPUTS_BOTH ("   --ha-in <file>                  Read high-availability events from this file on startup (warm-start).\n");
+#undef FPUTS_WIN32
+#undef FPUTS_UNIX
+#undef FPUTS_BOTH
+    return 0;
+}
+
+static void ParseCmdLineDynamicLibInfo(SnortConfig *sc, int type, char *path)
+{
+    DynamicLibInfo *dli = NULL;
+    DynamicLibPath *dlp = NULL;
+
+    if ((sc == NULL) || (path == NULL))
+        FatalError("%s(%d) NULL arguments.\n", __FILE__, __LINE__);
+
+    switch (type)
+    {
+        case DYNAMIC_PREPROC_FILE:
+        case DYNAMIC_PREPROC_DIRECTORY:
+            DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Dynamic preprocessor specifier\n"););
+            if (sc->dyn_preprocs == NULL)
+            {
+                sc->dyn_preprocs = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo));
+                sc->dyn_preprocs->type = DYNAMIC_TYPE__PREPROCESSOR;
+            }
+            else if (sc->dyn_preprocs->count >= MAX_DYNAMIC_LIBS)
+            {
+                FatalError("Maximum number of loaded Dynamic Preprocessor Libs "
+                           "(%d) exceeded.\n", MAX_DYNAMIC_LIBS);
+            }
+
+            dli = sc->dyn_preprocs;
+            break;
+
+        case DYNAMIC_LIBRARY_FILE:
+        case DYNAMIC_LIBRARY_DIRECTORY:
+            DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Dynamic detection specifier\n"););
+            if (sc->dyn_rules == NULL)
+            {
+                sc->dyn_rules = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo));
+                sc->dyn_rules->type = DYNAMIC_TYPE__DETECTION;
+            }
+            else if (sc->dyn_rules->count >= MAX_DYNAMIC_LIBS)
+            {
+                FatalError("Maximum number of loaded Dynamic Detection Libs "
+                           "(%d) exceeded.\n", MAX_DYNAMIC_LIBS);
+            }
+
+            dli = sc->dyn_rules;
+            break;
+
+        case DYNAMIC_ENGINE_FILE:
+        case DYNAMIC_ENGINE_DIRECTORY:
+            DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Dynamic engine specifier\n"););
+            if (sc->dyn_engines == NULL)
+            {
+                sc->dyn_engines = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo));
+                sc->dyn_engines->type = DYNAMIC_TYPE__ENGINE;
+            }
+            else if (sc->dyn_engines->count >= MAX_DYNAMIC_LIBS)
+            {
+                FatalError("Maximum number of loaded Dynamic Engine Libs "
+                           "(%d) exceeded.\n", MAX_DYNAMIC_LIBS);
+            }
+
+            dli = sc->dyn_engines;
+            break;
+        case DYNAMIC_OUTPUT_FILE:
+            output_load_module(path);
+            return;
+            break;
+        case DYNAMIC_OUTPUT_DIRECTORY:
+            output_load(path);
+            return;
+            break;
+
+
+        default:
+            FatalError("%s(%d) Invalid dynamic type: %d\n", __FILE__, __LINE__, type);
+            break;
+    }
+
+    dlp = (DynamicLibPath *)SnortAlloc(sizeof(DynamicLibPath));
+    switch (type)
+    {
+        case DYNAMIC_PREPROC_FILE:
+        case DYNAMIC_LIBRARY_FILE:
+        case DYNAMIC_ENGINE_FILE:
+        case DYNAMIC_OUTPUT_FILE:
+            dlp->ptype = PATH_TYPE__FILE;
+            break;
+
+        case DYNAMIC_PREPROC_DIRECTORY:
+        case DYNAMIC_LIBRARY_DIRECTORY:
+        case DYNAMIC_ENGINE_DIRECTORY:
+        case DYNAMIC_OUTPUT_DIRECTORY:
+            dlp->ptype = PATH_TYPE__DIRECTORY;
+            break;
+
+        default:
+            FatalError("%s(%d) Invalid dynamic type: %d\n", __FILE__, __LINE__, type);
+            break;
+    }
+
+    dlp->path = SnortStrdup(path);
+    dli->lib_paths[dli->count] = dlp;
+    dli->count++;
+}
+
+/*
+ * Function: ParseCmdLine(int, char **)
+ *
+ * Parses command line arguments
+ *
+ * Arguments:
+ *  int
+ *      count of arguments passed to the routine
+ *  char **
+ *      2-D character array, contains list of command line args
+ *
+ * Returns: None
+ *
+ */
+
+static void ParseCmdLine(int argc, char **argv)
+{
+    int ch;
+    int option_index = -1;
+    char *endptr;   /* for SnortStrtol calls */
+    SnortConfig *sc;
+    int output_logging = 0;
+    int output_alerting = 0;
+    int syslog_configured = 0;
+#ifndef WIN32
+    int daemon_configured = 0;
+#endif
+
+    DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Parsing command line...\n"););
+
+    if (snort_cmd_line_conf != NULL)
+    {
+        FatalError("%s(%d) Trying to parse the command line again.\n",
+                   __FILE__, __LINE__);
+    }
+
+    snort_cmd_line_conf = SnortConfNew();
+    snort_conf = snort_cmd_line_conf;     /* Set the global for log messages */
+    sc = snort_cmd_line_conf;
+
+    optind = 1;
+
+    /* Look for a -D and/or -M switch so we can start logging to syslog
+     * with "snort" tag right away */
+    while ((ch = getopt_long(argc, argv, valid_options, long_options, &option_index)) != -1)
+    {
+        switch (ch)
+        {
+            case 'M':
+                if (syslog_configured)
+                    break;
+
+                /* If daemon or logging to syslog use "snort" as identifier and
+                 * start logging there now */
+                openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
+
+                sc->logging_flags |= LOGGING_FLAG__SYSLOG;
+                syslog_configured = 1;
+                break;
+
+#ifndef WIN32
+            case 'E':
+                sc->run_flags |= RUN_FLAG__DAEMON_RESTART;
+                /* Fall through */
+            case 'D':
+                if (daemon_configured)
+                    break;
+
+                /* If daemon or logging to syslog use "snort" as identifier and
+                 * start logging there now */
+                openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
+
+                ConfigDaemon(sc, optarg);
+                daemon_configured = 1;
+                break;
+#endif
+
+            case 'q':
+                /* Turn on quiet mode if configured so any log messages that may
+                 * be printed while parsing the command line before the quiet option
+                 * is read won't be printed */
+                ConfigQuiet(sc, NULL);
+                break;
+
+            case '?':  /* show help and exit with 1 */
+                PrintVersion();
+                ShowUsage(argv[0]);
+                exit(1);
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    /*
+    **  Set this so we know whether to return 1 on invalid input.
+    **  Snort uses '?' for help and getopt uses '?' for telling us there
+    **  was an invalid option, so we can't use that to tell invalid input.
+    **  Instead, we check optopt and it will tell us.
+    */
+    optopt = 0;
+    optind = 1;
+
+    /* loop through each command line var and process it */
+    while ((ch = getopt_long(argc, argv, valid_options, long_options, &option_index)) != -1)
+    {
+        DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Processing cmd line switch: %c\n", ch););
+
+        switch (ch)
+        {
+            case DYNAMIC_ENGINE_FILE:       /* Load dynamic engine specified */
+            case DYNAMIC_ENGINE_DIRECTORY:  /* Load dynamic engine specified */
+            case DYNAMIC_PREPROC_FILE:      /* Load dynamic preprocessor lib specified */
+            case DYNAMIC_PREPROC_DIRECTORY:
+            case DYNAMIC_LIBRARY_FILE:      /* Load dynamic detection lib specified */
+            case DYNAMIC_LIBRARY_DIRECTORY:
+            case DYNAMIC_OUTPUT_FILE:      /* Load dynamic output lib specified */
+            case DYNAMIC_OUTPUT_DIRECTORY:
+                ParseCmdLineDynamicLibInfo(sc, ch, optarg);
+                break;
+
+            case DUMP_DYNAMIC_RULES:
+                ConfigDumpDynamicRulesPath(sc, optarg);
+                break;
+
+            case ALERT_BEFORE_PASS:
+                ConfigAlertBeforePass(sc, NULL);
+                break;
+
+            case PROCESS_ALL_EVENTS:
+                ConfigProcessAllEvents(sc, NULL);
+                break;
+
+            case TREAT_DROP_AS_ALERT:
+                ConfigTreatDropAsAlert(sc, NULL);
+                break;
+
+            case TREAT_DROP_AS_IGNORE:
+                ConfigTreatDropAsIgnore(sc, NULL);
+                break;
+
+            case PID_PATH:
+                ConfigPidPath(sc, optarg);
+                break;
+
+            case CREATE_PID_FILE:
+                ConfigCreatePidFile(sc, NULL);
+                break;
+
+            case NOLOCK_PID_FILE:
+                sc->run_flags |= RUN_FLAG__NO_LOCK_PID_FILE;
+                break;
+
+            case NO_IFACE_PID_FILE:
+                sc->run_flags |= RUN_FLAG__NO_IFACE_PID_FILE;
+                break;
+
+#ifdef INLINE_FAILOPEN
+            case DISABLE_INLINE_FAILOPEN:
+                ConfigDisableInlineFailopen(sc, NULL);
+                break;
+#endif
+            case NO_LOGGING_TIMESTAMPS:
+                ConfigNoLoggingTimestamps(sc, NULL);
+                break;
+
+#ifdef EXIT_CHECK
+            case ARG_EXIT_CHECK:
+                {
+                    char* endPtr;
+
+                    sc->exit_check = SnortStrtoul(optarg, &endPtr, 0);
+                    if ((errno == ERANGE) || (*endPtr != '\0'))
+                        FatalError("--exit-check value must be non-negative integer\n");
+
+                    LogMessage("Exit Check: limit = "STDu64" callbacks\n", (long long unsigned int)sc->exit_check);
+                }
+
+                break;
+#endif
+
+#ifdef TARGET_BASED
+            case DISABLE_ATTRIBUTE_RELOAD:
+                ConfigDisableAttributeReload(sc, NULL);
+                break;
+#endif
+            case DETECTION_SEARCH_METHOD:
+                if (sc->fast_pattern_config != NULL)
+                    FatalError("Can only configure search method once.\n");
+
+                sc->fast_pattern_config = FastPatternConfigNew();
+
+                if (fpSetDetectSearchMethod(sc->fast_pattern_config, optarg) == -1)
+                    FatalError("Invalid search method: %s.\n", optarg);
+
+                break;
+
+            case ARG_DAQ_TYPE:
+                ConfigDaqType(sc, optarg);
+                break;
+
+            case ARG_DAQ_MODE:
+                ConfigDaqMode(sc, optarg);
+                break;
+
+            case ARG_DAQ_VAR:
+                ConfigDaqVar(sc, optarg);
+                break;
+
+            case ARG_DAQ_DIR:
+                ConfigDaqDir(sc, optarg);
+                break;
+
+            case ARG_DAQ_LIST:
+                PrintDaqModules(sc, optarg);
+                exit(0);
+                break;
+
+            case ARG_DIRTY_PIG:
+                ConfigDirtyPig(sc, optarg);
+                break;
+
+            case 'A':  /* alert mode */
+                output_alerting = 1;
+
+                if (strcasecmp(optarg, ALERT_MODE_OPT__NONE) == 0)
+                {
+                    sc->no_alert = 1;
+                }
+                else if (strcasecmp(optarg, ALERT_MODE_OPT__PKT_CNT) == 0)
+                {
+                    /* print packet count at start of alert */
+                    sc->output_flags |= OUTPUT_FLAG__ALERT_PKT_CNT;
+                }
+                else if (strcasecmp(optarg, ALERT_MODE_OPT__FULL) == 0)
+                {
+                    ParseOutput(sc, NULL, "alert_full");
+                }
+                else if (strcasecmp(optarg, "console:" ALERT_MODE_OPT__FULL) == 0)
+                {
+                    ParseOutput(sc, NULL, "alert_full: stdout");
+                }
+                else if (strcasecmp(optarg, ALERT_MODE_OPT__FAST) == 0)
+                {
+                    ParseOutput(sc, NULL, "alert_fast");
+                }
+                else if (
+                    strcasecmp(optarg, "console:" ALERT_MODE_OPT__FAST) == 0 ||
+                    strcasecmp(optarg, ALERT_MODE_OPT__CONSOLE) == 0 )
+                {
+                    ParseOutput(sc, NULL, "alert_fast: stdout");
+                }
+                else if ((strcasecmp(optarg, ALERT_MODE_OPT__CMG) == 0) ||
+                         (strcasecmp(optarg, ALERT_MODE_OPT__JH) == 0) ||
+                         (strcasecmp(optarg, ALERT_MODE_OPT__DJR) == 0))
+                {
+                    ParseOutput(sc, NULL, "alert_fast: stdout packet");
+                    sc->no_log = 1;
+                    /* turn on layer2 headers */
+                    sc->output_flags |= OUTPUT_FLAG__SHOW_DATA_LINK;
+                    /* turn on data dump */
+                    sc->output_flags |= OUTPUT_FLAG__APP_DATA;
+                }
+                else if (strcasecmp(optarg, ALERT_MODE_OPT__AJK) == 0)
+                {
+                    ParseOutput(sc, NULL, "unified2");
+                }
+                else if (strcasecmp(optarg, ALERT_MODE_OPT__UNIX_SOCK) == 0)
+                {
+                    ParseOutput(sc, NULL, "alert_unixsock");
+                }
+                else if (strcasecmp(optarg, ALERT_MODE_OPT__TEST) == 0)
+                {
+                    ParseOutput(sc, NULL, "alert_test");
+                    sc->no_log = 1;
+                }
+                else if (strcasecmp(optarg, "console:" ALERT_MODE_OPT__TEST) == 0)
+                {
+                    ParseOutput(sc, NULL, "alert_test: stdout");
+                    sc->no_log = 1;
+                }
+                else
+                {
+                    FatalError("Unknown command line alert option: %s\n", optarg);
+                }
+
+                break;
+
+            case 'b':  /* log packets in binary format for post-processing */
+                ParseOutput(sc, NULL, "log_tcpdump");
+                output_logging = 1;
+                break;
+
+            case 'B':  /* obfuscate with a substitution mask */
+                ConfigObfuscationMask(sc, optarg);
+                break;
+
+            case 'c':  /* use configuration file x */
+                sc->run_mode_flags |= RUN_MODE_FLAG__IDS;
+                snort_conf_file = SnortStrdup(optarg);
+                break;
+
+            case 'C':  /* dump the application layer as text only */
+                ConfigDumpCharsOnly(sc, NULL);
+                break;
+
+            case 'd':  /* dump the application layer data */
+                ConfigDumpPayload(sc, NULL);
+                break;
+
+#ifndef WIN32
+            case 'E':  /* Restarting from daemon mode */
+            case 'D':  /* daemon mode */
+                /* These are parsed at the beginning so as to start logging
+                 * to syslog right away */
+                break;
+#endif
+
+            case 'e':  /* show second level header info */
+                ConfigDecodeDataLink(sc, NULL);
+                break;
+#ifdef WIN32
+            case 'E':  /* log alerts to Event Log */
+                ParseOutput(sc, NULL, "alert_syslog");
+                sc->logging_flags &= ~LOGGING_FLAG__SYSLOG_REMOTE;
+                output_alerting = 1;
+                break;
+#endif
+            case 'f':
+                sc->output_flags |= OUTPUT_FLAG__LINE_BUFFER;
+                break;
+
+            case 'F':   /* read BPF filter in from a file */
+                ConfigBpfFile(sc, optarg);
+                break;
+
+#ifndef WIN32
+            case 'g':   /* setgid */
+                ConfigSetGid(sc, optarg);
+                break;
+#endif
+
+            case 'G':  /* snort loG identifier */
+                sc->event_log_id = SnortStrtoul(optarg, &endptr, 0);
+                if ((errno == ERANGE) || (*endptr != '\0') ||
+                    (sc->event_log_id > UINT16_MAX))
+                {
+                    FatalError("Snort log identifier invalid: %s.  It must "
+                               "be between 0 and %u.\n", optarg, UINT16_MAX);
+                }
+
+                /* Forms upper 2 bytes.  Lower two bytes are the event id */
+                sc->event_log_id <<= 16;
+
+                break;
+
+            case 'h':
+                /* set home network to x, this will help determine what to set
+                 * logging diectories to */
+                ConfigReferenceNet(sc, optarg);
+                break;
+
+            case 'H':
+                sc->run_flags |= RUN_FLAG__STATIC_HASH;
+                break;
+
+            case 'i':
+                ConfigInterface(sc, optarg);
+                break;
+
+            case 'I':  /* add interface name to alert string */
+                ConfigAlertWithInterfaceName(sc, NULL);
+                break;
+
+            case 'k':  /* set checksum mode */
+                ConfigChecksumMode(sc, optarg);
+                break;
+
+            case 'K':  /* log mode */
+                if (strcasecmp(optarg, LOG_MODE_OPT__NONE) == 0)
+                {
+                    sc->no_log = 1;
+                }
+                else if (strcasecmp(optarg, LOG_MODE_OPT__PCAP) == 0)
+                {
+                    ParseOutput(sc, NULL, "log_tcpdump");
+                }
+                else if (strcasecmp(optarg, LOG_MODE_OPT__ASCII) == 0)
+                {
+                    ParseOutput(sc, NULL, "log_ascii");
+                }
+                else
+                {
+                    FatalError("Unknown command line log option: %s\n", optarg);
+                }
+
+                output_logging = 1;
+                break;
+
+            case 'l':  /* use log dir <X> */
+                ConfigLogDir(sc, optarg);
+                break;
+
+            case 'L':  /* set BinLogFile name */
+                /* implies tcpdump format logging
+                 * 256 is kind of arbitrary but should be more than enough */
+                if (strlen(optarg) < 256)
+                {
+                    ParseOutput(sc, NULL, "log_tcpdump");
+                    sc->pcap_log_file = SnortStrdup(optarg);
+                }
+                else
+                {
+                    FatalError("log_tcpdump file name \"%s\" has to be less "
+                               "than or equal to 256 characters.\n", optarg);
+                }
+
+                output_logging = 1;
+                break;
+
+            case 'M':
+                /* This is parsed at the beginning so as to start logging
+                 * to syslog right away */
+                break;
+
+#ifndef WIN32
+            case 'm':  /* set the umask for the output files */
+                ConfigUmask(sc, optarg);
+                break;
+#endif
+
+            case 'n':  /* grab x packets and exit */
+                ConfigPacketCount(sc, optarg);
+                break;
+
+            case 'N':  /* no logging mode */
+                ConfigNoLog(sc, NULL);
+                break;
+
+            case 'O':  /* obfuscate the logged IP addresses for privacy */
+                ConfigObfuscate(sc, NULL);
+                break;
+
+            case 'p':  /* disable explicit promiscuous mode */
+                ConfigNoPromiscuous(sc, NULL);
+                break;
+
+            case 'P':  /* explicitly define snaplength of packets */
+                ConfigPacketSnaplen(sc, optarg);
+                break;
+
+            case 'q':  /* no stdout output mode */
+                /* This is parsed at the beginning so as to start logging
+                 * in quiet mode right away */
+                break;
+
+#ifndef WIN32
+            case 'Q':
+                LogMessage("Enabling inline operation\n");
+                sc->run_flags |= RUN_FLAG__INLINE;
+                break;
+#endif
+            case ENABLE_INLINE_TEST:
+                LogMessage("Enable Inline Test Mode\n");
+                sc->run_flags |= RUN_FLAG__INLINE_TEST;
+                break;
+
+
+            case 'r':  /* read packets from a TCPdump file instead of the net */
+            case PCAP_SINGLE:
+                PQ_Single(optarg);
+                sc->run_flags |= RUN_FLAG__READ;
+                break;
+
+            case 'R': /* augment pid file name suffix */
+                if ((strlen(optarg) >= MAX_PIDFILE_SUFFIX) || (strlen(optarg) <= 0) ||
+                    (strstr(optarg, "..") != NULL) || (strstr(optarg, "/") != NULL))
+                {
+                        FatalError("Invalid pidfile suffix: %s.  Suffix must "
+                                   "less than %u characters and not have "
+                                   "\"..\" or \"/\" in the name.\n", optarg,
+                                   MAX_PIDFILE_SUFFIX);
+                }
+
+                SnortStrncpy(sc->pidfile_suffix, optarg, sizeof(sc->pidfile_suffix));
+                break;
+
+            case 's':  /* log alerts to syslog */
+#ifndef WIN32
+                ParseOutput(sc, NULL, "alert_syslog");
+#else
+                sc->logging_flags |= LOGGING_FLAG__SYSLOG_REMOTE;
+#endif
+                output_alerting = 1;
+                break;
+
+            case 'S':  /* set a rules file variable */
+                {
+                    char *equal_ptr = strchr(optarg, '=');
+                    VarNode *node;
+
+                    if (equal_ptr == NULL)
+                    {
+                        FatalError("Format for command line variable definitions "
+                                   "is:\n -S var=value\n");
+                    }
+
+                    /* Save these and parse when snort conf is parsed so
+                     * they can be added to the snort conf configuration */
+                    node = (VarNode *)SnortAlloc(sizeof(VarNode));
+                    node->name = SnortStrndup(optarg, equal_ptr - optarg);
+
+                    /* Make sure it's not already in the list */
+                    if (cmd_line_var_list != NULL)
+                    {
+                        VarNode *tmp = cmd_line_var_list;
+
+                        while (tmp != NULL)
+                        {
+                            if (strcasecmp(tmp->name, node->name) == 0)
+                            {
+                                FreeVarList(cmd_line_var_list);
+                                FatalError("Duplicate variable name: %s.\n",
+                                           tmp->name);
+                            }
+
+                            tmp = tmp->next;
+                        }
+                    }
+
+                    node->value = SnortStrdup(equal_ptr + 1);
+                    node->line = SnortStrdup(optarg);
+                    node->next = cmd_line_var_list;
+                    cmd_line_var_list = node;
+
+                    /* Put line in a parser parsable form - we know the
+                     * equals is already there */
+                    equal_ptr = strchr(node->line, '=');
+                    *equal_ptr = ' ';
+                }
+
+                break;
+
+#ifndef WIN32
+            case 't':  /* chroot to the user specified directory */
+                ConfigChrootDir(sc, optarg);
+                break;
+#endif
+
+            case 'T':  /* test mode, verify that the rules load properly */
+                sc->run_mode_flags |= RUN_MODE_FLAG__TEST;
+                break;
+
+#ifndef WIN32
+            case 'u':  /* setuid */
+                ConfigSetUid(sc, optarg);
+                break;
+#endif
+
+            case 'U':  /* use UTC */
+                ConfigUtc(sc, NULL);
+                break;
+
+            case 'v':  /* be verbose */
+                ConfigVerbose(sc, NULL);
+                break;
+
+            case 'V':  /* prog ver already gets printed out, so we just exit */
+                sc->run_mode_flags |= RUN_MODE_FLAG__VERSION;
+                sc->logging_flags |= LOGGING_FLAG__QUIET;
+                break;
+
+#ifdef WIN32
+            case 'W':
+                PrintVersion();
+                PrintAllInterfaces();
+                exit(0);  /* XXX Should maybe use CleanExit here? */
+                break;
+#endif
+
+#if !defined(NO_NON_ETHER_DECODER) && defined(DLT_IEEE802_11)
+            case 'w':  /* show 802.11 all frames info */
+                sc->output_flags |= OUTPUT_FLAG__SHOW_WIFI_MGMT;
+                break;
+#endif
+            case 'X':  /* display verbose packet bytecode dumps */
+                ConfigDumpPayloadVerbose(sc, NULL);
+                break;
+
+            case 'x':
+                sc->run_flags |= RUN_FLAG__CONF_ERROR_OUT;
+                break;
+
+            case 'y':  /* Add year to timestamp in alert and log files */
+                ConfigShowYear(sc, NULL);
+                break;
+
+            case 'Z':  /* Set preprocessor perfmon file path/filename */
+                ConfigPerfFile(sc, optarg);
+                break;
+
+            case PCAP_FILE_LIST:
+            case PCAP_LIST:
+#ifndef WIN32
+            case PCAP_DIR:
+#endif
+                PQ_Multi((char)ch, optarg);
+                sc->run_flags |= RUN_FLAG__READ;
+                break;
+
+            case PCAP_LOOP:
+                {
+                    long int loop_count = SnortStrtol(optarg, &endptr, 0);
+
+                    if ((errno == ERANGE) || (*endptr != '\0') ||
+                        (loop_count < 0) || (loop_count > 2147483647))
+                    {
+                        FatalError("Valid values for --pcap-loop are between 0 and 2147483647\n");
+                    }
+
+                    if (loop_count == 0)
+                        pcap_loop_count = -1;
+                    else
+                        pcap_loop_count = loop_count;
+                }
+
+                break;
+
+            case PCAP_RESET:
+                sc->run_flags |= RUN_FLAG__PCAP_RESET;
+                break;
+
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+            case PCAP_RELOAD:
+                sc->run_flags |= RUN_FLAG__PCAP_RELOAD;
+                break;
+#endif
+
+#ifndef WIN32
+            case PCAP_FILTER:
+                PQ_SetFilter(optarg);
+                break;
+
+            case PCAP_NO_FILTER:
+                PQ_SetFilter(NULL);
+                break;
+#endif
+
+            case PCAP_SHOW:
+                sc->run_flags |= RUN_FLAG__PCAP_SHOW;
+                break;
+#ifdef MPLS
+            case ENABLE_MPLS_MULTICAST:
+                ConfigEnableMplsMulticast(sc, NULL);
+                break;
+
+            case ENABLE_OVERLAPPING_IP:
+                ConfigEnableMplsOverlappingIp(sc, NULL);
+                break;
+
+            case MAX_MPLS_LABELCHAIN_LEN:
+                ConfigMaxMplsLabelChain(sc, optarg);
+                break;
+
+            case MPLS_PAYLOAD_TYPE:
+                ConfigMplsPayloadType(sc, optarg);
+                break;
+#endif
+            case REQUIRE_RULE_SID:
+                sc->run_flags |= RUN_FLAG__REQUIRE_RULE_SID;
+                break;
+
+            case ARG_CS_DIR:
+                if ( optarg != NULL )
+                    sc->cs_dir = SnortStrdup(optarg);
+                break;
+#ifdef REG_TEST
+            case ARG_HA_PEER:
+                sc->ha_peer = true;
+                break;
+
+            case ARG_HA_OUT:
+                sc->ha_out = SnortStrdup(optarg);
+                break;
+
+            case ARG_HA_IN:
+                sc->ha_in = SnortStrdup(optarg);
+                break;
+#endif
+
+            case '?':  /* show help and exit with 1 */
+                PrintVersion();
+                ShowUsage(argv[0]);
+                /* XXX Should do a clean exit */
+                exit(1);
+                break;
+
+            default:
+                FatalError("Invalid option: %c.\n", ch);
+                break;
+        }
+    }
+
+    sc->bpf_filter = copy_argv(&argv[optind]);
+
+    if ((sc->run_mode_flags & RUN_MODE_FLAG__TEST) &&
+        (sc->run_flags & RUN_FLAG__DAEMON))
+    {
+        FatalError("Cannot use test mode and daemon mode together.\n"
+                   "To verify configuration, run first in test "
+                   "mode and then restart in daemon mode.\n");
+    }
+
+    if ((sc->run_flags & RUN_FLAG__INLINE) &&
+            (sc->run_flags & RUN_FLAG__INLINE_TEST))
+    {
+        FatalError("Cannot use inline adapter mode and inline test "
+                "mode together. \n");
+    }
+
+    // TBD no reason why command line args only can't be checked
+    // marginally useful, perhaps, but why do we go out of our way
+    // to make things hard on the user?
+    if ((sc->run_mode_flags & RUN_MODE_FLAG__TEST) &&
+        (snort_conf_file == NULL))
+    {
+        FatalError("Test mode must be run with a snort configuration "
+                   "file.  Use the '-c' option on the command line to "
+                   "specify a configuration file.\n");
+    }
+    if (pcap_loop_count && !(sc->run_flags & RUN_FLAG__READ))
+    {
+        FatalError("--pcap-loop can only be used in combination with pcaps "
+                   "on the command line.\n");
+    }
+
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+    if ((sc->run_flags & RUN_FLAG__PCAP_RELOAD) &&
+        !(sc->run_flags & RUN_FLAG__READ))
+    {
+        FatalError("--pcap-reload can only be used in combination with pcaps "
+                   "on the command line.\n");
+    }
+#endif
+
+    /* Set the run mode based on what we've got from command line */
+
+    /* Version overrides all */
+    if (sc->run_mode_flags & RUN_MODE_FLAG__VERSION)
+    {
+        sc->run_mode = RUN_MODE__VERSION;
+    }
+    /* Next dumping so rule stubs */
+    else if (sc->run_mode_flags & RUN_MODE_FLAG__RULE_DUMP)
+    {
+        sc->run_mode = RUN_MODE__RULE_DUMP;
+    }
+    /* Next if we want to test a snort conf */
+    else if (sc->run_mode_flags & RUN_MODE_FLAG__TEST)
+    {
+        sc->run_mode = RUN_MODE__TEST;
+    }
+    /* Now if there is a snort conf.  If a snort conf wasn't given on the
+     * command line, we'll look in a default place if the next ones
+     * don't match */
+    else if ((sc->run_mode_flags & RUN_MODE_FLAG__IDS) && (snort_conf_file != NULL))
+    {
+        sc->run_mode = RUN_MODE__IDS;
+    }
+    /* If logging but not alerting or log directory is set */
+    else if ((output_logging && !output_alerting) || (sc->log_dir != NULL))
+    {
+        sc->no_alert = 1;
+        sc->run_mode = RUN_MODE__PACKET_LOG;
+    }
+    /* If none of the above and not logging or alerting and verbose */
+    else if ((!output_logging && !output_alerting) &&
+             (sc->logging_flags & LOGGING_FLAG__VERBOSE))
+    {
+        sc->no_alert = 1;
+        sc->no_log = 1;
+        sc->run_mode = RUN_MODE__PACKET_DUMP;
+    }
+
+#if 1
+    if (!sc->run_mode)
+    {
+        sc->no_alert = 1;
+        sc->no_log = 1;
+        sc->run_mode = RUN_MODE__PACKET_DUMP;
+    }
+#else
+    if (!sc->run_mode)
+        sc->run_mode = RUN_MODE__IDS;
+
+    /* If mode mandates a conf and we don't have one,  check for default. */
+    if (((sc->run_mode == RUN_MODE__IDS) || (sc->run_mode == RUN_MODE__TEST)) &&
+        (snort_conf_file == NULL))
+    {
+        snort_conf_file = ConfigFileSearch();
+        if (snort_conf_file == NULL)
+        {
+            DisplayBanner();
+            ShowUsage(argv[0]);
+            FatalError("\n\nUh, you need to tell me to do something...");
+        }
+    }
+#endif
+
+    if ((sc->run_mode == RUN_MODE__PACKET_LOG) &&
+        (sc->output_configs == NULL))
+    {
+        ParseOutput(sc, NULL, "log_tcpdump");
+    }
+
+    switch ( snort_conf->run_mode )
+    {
+        case RUN_MODE__IDS:
+            if (ScLogVerbose())
+                log_func = PrintPacket;
+            break;
+
+        case RUN_MODE__PACKET_LOG:
+            log_func = LogPacket;
+            break;
+
+        case RUN_MODE__PACKET_DUMP:
+            log_func = PrintPacket;
+            break;
+
+        default:
+            break;
+    }
+    SetSnortConfDir();
+}
+
+/*
+ * Function: SetPktProcessor()
+ *
+ * Purpose:  Set root decoder based on datalink
+ */
+// TBD add GetDecoder(dlt) to decode module and hide all
+// protocol decoder functions.
+static int SetPktProcessor(void)
+{
+	const char* slink = NULL;
+	const char* extra = NULL;
+	int dlt = DLT_EN10MB;
+
+	switch ( dlt )
+	{
+		case DLT_EN10MB:
+			slink = "Ethernet";
+			grinder = DecodeEthPkt;
+			break;
+		default:
+			/* oops, don't know how to handle this one */
+			FatalError("Cannot decode data link type %d\n", dlt);
+			break;
+	}
+	if ( !ScReadMode() || ScPcapShow() )
+	{
+		LogMessage("Decoding %s\n", slink);
+	}
+	if (extra && ScOutputDataLink())
+	{
+		LogMessage("%s\n", extra);
+		snort_conf->output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK;
+	}
+#ifdef ACTIVE_RESPONSE
+	Encode_Init();
+#endif
+	return 0;
+}
+/*
+ *  Handle idle time checks in snort packet processing loop
+ */
+static void SnortIdle(void)
+{
+    /* Rollover of performance log */
+    if (IsSetRotatePerfFileFlag())
+    {
+        sfRotateBaseStatsFile(perfmon_config);
+        sfRotateFlowStatsFile(perfmon_config);
+        ClearRotatePerfFileFlag();
+    }
+#ifdef OPENBSD
+    else if (reload_signal != reload_total)
+        nanosleep(&packet_sleep, NULL);
+#endif
+
+    checkLWSessionTimeout(16384, time(NULL));
+    ControlSocketDoWork(1);
+#ifdef SIDE_CHANNEL
+    SideChannelDrainRX(0);
+#endif
+    IdleProcessingExecute();
+}
+
+void PacketLoop (void)
+{
+    int error;
+    int pkts_to_read = (int)snort_conf->pkt_cnt;
+
+    TimeStart();
+
+    while ( !exit_logged )
+    {
+        error = DAQ_Acquire(pkts_to_read, PacketCallback, NULL);
+
+#ifdef SIDE_CHANNEL
+        /* If we didn't manage to lock the process lock in a DAQ acquire callback, lock it now. */
+        if (ScSideChannelEnabled() && !snort_process_lock_held)
+        {
+            pthread_mutex_lock(&snort_process_lock);
+            snort_process_lock_held = true;
+        }
+#endif
+
+        if ( error )
+        {
+            if ( !ScReadMode() || !PQ_Next() )
+            {
+                /* If not read-mode or no next pcap, we're done */
+                break;
+            }
+        }
+        /* Check for any pending signals when no packets are read*/
+        else
+        {
+            // TBD SnortIdle() only checks for perf file rotation
+            // and that can only be done after calling SignalCheck()
+            // so either move SnortIdle() to SignalCheck() or directly
+            // set the flag in the signal handler (and then clear it
+            // in SnortIdle()).
+
+            // check for signals
+            if ( SignalCheck() )
+            {
+#ifndef SNORT_RELOAD
+                // Got SIGNAL_SNORT_RELOAD
+                Restart();
+#endif
+            }
+            CheckForReload();
+        }
+        if ( pkts_to_read > 0 )
+        {
+            if ( snort_conf->pkt_cnt <= pc.total_from_daq )
+                break;
+            else
+                pkts_to_read = (int)(snort_conf->pkt_cnt - pc.total_from_daq);
+        }
+        // idle time processing..quick things to check or do ...
+        // TBD fix this per above ... and if it stays here, should
+        // prolly change the name if acquire breaks due to a signal
+        // (since in that case we aren't idle here)
+        SnortIdle();
+
+#ifdef SIDE_CHANNEL
+        /* Unlock the Snort process lock once we've hit the DAQ acquire timeout. */
+        if (snort_process_lock_held)
+        {
+            snort_process_lock_held = false;
+            pthread_mutex_unlock(&snort_process_lock);
+        }
+#endif
+    }
+
+#ifdef SIDE_CHANNEL
+    /* Error conditions can lead to exiting the packet loop prior to unlocking the process lock.  */
+    if (snort_process_lock_held)
+    {
+        snort_process_lock_held = false;
+        pthread_mutex_unlock(&snort_process_lock);
+    }
+#endif
+
+    if ( !exit_logged && error )
+    {
+        if ( error == DAQ_READFILE_EOF )
+            error = 0;
+        else if ( error > 0 )
+        {
+            DAQ_Abort();
+            exit(1);
+        }
+        CleanExit(error);
+    }
+    done_processing = 1;
+}
+
+/* Resets Snort to a post-configuration state */
+static void SnortReset(void)
+{
+    PreprocSignalFuncNode *idxPreprocReset;
+    PreprocSignalFuncNode *idxPreprocResetStats;
+
+    /* reset preprocessors */
+    idxPreprocReset = preproc_reset_funcs;
+    while (idxPreprocReset != NULL)
+    {
+        idxPreprocReset->func(-1, idxPreprocReset->arg);
+        idxPreprocReset = idxPreprocReset->next;
+    }
+
+    SnortEventqReset();
+    Replace_ResetQueue();
+#ifdef ACTIVE_RESPONSE
+    Active_ResetQueue();
+#endif
+
+    sfthreshold_reset_active();
+    RateFilter_ResetActive();
+    TagCacheReset();
+
+#ifdef PERF_PROFILING
+    ShowPreprocProfiles();
+    ShowRuleProfiles();
+#endif
+
+    DropStats(0);
+
+    /* zero out packet count */
+    memset(&pc, 0, sizeof(pc));
+
+#ifdef PERF_PROFILING
+    ResetRuleProfiling();
+    ResetPreprocProfiling();
+#endif
+
+    /* reset preprocessor stats */
+    idxPreprocResetStats = preproc_reset_stats_funcs;
+    while (idxPreprocResetStats != NULL)
+    {
+        idxPreprocResetStats->func(-1, idxPreprocResetStats->arg);
+        idxPreprocResetStats = idxPreprocResetStats->next;
+    }
+}
+
+
+#if 0
+/* locate one of the possible default config files */
+/* allocates memory to hold filename */
+static char *ConfigFileSearch(void)
+{
+    struct stat st;
+    int i;
+    char *conf_files[]={"/etc/snort.conf", "./snort.conf", NULL};
+    char *fname = NULL;
+    char *rval = NULL;
+
+    i = 0;
+
+    /* search the default set of config files */
+    while(conf_files[i])
+    {
+        fname = conf_files[i];
+
+        if(stat(fname, &st) != -1)
+        {
+            rval = SnortStrdup(fname);
+            break;
+        }
+        i++;
+    }
+
+    /* search for .snortrc in the HOMEDIR */
+    if(!rval)
+    {
+        char *home_dir = NULL;
+
+        if((home_dir = getenv("HOME")) != NULL)
+        {
+            char *snortrc = "/.snortrc";
+            int path_len;
+
+            path_len = strlen(home_dir) + strlen(snortrc) + 1;
+
+            /* create the full path */
+            fname = (char *)SnortAlloc(path_len);
+
+            SnortSnprintf(fname, path_len, "%s%s", home_dir, snortrc);
+
+            if(stat(fname, &st) != -1)
+                rval = fname;
+            else
+                free(fname);
+        }
+    }
+
+    return rval;
+}
+#endif
+
+/* Signal Handlers ************************************************************/
+static void SigExitHandler(int signal)
+{
+    if (exit_signal != 0)
+        return;
+
+    /* Don't want to have to wait to start processing packets before
+     * getting out of dodge */
+    if (snort_initializing)
+        _exit(0);
+
+    exit_signal = signal;
+}
+
+static void SigDumpStatsHandler(int signal)
+{
+    dump_stats_signal = true;
+}
+
+static void SigRotateStatsHandler(int signal)
+{
+    rotate_stats_signal = true;
+}
+
+static void SigReloadHandler(int signal)
+{
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+    reload_signal++;
+#else
+    reload_signal = true;
+#endif
+}
+
+#ifdef CONTROL_SOCKET
+static void SigPipeHandler(int signal)
+{
+}
+#endif
+
+#ifdef TARGET_BASED
+static void SigNoAttributeTableHandler(int signal)
+{
+   no_attr_table_signal = true;
+}
+#endif
+
+static void SigOopsHandler(int signal)
+{
+    if ( s_packet.pkth )
+    {
+        s_pkth = *s_packet.pkth;
+
+        if ( s_packet.pkt )
+            memcpy(s_data, s_packet.pkt, 0xFFFF & s_packet.pkth->caplen);
+    }
+    SnortAddSignal(signal, SIG_DFL, 0);
+
+    raise(signal);
+}
+
+
+static void PrintStatistics (void)
+{
+    if ( ScTestMode() || ScVersionMode() || ScRuleDumpMode() )
+        return;
+
+    fpShowEventStats(snort_conf);
+
+#ifdef PERF_PROFILING
+    {
+        int save_quiet_flag = snort_conf->logging_flags & LOGGING_FLAG__QUIET;
+
+        snort_conf->logging_flags &= ~LOGGING_FLAG__QUIET;
+
+        ShowPreprocProfiles();
+        ShowRuleProfiles();
+
+        snort_conf->logging_flags |= save_quiet_flag;
+    }
+#endif
+
+    DropStats(2);
+    print_thresholding(snort_conf->threshold_config, 1);
+}
+
+/****************************************************************************
+ *
+ * Function: CleanExit()
+ *
+ * Purpose:  Clean up misc file handles and such and exit
+ *
+ * Arguments: exit value;
+ *
+ * Returns: void function
+ *
+ ****************************************************************************/
+static void CleanExit(int exit_val)
+{
+    SnortConfig tmp;
+
+#ifdef TARGET_BASED
+#ifdef DEBUG
+#if 0
+    SFLAT_dump();
+#endif
+#endif
+#endif
+
+    /* Have to trick LogMessage to log correctly after snort_conf
+     * is freed */
+    memset(&tmp, 0, sizeof(tmp));
+
+    if (snort_conf != NULL)
+    {
+        tmp.logging_flags |=
+            (snort_conf->logging_flags & LOGGING_FLAG__QUIET);
+
+        tmp.run_flags |= (snort_conf->run_flags & RUN_FLAG__DAEMON);
+
+        tmp.logging_flags |=
+            (snort_conf->logging_flags & LOGGING_FLAG__SYSLOG);
+    }
+
+    SnortCleanup(exit_val);
+    snort_conf = &tmp;
+
+    LogMessage("Snort exiting\n");
+#ifndef WIN32
+    closelog();
+#endif
+    if ( !done_processing )
+        exit(exit_val);
+}
+
+static void SnortCleanup(int exit_val)
+{
+    PreprocSignalFuncNode *idxPreproc = NULL;
+    PluginSignalFuncNode *idxPlugin = NULL;
+
+    /* This function can be called more than once.  For example,
+     * once from the SIGINT signal handler, and once recursively
+     * as a result of calling pcap_close() below.  We only need
+     * to perform the cleanup once, however.  So the static
+     * variable already_exiting will act as a flag to prevent
+     * double-freeing any memory.  Not guaranteed to be
+     * thread-safe, but it will prevent the simple cases.
+     */
+    static int already_exiting = 0;
+    if( already_exiting != 0 )
+    {
+        return;
+    }
+    already_exiting = 1;
+    snort_exiting = 1;
+    snort_initializing = false;  /* just in case we cut out early */
+
+    Active_Suspend();  // rules that fire now can't actually block
+
+#if 0
+    if ( DAQ_WasStarted() )
+    {
+#ifdef EXIT_CHECK
+        if (snort_conf->exit_check)
+            ExitCheckEnd();
+#endif
+        DAQ_Stop();
+    }
+#endif
+
+    ControlSocketCleanUp();
+#ifdef SIDE_CHANNEL
+    SideChannelStopTXThread();
+    SideChannelCleanUp();
+#endif
+    IdleProcessingCleanUp();
+
+    if ( snort_conf->dirty_pig )
+    {
+        //DAQ_Delete();
+        //DAQ_Term();
+        //PrintStatistics();
+        return;
+    }
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+    /* Setting snort_exiting will cause the thread to break out
+     * of it's loop and exit */
+    if (snort_reload_thread_created)
+        pthread_join(snort_reload_thread_id, NULL);
+#endif
+
+#if defined(INLINE_FAILOPEN) && !defined(WIN32)
+    if (inline_failopen_thread_running)
+        pthread_kill(inline_failopen_thread_id, SIGKILL);
+#endif
+
+#if defined(TARGET_BASED) && !defined(WIN32)
+    if (attribute_reload_thread_running)
+    {
+        /* Set the flag to stop the attribute reload thread and
+         * send VTALRM signal to pull it out of the idle sleep.
+         * Thread exits normally on next iteration through its
+         * loop.
+         *
+         * If its doing other processing, that continues post
+         * interrupt and thread exits normally.
+         */
+        attribute_reload_thread_stop = 1;
+        pthread_kill(attribute_reload_thread_id, SIGVTALRM);
+        while (attribute_reload_thread_running)
+            nanosleep(&thread_sleep, NULL);
+        pthread_join(attribute_reload_thread_id, NULL);
+    }
+#endif
+
+    /* Do some post processing on any incomplete Preprocessor Data */
+    idxPreproc = preproc_shutdown_funcs;
+    while (idxPreproc)
+    {
+        idxPreproc->func(SIGQUIT, idxPreproc->arg);
+        idxPreproc = idxPreproc->next;
+    }
+
+    /* Do some post processing on any incomplete Plugin Data */
+    idxPlugin = plugin_shutdown_funcs;
+    while(idxPlugin)
+    {
+        idxPlugin->func(SIGQUIT, idxPlugin->arg);
+        idxPlugin = idxPlugin->next;
+    }
+
+    if (!ScTestMode() && !ScVersionMode() && !ScRuleDumpMode() )
+    {
+        if ( !exit_val )
+            TimeStop();
+    }
+
+    /* Exit preprocessors */
+    idxPreproc = preproc_clean_exit_funcs;
+    while(idxPreproc)
+    {
+        idxPreproc->func(SIGQUIT, idxPreproc->arg);
+        idxPreproc = idxPreproc->next;
+    }
+
+    /* Do some post processing on any incomplete Plugin Data */
+    idxPlugin = plugin_clean_exit_funcs;
+    while(idxPlugin)
+    {
+        idxPlugin->func(SIGQUIT, idxPlugin->arg);
+        idxPlugin = idxPlugin->next;
+    }
+
+    if (decoderActionQ != NULL)
+    {
+        sfActionQueueDestroy (decoderActionQ);
+        mempool_destroy (&decoderAlertMemPool);
+        decoderActionQ = NULL;
+        memset(&decoderAlertMemPool, 0, sizeof(decoderAlertMemPool));
+    }
+
+    //DAQ_Delete();
+    //DAQ_Term();
+    //PrintStatistics();
+
+#ifdef ACTIVE_RESPONSE
+    Active_Term();
+    Encode_Term();
+#endif
+
+
+    CleanupProtoNames();
+
+#ifdef TARGET_BASED
+    SFAT_Cleanup();
+#endif
+
+    PQ_CleanUp();
+
+    ClosePidFile();
+
+    /* remove pid file */
+    if (SnortStrnlen(snort_conf->pid_filename, sizeof(snort_conf->pid_filename)) > 0)
+    {
+        int ret;
+
+        ret = unlink(snort_conf->pid_filename);
+
+        if (ret != 0)
+        {
+            ErrorMessage("Could not remove pid file %s: %s\n",
+                         snort_conf->pid_filename, strerror(errno));
+        }
+    }
+
+#ifdef INTEL_SOFT_CPM
+    //IntelPmPrintBufferStats();
+#endif
+
+    /* free allocated memory */
+    if (snort_conf == snort_cmd_line_conf)
+    {
+        SnortConfFree(snort_cmd_line_conf);
+        snort_cmd_line_conf = NULL;
+        snort_conf = NULL;
+    }
+    else
+    {
+        SnortConfFree(snort_cmd_line_conf);
+        snort_cmd_line_conf = NULL;
+        SnortConfFree(snort_conf);
+        snort_conf = NULL;
+    }
+
+#ifdef SNORT_RELOAD
+    if (snort_conf_new != NULL)
+    {
+        /* If main thread is exiting, it won't swap in the new configuration,
+         * so free it here, really just to quiet valgrind.  Note this needs to
+         * be done here since some preprocessors, will potentially need access
+         * to the data here since stream5 flushes out its cache and potentially
+         * sends reassembled packets back through Preprocess */
+        SnortConfFree(snort_conf_new);
+        snort_conf_new = NULL;
+    }
+#endif
+
+    EventTrace_Term();
+
+    detection_filter_cleanup();
+    sfthreshold_free();
+    RateFilter_Cleanup();
+    asn1_free_mem();
+    FreeOutputConfigFuncs();
+    FreePreprocConfigFuncs();
+
+    FreeRuleOptConfigFuncs(rule_opt_config_funcs);
+    rule_opt_config_funcs = NULL;
+
+    FreeRuleOptOverrideInitFuncs(rule_opt_override_init_funcs);
+    rule_opt_override_init_funcs = NULL;
+
+    FreeRuleOptByteOrderFuncs(rule_opt_byte_order_funcs);
+    rule_opt_byte_order_funcs = NULL;
+
+    FreeRuleOptParseCleanupList(rule_opt_parse_cleanup_list);
+    rule_opt_parse_cleanup_list = NULL;
+
+    FreeOutputList(AlertList);
+    AlertList = NULL;
+
+    FreeOutputList(LogList);
+    LogList = NULL;
+
+    /* Global lists */
+    FreePreprocStatsFuncs(preproc_stats_funcs);
+    preproc_stats_funcs = NULL;
+
+    FreePreprocSigFuncs(preproc_shutdown_funcs);
+    preproc_shutdown_funcs = NULL;
+
+    FreePreprocSigFuncs(preproc_clean_exit_funcs);
+    preproc_clean_exit_funcs = NULL;
+
+    FreePreprocSigFuncs(preproc_reset_funcs);
+    preproc_reset_funcs = NULL;
+
+    FreePreprocSigFuncs(preproc_reset_stats_funcs);
+    preproc_reset_stats_funcs = NULL;
+
+    FreePluginSigFuncs(plugin_shutdown_funcs);
+    plugin_shutdown_funcs = NULL;
+
+    FreePluginSigFuncs(plugin_clean_exit_funcs);
+    plugin_clean_exit_funcs = NULL;
+
+#ifdef SNORT_RELOAD
+    FreePluginPostConfigFuncs(plugin_reload_funcs);
+    plugin_reload_funcs = NULL;
+#endif
+
+    FreePeriodicFuncs(periodic_check_funcs);
+    periodic_check_funcs = NULL;
+
+    ParserCleanup();
+
+    /* Stuff from plugbase */
+    DynamicRuleListFree(dynamic_rules);
+    dynamic_rules = NULL;
+
+    CloseDynamicPreprocessorLibs();
+    CloseDynamicDetectionLibs();
+    CloseDynamicEngineLibs();
+#ifdef SIDE_CHANNEL
+    CloseDynamicSideChannelLibs();
+#endif
+    output_unload();
+
+    CleanupTag();
+    ClearDumpBuf();
+
+#ifdef PERF_PROFILING
+    CleanupPreprocStatsNodeList();
+#endif
+
+    if (netmasks != NULL)
+    {
+        free(netmasks);
+        netmasks = NULL;
+    }
+
+    if (protocol_names != NULL)
+    {
+        int i;
+
+        for (i = 0; i < NUM_IP_PROTOS; i++)
+        {
+            if (protocol_names[i] != NULL)
+                free(protocol_names[i]);
+        }
+
+        free(protocol_names);
+        protocol_names = NULL;
+    }
+
+#ifdef INTEL_SOFT_CPM
+    IntelPmStopInstance();
+#endif
+
+    SynToMulticastDstIpDestroy();
+
+    FreeVarList(cmd_line_var_list);
+
+    if (snort_conf_file != NULL)
+        free(snort_conf_file);
+
+    if (snort_conf_dir != NULL)
+        free(snort_conf_dir);
+
+    close_fileAPI();
+}
+
+static void InitGlobals(void)
+{
+    memset(&pc, 0, sizeof(pc));
+
+    InitNetmasks();
+    InitProtoNames();
+#ifdef SIDE_CHANNEL
+    pthread_mutex_init(&snort_process_lock, NULL);
+#endif
+}
+
+/****************************************************************************
+ *
+ * Function: InitNetMasks()
+ *
+ * Purpose: Loads the netmask struct in network order.  Yes, I know I could
+ *          just load the array when I define it, but this is what occurred
+ *          to me when I wrote this at 3:00 AM.
+ *
+ * Arguments: None.
+ *
+ * Returns: void function
+ *
+ ****************************************************************************/
+static void InitNetmasks(void)
+{
+    if (netmasks == NULL)
+        netmasks = (uint32_t *)SnortAlloc(33 * sizeof(uint32_t));
+
+    netmasks[0]  = 0x00000000;
+    netmasks[1]  = 0x80000000;
+    netmasks[2]  = 0xC0000000;
+    netmasks[3]  = 0xE0000000;
+    netmasks[4]  = 0xF0000000;
+    netmasks[5]  = 0xF8000000;
+    netmasks[6]  = 0xFC000000;
+    netmasks[7]  = 0xFE000000;
+    netmasks[8]  = 0xFF000000;
+    netmasks[9]  = 0xFF800000;
+    netmasks[10] = 0xFFC00000;
+    netmasks[11] = 0xFFE00000;
+    netmasks[12] = 0xFFF00000;
+    netmasks[13] = 0xFFF80000;
+    netmasks[14] = 0xFFFC0000;
+    netmasks[15] = 0xFFFE0000;
+    netmasks[16] = 0xFFFF0000;
+    netmasks[17] = 0xFFFF8000;
+    netmasks[18] = 0xFFFFC000;
+    netmasks[19] = 0xFFFFE000;
+    netmasks[20] = 0xFFFFF000;
+    netmasks[21] = 0xFFFFF800;
+    netmasks[22] = 0xFFFFFC00;
+    netmasks[23] = 0xFFFFFE00;
+    netmasks[24] = 0xFFFFFF00;
+    netmasks[25] = 0xFFFFFF80;
+    netmasks[26] = 0xFFFFFFC0;
+    netmasks[27] = 0xFFFFFFE0;
+    netmasks[28] = 0xFFFFFFF0;
+    netmasks[29] = 0xFFFFFFF8;
+    netmasks[30] = 0xFFFFFFFC;
+    netmasks[31] = 0xFFFFFFFE;
+    netmasks[32] = 0xFFFFFFFF;
+}
+
+/****************************************************************************
+ *
+ * Function: InitProtoNames()
+ *
+ * Purpose: Initializes the protocol names
+ *
+ * Arguments: None.
+ *
+ * Returns: void function
+ *
+ ****************************************************************************/
+static void InitProtoNames(void)
+{
+    int i;
+
+    if (protocol_names == NULL)
+        protocol_names = (char **)SnortAlloc(sizeof(char *) * NUM_IP_PROTOS);
+
+    for (i = 0; i < NUM_IP_PROTOS; i++)
+    {
+        struct protoent *pt = getprotobynumber(i);
+
+        if (pt != NULL)
+        {
+            size_t j;
+
+            protocol_names[i] = SnortStrdup(pt->p_name);
+            for (j = 0; j < strlen(protocol_names[i]); j++)
+                protocol_names[i][j] = toupper(protocol_names[i][j]);
+        }
+        else
+        {
+            char protoname[10];
+
+            SnortSnprintf(protoname, sizeof(protoname), "PROTO:%03d", i);
+            protocol_names[i] = SnortStrdup(protoname);
+        }
+    }
+}
+
+
+static void SetSnortConfDir(void)
+{
+    /* extract the config directory from the config filename */
+    if (snort_conf_file != NULL)
+    {
+#ifndef WIN32
+        char *path_sep = strrchr(snort_conf_file, '/');
+#else
+        char *path_sep = strrchr(snort_conf_file, '\\');
+#endif
+
+        /* is there a directory seperator in the filename */
+        if (path_sep != NULL)
+        {
+            path_sep++;  /* include path separator */
+            snort_conf_dir = SnortStrndup(snort_conf_file, path_sep - snort_conf_file);
+        }
+        else
+        {
+            snort_conf_dir = SnortStrdup("./");
+        }
+
+        DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Config file = %s, config dir = "
+                    "%s\n", snort_conf_file, snort_conf_dir););
+    }
+}
+
+static void FreePlugins(SnortConfig *sc)
+{
+    if (sc == NULL)
+        return;
+
+    FreePreprocessors(sc);
+
+    FreePluginPostConfigFuncs(sc->plugin_post_config_funcs);
+    sc->plugin_post_config_funcs = NULL;
+}
+
+static void FreePreprocessors(SnortConfig *sc)
+{
+    tSfPolicyId i;
+
+    if (sc == NULL)
+        return;
+
+    FreePreprocCheckConfigFuncs(sc->preproc_config_check_funcs);
+    sc->preproc_config_check_funcs = NULL;
+
+    for (i = 0; i < sc->num_policies_allocated; i++)
+    {
+        SnortPolicy *p = sc->targeted_policies[i];
+
+        if (p == NULL)
+            continue;
+
+        FreePreprocEvalFuncs(p->preproc_eval_funcs);
+        p->preproc_eval_funcs = NULL;
+        p->num_preprocs = 0;
+
+        FreePreprocEvalFuncs(p->unused_preproc_eval_funcs);
+        p->unused_preproc_eval_funcs = NULL;
+
+        FreePreprocMetaEvalFuncs(p->preproc_meta_eval_funcs);
+        p->preproc_meta_eval_funcs = NULL;
+        p->num_meta_preprocs = 0;
+
+        FreeDetectionEvalFuncs(p->detect_eval_funcs);
+        p->detect_eval_funcs = NULL;
+        p->num_detects = 0;
+    }
+
+    FreePreprocPostConfigFuncs(sc->preproc_post_config_funcs);
+    sc->preproc_post_config_funcs = NULL;
+}
+
+static SnortConfig * MergeSnortConfs(SnortConfig *cmd_line, SnortConfig *config_file)
+{
+    unsigned int i;
+
+    /* Move everything from the command line config over to the
+     * config_file config */
+
+    if (cmd_line == NULL)
+    {
+        FatalError("%s(%d) Merging snort configs: snort conf is NULL.\n",
+                   __FILE__, __LINE__);
+    }
+
+    ResolveOutputPlugins(cmd_line, config_file);
+
+    if (config_file == NULL)
+    {
+        if (cmd_line->log_dir == NULL)
+            cmd_line->log_dir = SnortStrdup(DEFAULT_LOG_DIR);
+    }
+    else if ((cmd_line->log_dir == NULL) && (config_file->log_dir == NULL))
+    {
+        config_file->log_dir = SnortStrdup(DEFAULT_LOG_DIR);
+    }
+    else if (cmd_line->log_dir != NULL)
+    {
+        if (config_file->log_dir != NULL)
+            free(config_file->log_dir);
+
+        config_file->log_dir = SnortStrdup(cmd_line->log_dir);
+    }
+
+    if (config_file == NULL)
+        return cmd_line;
+
+    /* Used because of a potential chroot */
+    config_file->orig_log_dir = SnortStrdup(config_file->log_dir);
+
+    config_file->run_mode = cmd_line->run_mode;
+    config_file->run_mode_flags |= cmd_line->run_mode_flags;
+
+    if ((cmd_line->run_mode == RUN_MODE__TEST) &&
+        (config_file->run_flags & RUN_FLAG__DAEMON))
+    {
+        /* Just ignore deamon setting in conf file */
+        config_file->run_flags &= ~RUN_FLAG__DAEMON;
+    }
+
+    config_file->run_flags |= cmd_line->run_flags;
+    config_file->output_flags |= cmd_line->output_flags;
+    config_file->logging_flags |= cmd_line->logging_flags;
+
+    /* Merge checksum flags.  If command line modified them, use from the
+     * command line, else just use from config_file. */
+    for (i = 0; i < config_file->num_policies_allocated; i++)
+    {
+        if (config_file->targeted_policies[i] != NULL)
+        {
+            if (cmd_line->checksum_flags_modified)
+                config_file->targeted_policies[i]->checksum_flags = cmd_line->checksum_flags;
+
+            if (cmd_line->checksum_drop_flags_modified)
+                config_file->targeted_policies[i]->checksum_drop_flags = cmd_line->checksum_drop_flags;
+        }
+    }
+
+    config_file->event_log_id = cmd_line->event_log_id;
+
+    if (cmd_line->dynamic_rules_path != NULL)
+    {
+        if(strcmp(cmd_line->dynamic_rules_path, "")  != 0)
+        {
+            if( config_file->dynamic_rules_path != NULL )
+                free(config_file->dynamic_rules_path);
+            config_file->dynamic_rules_path = SnortStrdup(cmd_line->dynamic_rules_path);
+        }
+    }
+
+    if (cmd_line->dyn_engines != NULL)
+    {
+        FreeDynamicLibInfo(config_file->dyn_engines);
+        config_file->dyn_engines = DupDynamicLibInfo(cmd_line->dyn_engines);
+    }
+
+    if (cmd_line->dyn_rules != NULL)
+    {
+        FreeDynamicLibInfo(config_file->dyn_rules);
+        config_file->dyn_rules = DupDynamicLibInfo(cmd_line->dyn_rules);
+    }
+
+    if (cmd_line->dyn_preprocs != NULL)
+    {
+        FreeDynamicLibInfo(config_file->dyn_preprocs);
+        config_file->dyn_preprocs = DupDynamicLibInfo(cmd_line->dyn_preprocs);
+    }
+
+    if (cmd_line->pid_path[0] != '\0')
+        ConfigPidPath(config_file, cmd_line->pid_path);
+
+    config_file->exit_check = cmd_line->exit_check;
+
+    /* Command line only configures search method */
+    if (cmd_line->fast_pattern_config != NULL)
+        config_file->fast_pattern_config->search_method = cmd_line->fast_pattern_config->search_method;
+
+    if (cmd_line->obfuscation_net.family != 0)
+        memcpy(&config_file->obfuscation_net, &cmd_line->obfuscation_net, sizeof(sfip_t));
+
+    if (cmd_line->homenet.family != 0)
+        memcpy(&config_file->homenet, &cmd_line->homenet, sizeof(sfip_t));
+
+    if (cmd_line->interface != NULL)
+    {
+        if (config_file->interface != NULL)
+            free(config_file->interface);
+        config_file->interface = SnortStrdup(cmd_line->interface);
+    }
+
+    if (cmd_line->bpf_file != NULL)
+    {
+        if (config_file->bpf_file != NULL)
+            free(config_file->bpf_file);
+        config_file->bpf_file = SnortStrdup(cmd_line->bpf_file);
+    }
+
+    if (cmd_line->bpf_filter != NULL)
+        config_file->bpf_filter = SnortStrdup(cmd_line->bpf_filter);
+
+    if (cmd_line->pkt_snaplen != -1)
+        config_file->pkt_snaplen = cmd_line->pkt_snaplen;
+
+    if (cmd_line->pkt_cnt != 0)
+        config_file->pkt_cnt = cmd_line->pkt_cnt;
+
+#ifdef REG_TEST
+    if (cmd_line->pkt_skip != 0)
+        config_file->pkt_skip = cmd_line->pkt_skip;
+#endif
+
+    if (cmd_line->group_id != -1)
+        config_file->group_id = cmd_line->group_id;
+
+    if (cmd_line->user_id != -1)
+        config_file->user_id = cmd_line->user_id;
+
+    /* Only configurable on command line */
+    if (cmd_line->pcap_log_file != NULL)
+        config_file->pcap_log_file = SnortStrdup(cmd_line->pcap_log_file);
+
+    if (cmd_line->file_mask != 0)
+        config_file->file_mask = cmd_line->file_mask;
+
+    if (cmd_line->pidfile_suffix[0] != '\0')
+    {
+        SnortStrncpy(config_file->pidfile_suffix, cmd_line->pidfile_suffix,
+                     sizeof(config_file->pidfile_suffix));
+    }
+
+    if (cmd_line->chroot_dir != NULL)
+    {
+        if (config_file->chroot_dir != NULL)
+            free(config_file->chroot_dir);
+        config_file->chroot_dir = SnortStrdup(cmd_line->chroot_dir);
+    }
+
+    if (cmd_line->perf_file != NULL)
+    {
+        if (config_file->perf_file != NULL)
+            free(config_file->perf_file);
+        config_file->perf_file = SnortStrdup(cmd_line->perf_file);
+    }
+
+    if ( cmd_line->daq_type )
+        config_file->daq_type = SnortStrdup(cmd_line->daq_type);
+
+    if ( cmd_line->daq_mode )
+        config_file->daq_mode = SnortStrdup(cmd_line->daq_mode);
+
+    if ( cmd_line->dirty_pig )
+        config_file->dirty_pig = cmd_line->dirty_pig;
+
+    if ( cmd_line->daq_vars )
+    {
+        /* Command line overwrites daq_vars */
+        if (config_file->daq_vars)
+            StringVector_Delete(config_file->daq_vars);
+
+        config_file->daq_vars = StringVector_New();
+        StringVector_AddVector(config_file->daq_vars, cmd_line->daq_vars);
+    }
+    if ( cmd_line->daq_dirs )
+    {
+        /* Command line overwrites daq_dirs */
+        if (config_file->daq_dirs)
+            StringVector_Delete(config_file->daq_dirs);
+
+        config_file->daq_dirs = StringVector_New();
+        StringVector_AddVector(config_file->daq_dirs, cmd_line->daq_dirs);
+    }
+#ifdef MPLS
+    if (cmd_line->mpls_stack_depth != DEFAULT_LABELCHAIN_LENGTH)
+        config_file->mpls_stack_depth = cmd_line->mpls_stack_depth;
+
+    /* Set MPLS payload type here if it hasn't been defined */
+    if ((cmd_line->mpls_payload_type == 0) &&
+        (config_file->mpls_payload_type == 0))
+    {
+        config_file->mpls_payload_type = DEFAULT_MPLS_PAYLOADTYPE;
+    }
+    else if (cmd_line->mpls_payload_type != 0)
+    {
+        config_file->mpls_payload_type = cmd_line->mpls_payload_type;
+    }
+#endif
+
+    if (cmd_line->run_flags & RUN_FLAG__PROCESS_ALL_EVENTS)
+        config_file->event_queue_config->process_all_events = 1;
+
+    if (cmd_line->cs_dir != NULL)
+    {
+        if (config_file->cs_dir != NULL)
+            free(config_file->cs_dir);
+        config_file->cs_dir = SnortStrdup(cmd_line->cs_dir);
+    }
+    if (config_file->cs_dir)
+    {
+
+#ifndef WIN32
+        /*
+         *  If an absolute path is specified, then use that.
+         *  otherwise, relative to pid path
+         */
+        if ((config_file->cs_dir[0] != '/') && config_file->pid_path[0])
+        {
+
+            char fullpath[PATH_MAX];
+
+            if (config_file->pid_path[strlen(config_file->pid_path) - 1] == '/')
+            {
+                SnortSnprintf(fullpath, sizeof(fullpath),
+                        "%s%s", config_file->pid_path, config_file->cs_dir);
+            }
+            else
+            {
+                SnortSnprintf(fullpath, sizeof(fullpath),
+                        "%s/%s", config_file->pid_path, config_file->cs_dir);
+            }
+            free (config_file->cs_dir);
+            config_file->cs_dir = SnortStrdup(fullpath);
+
+        }
+#else
+        /*Not supported in WINDOWS*/
+        free (config_file->cs_dir);
+        config_file->cs_dir = NULL;
+#endif
+        ControlSocketConfigureDirectory(config_file->cs_dir);
+    }
+
+#ifdef REG_TEST
+    config_file->ha_peer = cmd_line->ha_peer;
+
+    if ( cmd_line->ha_out )
+    {
+        if(config_file->ha_out != NULL)
+            free(config_file->ha_out);
+        config_file->ha_out = strdup(cmd_line->ha_out);
+    }
+
+    if ( cmd_line->ha_in )
+    {
+        if(config_file->ha_in != NULL)
+            free(config_file->ha_in);
+        config_file->ha_in = strdup(cmd_line->ha_in);
+    }
+#endif
+
+    return config_file;
+}
+
+static void FreeDynamicLibInfos(SnortConfig *sc)
+{
+    if (sc == NULL)
+        return;
+
+    if (sc->dyn_engines != NULL)
+    {
+        FreeDynamicLibInfo(sc->dyn_engines);
+        sc->dyn_engines = NULL;
+    }
+
+    if (sc->dyn_rules != NULL)
+    {
+        FreeDynamicLibInfo(sc->dyn_rules);
+        sc->dyn_rules = NULL;
+    }
+
+    if (sc->dyn_preprocs != NULL)
+    {
+        FreeDynamicLibInfo(sc->dyn_preprocs);
+        sc->dyn_preprocs = NULL;
+    }
+
+#ifdef SIDE_CHANNEL
+    if (sc->dyn_side_channels != NULL)
+    {
+        FreeDynamicLibInfo(sc->dyn_side_channels);
+        sc->dyn_side_channels = NULL;
+    }
+#endif
+}
+
+static void FreeDynamicLibInfo(DynamicLibInfo *lib_info)
+{
+    unsigned i;
+
+    if (lib_info == NULL)
+        return;
+
+    for (i = 0; i < lib_info->count; i++)
+    {
+        free(lib_info->lib_paths[i]->path);
+        free(lib_info->lib_paths[i]);
+    }
+
+    free(lib_info);
+}
+
+static DynamicLibInfo * DupDynamicLibInfo(DynamicLibInfo *src)
+{
+    DynamicLibInfo *dst;
+    unsigned i;
+
+    if (src == NULL)
+        return NULL;
+
+    dst = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo));
+    dst->type = src->type;
+    dst->count = src->count;
+
+    for (i = 0; i < src->count; i++)
+    {
+        DynamicLibPath *dylib_path = (DynamicLibPath *)SnortAlloc(sizeof(DynamicLibPath));
+
+        dylib_path->ptype = src->lib_paths[i]->ptype;
+        dylib_path->path = SnortStrdup(src->lib_paths[i]->path);
+
+        dst->lib_paths[i] = dylib_path;
+    }
+
+    return dst;
+}
+
+#if defined(INLINE_FAILOPEN) && !defined(WIN32)
+static void * SnortPostInitThread(void *data)
+{
+    sigset_t mtmask;
+
+    inline_failopen_thread_pid = gettid();
+    inline_failopen_thread_running = 1;
+
+    /* Don't handle any signals here */
+    sigfillset(&mtmask);
+    pthread_sigmask(SIG_BLOCK, &mtmask, NULL);
+
+    while (!inline_failopen_initialized)
+        nanosleep(&thread_sleep, NULL);
+
+    SnortUnprivilegedInit();
+
+    pthread_exit((void *)NULL);
+}
+
+static DAQ_Verdict IgnoreCallback (
+    void *user, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt)
+{
+    /* Empty function -- do nothing with the packet we just read */
+    inline_failopen_pass_pkt_cnt++;
+
+#ifdef DEBUG
+    {
+        FILE *tmp = fopen("/var/tmp/fo_threadid", "a");
+        if ( tmp )
+        {
+            fprintf(tmp, "Packet Count %d\n", inline_failopen_pass_pkt_cnt);
+            fclose(tmp);
+        }
+    }
+#endif
+    return DAQ_VERDICT_PASS;
+}
+#endif /* defined(INLINE_FAILOPEN) && !defined(WIN32) */
+
+
+#if defined(NOCOREFILE) && !defined(WIN32)
+static void SetNoCores(void)
+{
+    struct rlimit rlim;
+
+    getrlimit(RLIMIT_CORE, &rlim);
+    rlim.rlim_max = 0;
+    setrlimit(RLIMIT_CORE, &rlim);
+}
+#endif
+
+static void InitSignals(void)
+{
+
+#ifndef WIN32
+# if defined(LINUX) || defined(FREEBSD) || defined(OPENBSD) || \
+     defined(SOLARIS) || defined(BSD) || defined(MACOS)
+    sigset_t set;
+
+    sigemptyset(&set);
+#  if defined(INLINE_FAILOPEN) || \
+      defined(TARGET_BASED) || defined(SNORT_RELOAD)
+    pthread_sigmask(SIG_SETMASK, &set, NULL);
+#  else
+    sigprocmask(SIG_SETMASK, &set, NULL);
+#  endif /* INLINE_FAILOPEN */
+# else
+    sigsetmask(0);
+# endif /* LINUX, BSD, SOLARIS */
+#endif  /* !WIN32 */
+
+    /* Make this prog behave nicely when signals come along.
+     * Windows doesn't like all of these signals, and will
+     * set errno for some.  Ignore/reset this error so it
+     * doesn't interfere with later checks of errno value.  */
+    signal_error_msg[0] = '\0';
+    SnortAddSignal(SIGTERM, SigExitHandler, 1);
+    SnortAddSignal(SIGINT, SigExitHandler, 1);
+#ifndef WIN32
+    SnortAddSignal(SIGQUIT, SigExitHandler, 1);
+    SnortAddSignal(SIGNAL_SNORT_DUMP_STATS, SigDumpStatsHandler, 1);
+    SnortAddSignal(SIGNAL_SNORT_RELOAD, SigReloadHandler, 1);
+    SnortAddSignal(SIGNAL_SNORT_ROTATE_STATS, SigRotateStatsHandler, 1);
+#endif
+
+#ifdef CONTROL_SOCKET
+    SnortAddSignal(SIGPIPE, SigPipeHandler, 1);
+#endif
+
+#ifdef TARGET_BASED
+#ifndef WIN32
+    /* Used to print warning if attribute table is not configured
+     * When it is, it will set new signal handler */
+    SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1);
+#endif
+#endif
+
+    SnortAddSignal(SIGABRT, SigOopsHandler, 1);
+    SnortAddSignal(SIGSEGV, SigOopsHandler, 1);
+#ifndef WIN32
+    SnortAddSignal(SIGBUS, SigOopsHandler, 1);
+#endif
+
+    errno = 0;
+}
+
+static void FreeOutputConfigs(OutputConfig *head)
+{
+    while (head != NULL)
+    {
+        OutputConfig *tmp = head;
+
+        head = head->next;
+
+        if (tmp->keyword != NULL)
+            free(tmp->keyword);
+
+        if (tmp->opts != NULL)
+            free(tmp->opts);
+
+        if (tmp->file_name != NULL)
+            free(tmp->file_name);
+
+        /* Don't free listhead as it's just a pointer to the user defined
+         * rule's rule list node's list head */
+
+        free(tmp);
+    }
+}
+
+#ifdef SIDE_CHANNEL
+static void FreeSideChannelModuleConfigs(SideChannelModuleConfig *head)
+{
+    while (head != NULL)
+    {
+        SideChannelModuleConfig *tmp = head;
+
+        head = head->next;
+
+        if (tmp->keyword != NULL)
+            free(tmp->keyword);
+
+        if (tmp->opts != NULL)
+            free(tmp->opts);
+
+        if (tmp->file_name != NULL)
+            free(tmp->file_name);
+
+        free(tmp);
+    }
+}
+#endif
+
+static void FreePreprocConfigs(SnortConfig *sc)
+{
+    tSfPolicyId i;
+
+    if (sc == NULL)
+        return;
+
+    for (i = 0; i < sc->num_policies_allocated; i++)
+    {
+        SnortPolicy *p = sc->targeted_policies[i];
+        PreprocConfig *head;
+
+        if (p == NULL)
+            continue;
+
+        head = p->preproc_configs;
+
+        while (head != NULL)
+        {
+            PreprocConfig *tmp = head;
+
+            head = head->next;
+
+            if (tmp->keyword != NULL)
+                free(tmp->keyword);
+
+            if (tmp->opts != NULL)
+                free(tmp->opts);
+
+            if (tmp->file_name != NULL)
+                free(tmp->file_name);
+
+            free(tmp);
+        }
+    }
+}
+
+static void FreeRuleStateList(RuleState *head)
+{
+    while (head != NULL)
+    {
+        RuleState *tmp = head;
+
+        head = head->next;
+
+        free(tmp);
+    }
+}
+
+static void FreeClassifications(ClassType *head)
+{
+    while (head != NULL)
+    {
+        ClassType *tmp = head;
+
+        head = head->next;
+
+        if (tmp->name != NULL)
+            free(tmp->name);
+
+        if (tmp->type != NULL)
+            free(tmp->type);
+
+        free(tmp);
+    }
+}
+
+static void FreeReferences(ReferenceSystemNode *head)
+{
+    while (head != NULL)
+    {
+        ReferenceSystemNode *tmp = head;
+
+        head = head->next;
+
+        if (tmp->name != NULL)
+            free(tmp->name);
+
+        if (tmp->url != NULL)
+            free(tmp->url);
+
+        free(tmp);
+    }
+}
+
+#if defined(SNORT_RELOAD) && !defined(WIN32)
+static void updatePeriodicCheck()
+{
+    PeriodicCheckFuncNode *checkFunc;
+
+    /* reset preprocessors */
+    checkFunc = periodic_check_funcs;
+    while (checkFunc != NULL)
+    {
+        if ( 0 == checkFunc->time_left )
+        {
+            checkFunc->func(-1, checkFunc->arg);
+            checkFunc->time_left = checkFunc->period;
+            //LogMessage("        --== Share Memory! ==--\n");
+        }
+        else
+            checkFunc->time_left--;
+
+        checkFunc = checkFunc->next;
+    }
+
+}
+
+static void * ReloadConfigThread(void *data)
+{
+    sigset_t mtmask;
+
+    /* Don't handle any signals here */
+    sigfillset(&mtmask);
+    pthread_sigmask(SIG_BLOCK, &mtmask, NULL);
+
+    snort_reload_thread_pid = gettid();
+    snort_reload_thread_created = 1;
+
+    while (snort_initializing)
+        nanosleep(&thread_sleep, NULL);
+
+    while (!snort_exiting)
+    {
+        if (reload_signal != reload_total)
+        {
+            int reload_failed = 0;
+
+#ifdef CONTROL_SOCKET
+            pthread_mutex_lock(&reload_mutex);
+            if (!reloadInProgress)
+            {
+                reloadInProgress = 1;
+                pthread_mutex_unlock(&reload_mutex);
+#endif
+                reload_total++;
+
+                LogMessage("\n");
+                LogMessage("        --== Reloading Snort ==--\n");
+                LogMessage("\n");
+
+                snort_conf_new = ReloadConfig();
+                if (snort_conf_new == NULL)
+                    reload_failed = 1;
+                snort_reload = 1;
+
+                while (!snort_swapped && !snort_exiting)
+                    nanosleep(&thread_sleep, NULL);
+
+                snort_swapped = 0;
+
+                SnortConfFree(snort_conf_old);
+                snort_conf_old = NULL;
+
+#ifdef INTEL_SOFT_CPM
+                if (snort_conf->fast_pattern_config->search_method != MPSE_INTEL_CPM)
+                    IntelPmStopInstance();
+#endif
+
+                if (snort_exiting && !reload_failed)
+                {
+                    /* This will load the new preprocessor configurations and
+                     * free the old ones, so any preprocessor cleanup that
+                     * requires a configuration will be using the new one
+                     * unless it relies on old configurations that are still
+                     * attached to existing sessions. */
+                    SwapPreprocConfigurations(snort_conf);
+                    FreeSwappedPreprocConfigurations(snort_conf);
+
+#ifdef CONTROL_SOCKET
+                    reloadInProgress = 0;
+#endif
+                    /* Get out of the loop and exit */
+                    break;
+                }
+
+                if (!reload_failed)
+                {
+                    LogMessage("\n");
+                    LogMessage("        --== Reload Complete ==--\n");
+                    LogMessage("\n");
+                }
+#ifdef CONTROL_SOCKET
+                reloadInProgress = 0;
+            }
+            else
+                pthread_mutex_unlock(&reload_mutex);
+#endif
+        }
+        /* Use the maintenance thread for periodic check*/
+        updatePeriodicCheck();
+
+        sleep(1);
+    }
+
+    pthread_exit((void *)0);
+}
+
+static SnortConfig * ReloadConfig(void)
+{
+    SnortConfig *sc;
+
+#ifdef HAVE_MALLOC_TRIM
+    malloc_trim(0);
+#endif
+
+    sc = ParseSnortConf();
+
+    sc = MergeSnortConfs(snort_cmd_line_conf, sc);
+
+    sc->reloadPolicyFlag = 1;
+
+#ifdef PERF_PROFILING
+    /* Parse profiling here because of file option and potential
+     * dependence on log directory */
+    {
+        char *opts = NULL;
+        int in_table;
+
+        in_table = sfghash_find2(sc->config_table,
+                                 CONFIG_OPT__PROFILE_PREPROCS, (void *)&opts);
+        if (in_table)
+            ConfigProfilePreprocs(sc, opts);
+
+        in_table = sfghash_find2(sc->config_table,
+                                 CONFIG_OPT__PROFILE_RULES, (void *)&opts);
+        if (in_table)
+            ConfigProfileRules(sc, opts);
+    }
+#endif
+
+    if (VerifyReload(sc) == -1)
+    {
+        SnortConfFree(sc);
+        return NULL;
+    }
+
+    if (sc->output_flags & OUTPUT_FLAG__USE_UTC)
+        sc->thiszone = 0;
+    else
+        sc->thiszone = gmt2local(0);
+
+    /* Preprocessors will have a reload callback */
+    ConfigurePreprocessors(sc, 1);
+
+    FlowbitResetCounts();
+    ParseRules(sc);
+    RuleOptParseCleanup();
+
+    ReloadDynamicRules(sc);
+
+    /* Handles Fatal Errors itself. */
+    SnortEventqNew(sc->event_queue_config, sc->event_queue);
+
+    detection_filter_print_config(sc->detection_filter_config);
+    RateFilter_PrintConfig(sc->rate_filter_config);
+    print_thresholding(sc->threshold_config, 0);
+    PrintRuleOrder(sc->rule_lists);
+
+    SetRuleStates(sc);
+
+    if (file_sevice_config_verify(snort_conf, sc) == -1)
+    {
+        SnortConfFree(sc);
+        return NULL;
+    }
+
+    if (VerifyReloadedPreprocessors(sc) == -1)
+    {
+        SnortConfFree(sc);
+        return NULL;
+    }
+
+    if (CheckPreprocessorsConfig(sc))
+    {
+        SnortConfFree(sc);
+        return NULL;
+    }
+
+    FilterConfigPreprocessors(sc);
+    PostConfigPreprocessors(sc);
+
+    /* Need to do this after dynamic detection stuff is initialized, too */
+    FlowBitsVerify();
+
+    if ((sc->file_mask != 0) && (sc->file_mask != snort_conf->file_mask))
+        umask(sc->file_mask);
+
+    /* Transfer any user defined rule type outputs to the new rule list */
+    {
+        RuleListNode *cur = snort_conf->rule_lists;
+
+        for (; cur != NULL; cur = cur->next)
+        {
+            RuleListNode *new = sc->rule_lists;
+
+            for (; new != NULL; new = new->next)
+            {
+                if (strcasecmp(cur->name, new->name) == 0)
+                {
+                    OutputFuncNode *alert_list = cur->RuleList->AlertList;
+                    OutputFuncNode *log_list = cur->RuleList->LogList;
+
+                    sc->head_tmp = new->RuleList;
+
+                    for (; alert_list != NULL; alert_list = alert_list->next)
+                    {
+                        AddFuncToOutputList(sc, alert_list->func,
+                                            OUTPUT_TYPE__ALERT, alert_list->arg);
+                    }
+
+                    for (; log_list != NULL; log_list = log_list->next)
+                    {
+                        AddFuncToOutputList(sc, log_list->func,
+                                            OUTPUT_TYPE__LOG, log_list->arg);
+                    }
+
+                    sc->head_tmp = NULL;
+                    break;
+                }
+            }
+        }
+    }
+
+    /* XXX XXX Can't do any output plugins */
+    //PostConfigInitPlugins(sc->plugin_post_config_funcs);
+
+    fpCreateFastPacketDetection(sc);
+
+#ifdef PPM_MGR
+    PPM_PRINT_CFG(&sc->ppm_cfg);
+#endif
+
+    return sc;
+}
+
+static int VerifyReload(SnortConfig *sc)
+{
+    if (sc == NULL)
+        return -1;
+
+#ifdef TARGET_BASED
+    {
+        SnortPolicy *p1 = sc->targeted_policies[getDefaultPolicy()];
+        SnortPolicy *p2 = snort_conf->targeted_policies[getDefaultPolicy()];
+
+        if ((p1->target_based_config.args != NULL) &&
+            (p2->target_based_config.args != NULL))
+        {
+            if (strcasecmp(p1->target_based_config.args,
+                           p2->target_based_config.args) != 0)
+            {
+                ErrorMessage("Snort Reload: Changing the attribute table "
+                             "configuration requires a restart.\n");
+                return -1;
+            }
+        }
+        else if (p1->target_based_config.args !=
+                 p2->target_based_config.args)
+        {
+            /* Covers one being NULL and not the other */
+            ErrorMessage("Snort Reload: Changing the attribute table "
+                         "configuration requires a restart.\n");
+            return -1;
+        }
+    }
+#endif
+
+    if ((snort_conf->alert_file != NULL) && (sc->alert_file != NULL))
+    {
+        if (strcasecmp(snort_conf->alert_file, sc->alert_file) != 0)
+        {
+            ErrorMessage("Snort Reload: Changing the alert file "
+                         "configuration requires a restart.\n");
+            return -1;
+        }
+    }
+    else if (snort_conf->alert_file != sc->alert_file)
+    {
+        ErrorMessage("Snort Reload: Changing the alert file "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (snort_conf->asn1_mem != sc->asn1_mem)
+    {
+        ErrorMessage("Snort Reload: Changing the asn1 memory configuration "
+                     "requires a restart.\n");
+        return -1;
+    }
+
+    if ((sc->bpf_filter == NULL) && (sc->bpf_file != NULL))
+        sc->bpf_filter = read_infile(sc->bpf_file);
+
+    if ((sc->bpf_filter != NULL) && (snort_conf->bpf_filter != NULL))
+    {
+        if (strcasecmp(snort_conf->bpf_filter, sc->bpf_filter) != 0)
+        {
+            ErrorMessage("Snort Reload: Changing the bpf filter configuration "
+                         "requires a restart.\n");
+            return -1;
+        }
+    }
+    else if (sc->bpf_filter != snort_conf->bpf_filter)
+    {
+        ErrorMessage("Snort Reload: Changing the bpf filter configuration "
+                     "requires a restart.\n");
+        return -1;
+    }
+
+#ifdef ACTIVE_RESPONSE
+    if ( sc->respond_attempts != snort_conf->respond_attempts ||
+         sc->respond_device != snort_conf->respond_device )
+    {
+        ErrorMessage("Snort Reload: Changing config response "
+                     "requires a restart.\n");
+        return -1;
+    }
+#endif
+
+    if ((snort_conf->chroot_dir != NULL) &&
+        (sc->chroot_dir != NULL))
+    {
+        if (strcasecmp(snort_conf->chroot_dir, sc->chroot_dir) != 0)
+        {
+            ErrorMessage("Snort Reload: Changing the chroot directory "
+                         "configuration requires a restart.\n");
+            return -1;
+        }
+    }
+    else if (snort_conf->chroot_dir != sc->chroot_dir)
+    {
+        ErrorMessage("Snort Reload: Changing the chroot directory "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if ((snort_conf->run_flags & RUN_FLAG__DAEMON) !=
+        (sc->run_flags & RUN_FLAG__DAEMON))
+    {
+        ErrorMessage("Snort Reload: Changing to or from daemon mode "
+                     "requires a restart.\n");
+        return -1;
+    }
+
+    if ((snort_conf->interface != NULL) && (sc->interface != NULL))
+    {
+        if (strcasecmp(snort_conf->interface, sc->interface) != 0)
+        {
+            ErrorMessage("Snort Reload: Changing the interface "
+                         "configuration requires a restart.\n");
+            return -1;
+        }
+    }
+    else if (snort_conf->interface != sc->interface)
+    {
+        ErrorMessage("Snort Reload: Changing the interface "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    /* Orig log dir because a chroot might have changed it */
+    if ((snort_conf->orig_log_dir != NULL) &&
+        (sc->orig_log_dir != NULL))
+    {
+        if (strcasecmp(snort_conf->orig_log_dir, sc->orig_log_dir) != 0)
+        {
+            ErrorMessage("Snort Reload: Changing the log directory "
+                         "configuration requires a restart.\n");
+            return -1;
+        }
+    }
+    else if (snort_conf->orig_log_dir != sc->orig_log_dir)
+    {
+        ErrorMessage("Snort Reload: Changing the log directory "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+#ifdef TARGET_BASED
+    if (snort_conf->max_attribute_hosts != sc->max_attribute_hosts)
+    {
+        ErrorMessage("Snort Reload: Changing max_attribute_hosts "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+    if (snort_conf->max_attribute_services_per_host != sc->max_attribute_services_per_host)
+    {
+        ErrorMessage("Snort Reload: Changing max_attribute_services_per_host "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+#endif
+
+    if (snort_conf->no_log != sc->no_log)
+    {
+        ErrorMessage("Snort Reload: Changing from log to no log or vice "
+                     "versa requires a restart.\n");
+        return -1;
+    }
+
+    if ((snort_conf->run_flags & RUN_FLAG__NO_PROMISCUOUS) !=
+        (sc->run_flags & RUN_FLAG__NO_PROMISCUOUS))
+    {
+        ErrorMessage("Snort Reload: Changing to or from promiscuous mode "
+                     "requires a restart.\n");
+        return -1;
+    }
+
+#ifdef PPM_MGR
+    /* XXX XXX Not really sure we need to disallow this */
+    if (snort_conf->ppm_cfg.rule_log != sc->ppm_cfg.rule_log)
+    {
+        ErrorMessage("Snort Reload: Changing the ppm rule_log "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+#endif
+
+#ifdef PERF_PROFILING
+    if ((snort_conf->profile_rules.num != sc->profile_rules.num) ||
+        (snort_conf->profile_rules.sort != sc->profile_rules.sort) ||
+        (snort_conf->profile_rules.append != sc->profile_rules.append))
+    {
+        ErrorMessage("Snort Reload: Changing rule profiling number, sort "
+                     "or append configuration requires a restart.\n");
+        return -1;
+    }
+
+    if ((snort_conf->profile_rules.filename != NULL) &&
+        (sc->profile_rules.filename != NULL))
+    {
+        if (strcasecmp(snort_conf->profile_rules.filename,
+                       sc->profile_rules.filename) != 0)
+        {
+            ErrorMessage("Snort Reload: Changing the rule profiling filename "
+                         "configuration requires a restart.\n");
+            return -1;
+        }
+    }
+    else if (snort_conf->profile_rules.filename !=
+             sc->profile_rules.filename)
+    {
+        ErrorMessage("Snort Reload: Changing the rule profiling filename "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if ((snort_conf->profile_preprocs.num !=  sc->profile_preprocs.num) ||
+        (snort_conf->profile_preprocs.sort != sc->profile_preprocs.sort) ||
+        (snort_conf->profile_preprocs.append != sc->profile_preprocs.append))
+    {
+        ErrorMessage("Snort Reload: Changing preprocessor profiling number, "
+                     "sort or append configuration requires a restart.\n");
+        return -1;
+    }
+
+    if ((snort_conf->profile_preprocs.filename != NULL) &&
+        (sc->profile_preprocs.filename != NULL))
+    {
+        if (strcasecmp(snort_conf->profile_preprocs.filename,
+                       sc->profile_preprocs.filename) != 0)
+        {
+            ErrorMessage("Snort Reload: Changing the preprocessor profiling "
+                         "filename configuration requires a restart.\n");
+            return -1;
+        }
+    }
+    else if (snort_conf->profile_preprocs.filename !=
+             sc->profile_preprocs.filename)
+    {
+        ErrorMessage("Snort Reload: Changing the preprocessor profiling "
+                     "filename configuration requires a restart.\n");
+        return -1;
+    }
+#endif
+
+    if (snort_conf->group_id != sc->group_id)
+    {
+        ErrorMessage("Snort Reload: Changing the group id "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (snort_conf->user_id != sc->user_id)
+    {
+        ErrorMessage("Snort Reload: Changing the user id "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (snort_conf->pkt_snaplen != sc->pkt_snaplen)
+    {
+        ErrorMessage("Snort Reload: Changing the packet snaplen "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (snort_conf->threshold_config->memcap !=
+        sc->threshold_config->memcap)
+    {
+        ErrorMessage("Snort Reload: Changing the threshold memcap "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (snort_conf->rate_filter_config->memcap !=
+        sc->rate_filter_config->memcap)
+    {
+        ErrorMessage("Snort Reload: Changing the rate filter memcap "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (snort_conf->detection_filter_config->memcap !=
+        sc->detection_filter_config->memcap)
+    {
+        ErrorMessage("Snort Reload: Changing the detection filter memcap "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (VerifyLibInfos(snort_conf->dyn_engines, sc->dyn_engines) == -1)
+    {
+        ErrorMessage("Snort Reload: Any change to the dynamic engine "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (VerifyLibInfos(snort_conf->dyn_rules, sc->dyn_rules) == -1)
+    {
+        ErrorMessage("Snort Reload: Any change to the dynamic detection "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (VerifyLibInfos(snort_conf->dyn_preprocs, sc->dyn_preprocs) == -1)
+    {
+        ErrorMessage("Snort Reload: Any change to the dynamic preprocessor "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (snort_conf->so_rule_memcap != sc->so_rule_memcap)
+    {
+        ErrorMessage("Snort Reload: Changing the so rule memcap "
+                     "configuration requires a restart.\n");
+        return -1;
+    }
+
+    if (VerifyOutputs(snort_conf, sc) == -1)
+        return -1;
+
+#ifdef SIDE_CHANNEL
+    if (SideChannelVerifyConfig(sc) != 0)
+    {
+        ErrorMessage("Snort Reload: Changing the side channel configuration requires a restart.\n");
+        return -1;
+    }
+#endif
+
+    return 0;
+}
+
+static int VerifyOutputs(SnortConfig *old_config, SnortConfig *new_config)
+{
+    OutputConfig *old_output_config, *new_output_config;
+    int old_outputs = 0, new_outputs = 0;
+
+    /* Get from output_configs to see if output has changed */
+    for (old_output_config = old_config->output_configs;
+         old_output_config != NULL;
+         old_output_config = old_output_config->next)
+    {
+        old_outputs++;
+    }
+
+    for (new_output_config = new_config->output_configs;
+         new_output_config != NULL;
+         new_output_config = new_output_config->next)
+    {
+        new_outputs++;
+    }
+
+    if (new_outputs != old_outputs)
+    {
+        ErrorMessage("Snort Reload: Any change to any output "
+                     "configurations requires a restart.\n");
+        return -1;
+    }
+
+    for (old_output_config = old_config->output_configs;
+         old_output_config != NULL;
+         old_output_config = old_output_config->next)
+    {
+
+        for (new_output_config = new_config->output_configs;
+                new_output_config != NULL;
+                new_output_config = new_output_config->next)
+        {
+            if (strcasecmp(old_output_config->keyword, new_output_config->keyword) == 0)
+            {
+                if ((old_output_config->opts != NULL) &&
+                        (new_output_config->opts != NULL) &&
+                        (strcasecmp(old_output_config->opts, new_output_config->opts) == 0))
+                {
+                    new_outputs++;
+                    break;
+                }
+                else if (old_output_config->opts == NULL &&
+                        new_output_config->opts == NULL)
+                {
+                    new_outputs++;
+                    break;
+                }
+            }
+
+        }
+
+        old_outputs++;
+    }
+
+    if (new_outputs != old_outputs)
+    {
+        ErrorMessage("Snort Reload: Any change to any output "
+                     "configurations requires a restart.\n");
+        return -1;
+    }
+
+    /* Check user defined rule type outputs */
+    for (old_output_config = old_config->rule_type_output_configs;
+         old_output_config != NULL;
+         old_output_config = old_output_config->next)
+    {
+        old_outputs++;
+    }
+
+    for (new_output_config = new_config->rule_type_output_configs;
+         new_output_config != NULL;
+         new_output_config = new_output_config->next)
+    {
+        new_outputs++;
+    }
+
+    if (new_outputs != old_outputs)
+    {
+        ErrorMessage("Snort Reload: Any change to any output "
+                     "configurations requires a restart.\n");
+        return -1;
+    }
+
+    /* Do user defined rule type outputs as well */
+    for (old_output_config = old_config->rule_type_output_configs;
+         old_output_config != NULL;
+         old_output_config = old_output_config->next)
+    {
+        for (new_output_config = new_config->rule_type_output_configs;
+             new_output_config != NULL;
+             new_output_config = new_output_config->next)
+        {
+            if (strcasecmp(old_output_config->keyword,
+                           new_output_config->keyword) == 0)
+            {
+                if (strcasecmp(old_output_config->opts,
+                               new_output_config->opts) == 0)
+                {
+                    new_outputs++;
+                    break;
+                }
+            }
+        }
+
+        old_outputs++;
+    }
+
+    if (new_outputs != old_outputs)
+    {
+        ErrorMessage("Snort Reload: Any change to any output "
+                     "configurations requires a restart.\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int VerifyLibInfos(DynamicLibInfo *old_info, DynamicLibInfo *new_info)
+{
+    if ((old_info != NULL) && (new_info != NULL))
+    {
+        unsigned i;
+
+        if (old_info->type != new_info->type)
+        {
+            FatalError("%s(%d) Incompatible library types.\n",
+                       __FILE__, __LINE__);
+        }
+
+        if (old_info->count != new_info->count)
+            return -1;
+
+        for (i = 0; i < old_info->count; i++)
+        {
+            unsigned j;
+            DynamicLibPath *old_path = old_info->lib_paths[i];
+
+            for (j = 0; j < new_info->count; j++)
+            {
+                DynamicLibPath *new_path = new_info->lib_paths[j];
+
+                if ((strcmp(old_path->path, new_path->path) == 0) &&
+                    (old_path->ptype == new_path->ptype))
+                {
+                    if (old_path->last_mod_time != new_path->last_mod_time)
+                        return -1;
+
+                    break;
+                }
+            }
+
+            if (j == new_info->count)
+                return -1;
+        }
+    }
+    else if (old_info != new_info)
+    {
+        return -1;
+    }
+
+    return 0;
+}
+#endif  /* SNORT_RELOAD */
+
--- /dev/null
+++ b/snort/snort-patches/0001-add-dependancy-for-lrt.patch
@@ -0,0 +1,30 @@
+From 1cc044fb3b00c290afcacab3ca044d371bb039be Mon Sep 17 00:00:00 2001
+From: Maxim Uvarov <maxim.uvarov@linaro.org>
+Date: Wed, 9 Apr 2014 18:42:29 +0400
+Subject: [PATCH] add dependancy for -lrt
+
+Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
+---
+ snort-2.9.6.0/src/snort.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/snort-2.9.6.0/src/snort.c b/snort-2.9.6.0/src/snort.c
+index 1481d4f..0280107 100644
+--- a/snort-2.9.6.0/src/snort.c
++++ b/snort-2.9.6.0/src/snort.c
+@@ -777,6 +777,12 @@ static int InlineFailOpen (void)
+  */
+ int main(int argc, char *argv[])
+ {
++	/* hack to add deps to -lrt for timer_create() and friends from odp */
++	static volatile int link_rt = 0;
++	timer_t timerid = 0;
++	if (link_rt)
++		timer_settime(timerid, 0, NULL, NULL);
++
+ #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
+     /* Do some sanity checking, because some people seem to forget to
+      * put spaces between their parameters
+-- 
+1.7.9.5
+
