#include "tm-threads.h"
#include "source-pcap.h"
#include "conf.h"
+#include "util-bpf.h"
#include "util-debug.h"
#include "util-error.h"
#include "util-privs.h"
} PcapThreadVars;
static TmEcode ReceivePcapThreadInit(ThreadVars *, const void *, void **);
+static TmEcode ReceivePcapThreadDeinit(ThreadVars *tv, void *data);
static void ReceivePcapThreadExitStats(ThreadVars *, void *);
static TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot);
static TmEcode ReceivePcapBreakLoop(ThreadVars *tv, void *data);
{
tmm_modules[TMM_RECEIVEPCAP].name = "ReceivePcap";
tmm_modules[TMM_RECEIVEPCAP].ThreadInit = ReceivePcapThreadInit;
+ tmm_modules[TMM_RECEIVEPCAP].ThreadDeinit = ReceivePcapThreadDeinit;
tmm_modules[TMM_RECEIVEPCAP].PktAcqLoop = ReceivePcapLoop;
tmm_modules[TMM_RECEIVEPCAP].PktAcqBreakLoop = ReceivePcapBreakLoop;
tmm_modules[TMM_RECEIVEPCAP].ThreadExitPrintStats = ReceivePcapThreadExitStats;
ptv->livedev = LiveGetDevice(pcapconfig->iface);
if (ptv->livedev == NULL) {
SCLogError(SC_ERR_INVALID_VALUE, "unable to find Live device");
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
SCReturnInt(TM_ECODE_FAILED);
}
SCLogInfo("using interface %s", (char *)pcapconfig->iface);
"pcap handler for %s",
(char *)pcapconfig->iface);
}
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
if (pcap_set_snaplen_r != 0) {
SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "could not set snaplen, "
"error: %s", pcap_geterr(ptv->pcap_handle));
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
if (pcap_set_promisc_r != 0) {
SCLogError(SC_ERR_PCAP_SET_PROMISC, "could not set promisc mode, "
"error %s", pcap_geterr(ptv->pcap_handle));
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
if (pcap_set_timeout_r != 0) {
SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "could not set timeout, "
"error %s", pcap_geterr(ptv->pcap_handle));
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
if (pcap_set_buffer_size_r != 0) {
SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "could not set "
"pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle));
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
if (pcap_activate_r != 0) {
SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "could not activate the "
"pcap handler, error %s", pcap_geterr(ptv->pcap_handle));
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED);
}
pcap_geterr(ptv->pcap_handle));
SCMutexUnlock(&pcap_bpf_compile_lock);
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED;
}
pcap_geterr(ptv->pcap_handle));
SCMutexUnlock(&pcap_bpf_compile_lock);
- SCFree(ptv);
+ ReceivePcapThreadDeinit(tv, ptv);
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED;
}
}
}
+static TmEcode ReceivePcapThreadDeinit(ThreadVars *tv, void *data)
+{
+ SCEnter();
+ PcapThreadVars *ptv = (PcapThreadVars *)data;
+ if (ptv != NULL) {
+ if (ptv->pcap_handle != NULL) {
+ pcap_close(ptv->pcap_handle);
+ }
+ if (ptv->filter.bf_insns) {
+ SCBPFFree(&ptv->filter);
+ }
+ SCFree(ptv);
+ }
+ SCReturnInt(TM_ECODE_OK);
+}
+
/**
* \brief This function passes off to link type decoders.
*