aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/source-pcap-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/suricata/src/source-pcap-file.c')
-rw-r--r--framework/src/suricata/src/source-pcap-file.c475
1 files changed, 0 insertions, 475 deletions
diff --git a/framework/src/suricata/src/source-pcap-file.c b/framework/src/suricata/src/source-pcap-file.c
deleted file mode 100644
index 0b982fd3..00000000
--- a/framework/src/suricata/src/source-pcap-file.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/* Copyright (C) 2007-2014 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * 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
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Victor Julien <victor@inliniac.net>
- *
- * File based pcap packet acquisition support
- */
-
-#include "suricata-common.h"
-#include "suricata.h"
-#include "decode.h"
-#include "packet-queue.h"
-#include "threads.h"
-#include "threadvars.h"
-#include "tm-queuehandlers.h"
-#include "source-pcap-file.h"
-#include "util-time.h"
-#include "util-debug.h"
-#include "conf.h"
-#include "util-error.h"
-#include "util-privs.h"
-#include "tmqh-packetpool.h"
-#include "tm-threads.h"
-#include "util-optimize.h"
-#include "flow-manager.h"
-#include "util-profiling.h"
-#include "runmode-unix-socket.h"
-#include "util-checksum.h"
-#include "util-atomic.h"
-
-#ifdef __SC_CUDA_SUPPORT__
-
-#include "util-cuda.h"
-#include "util-cuda-buffer.h"
-#include "util-mpm-ac.h"
-#include "util-cuda-handlers.h"
-#include "detect-engine.h"
-#include "detect-engine-mpm.h"
-#include "util-cuda-vars.h"
-
-#endif /* __SC_CUDA_SUPPORT__ */
-
-extern int max_pending_packets;
-
-//static int pcap_max_read_packets = 0;
-
-typedef struct PcapFileGlobalVars_ {
- pcap_t *pcap_handle;
- int (*Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
- int datalink;
- struct bpf_program filter;
- uint64_t cnt; /** packet counter */
- ChecksumValidationMode conf_checksum_mode;
- ChecksumValidationMode checksum_mode;
- SC_ATOMIC_DECLARE(unsigned int, invalid_checksums);
-
-} PcapFileGlobalVars;
-
-/** max packets < 65536 */
-//#define PCAP_FILE_MAX_PKTS 256
-
-typedef struct PcapFileThreadVars_
-{
- uint32_t tenant_id;
-
- /* counters */
- uint32_t pkts;
- uint64_t bytes;
-
- ThreadVars *tv;
- TmSlot *slot;
-
- /** callback result -- set if one of the thread module failed. */
- int cb_result;
-
- uint8_t done;
- uint32_t errs;
-} PcapFileThreadVars;
-
-static PcapFileGlobalVars pcap_g;
-
-TmEcode ReceivePcapFileLoop(ThreadVars *, void *, void *);
-
-TmEcode ReceivePcapFileThreadInit(ThreadVars *, void *, void **);
-void ReceivePcapFileThreadExitStats(ThreadVars *, void *);
-TmEcode ReceivePcapFileThreadDeinit(ThreadVars *, void *);
-
-TmEcode DecodePcapFile(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
-TmEcode DecodePcapFileThreadInit(ThreadVars *, void *, void **);
-TmEcode DecodePcapFileThreadDeinit(ThreadVars *tv, void *data);
-
-void TmModuleReceivePcapFileRegister (void)
-{
- memset(&pcap_g, 0x00, sizeof(pcap_g));
-
- tmm_modules[TMM_RECEIVEPCAPFILE].name = "ReceivePcapFile";
- tmm_modules[TMM_RECEIVEPCAPFILE].ThreadInit = ReceivePcapFileThreadInit;
- tmm_modules[TMM_RECEIVEPCAPFILE].Func = NULL;
- tmm_modules[TMM_RECEIVEPCAPFILE].PktAcqLoop = ReceivePcapFileLoop;
- tmm_modules[TMM_RECEIVEPCAPFILE].ThreadExitPrintStats = ReceivePcapFileThreadExitStats;
- tmm_modules[TMM_RECEIVEPCAPFILE].ThreadDeinit = ReceivePcapFileThreadDeinit;
- tmm_modules[TMM_RECEIVEPCAPFILE].RegisterTests = NULL;
- tmm_modules[TMM_RECEIVEPCAPFILE].cap_flags = 0;
- tmm_modules[TMM_RECEIVEPCAPFILE].flags = TM_FLAG_RECEIVE_TM;
-}
-
-void TmModuleDecodePcapFileRegister (void)
-{
- tmm_modules[TMM_DECODEPCAPFILE].name = "DecodePcapFile";
- tmm_modules[TMM_DECODEPCAPFILE].ThreadInit = DecodePcapFileThreadInit;
- tmm_modules[TMM_DECODEPCAPFILE].Func = DecodePcapFile;
- tmm_modules[TMM_DECODEPCAPFILE].ThreadExitPrintStats = NULL;
- tmm_modules[TMM_DECODEPCAPFILE].ThreadDeinit = DecodePcapFileThreadDeinit;
- tmm_modules[TMM_DECODEPCAPFILE].RegisterTests = NULL;
- tmm_modules[TMM_DECODEPCAPFILE].cap_flags = 0;
- tmm_modules[TMM_DECODEPCAPFILE].flags = TM_FLAG_DECODE_TM;
-}
-
-void PcapFileGlobalInit()
-{
- SC_ATOMIC_INIT(pcap_g.invalid_checksums);
-}
-
-void PcapFileCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt)
-{
- SCEnter();
-
- PcapFileThreadVars *ptv = (PcapFileThreadVars *)user;
- Packet *p = PacketGetFromQueueOrAlloc();
-
- if (unlikely(p == NULL)) {
- SCReturn;
- }
- PACKET_PROFILING_TMM_START(p, TMM_RECEIVEPCAPFILE);
-
- PKT_SET_SRC(p, PKT_SRC_WIRE);
- p->ts.tv_sec = h->ts.tv_sec;
- p->ts.tv_usec = h->ts.tv_usec;
- SCLogDebug("p->ts.tv_sec %"PRIuMAX"", (uintmax_t)p->ts.tv_sec);
- p->datalink = pcap_g.datalink;
- p->pcap_cnt = ++pcap_g.cnt;
-
- p->pcap_v.tenant_id = ptv->tenant_id;
- ptv->pkts++;
- ptv->bytes += h->caplen;
-
- if (unlikely(PacketCopyData(p, pkt, h->caplen))) {
- TmqhOutputPacketpool(ptv->tv, p);
- PACKET_PROFILING_TMM_END(p, TMM_RECEIVEPCAPFILE);
- SCReturn;
- }
-
- /* We only check for checksum disable */
- if (pcap_g.checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
- p->flags |= PKT_IGNORE_CHECKSUM;
- } else if (pcap_g.checksum_mode == CHECKSUM_VALIDATION_AUTO) {
- if (ChecksumAutoModeCheck(ptv->pkts, p->pcap_cnt,
- SC_ATOMIC_GET(pcap_g.invalid_checksums))) {
- pcap_g.checksum_mode = CHECKSUM_VALIDATION_DISABLE;
- p->flags |= PKT_IGNORE_CHECKSUM;
- }
- }
-
- PACKET_PROFILING_TMM_END(p, TMM_RECEIVEPCAPFILE);
-
- if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
- pcap_breakloop(pcap_g.pcap_handle);
- ptv->cb_result = TM_ECODE_FAILED;
- }
-
- SCReturn;
-}
-
-/**
- * \brief Main PCAP file reading Loop function
- */
-TmEcode ReceivePcapFileLoop(ThreadVars *tv, void *data, void *slot)
-{
- SCEnter();
-
- int packet_q_len = 64;
- PcapFileThreadVars *ptv = (PcapFileThreadVars *)data;
- int r;
- TmSlot *s = (TmSlot *)slot;
-
- ptv->slot = s->slot_next;
- ptv->cb_result = TM_ECODE_OK;
-
- while (1) {
- if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) {
- SCReturnInt(TM_ECODE_OK);
- }
-
- /* make sure we have at least one packet in the packet pool, to prevent
- * us from alloc'ing packets at line rate */
- PacketPoolWait();
-
- /* Right now we just support reading packets one at a time. */
- r = pcap_dispatch(pcap_g.pcap_handle, packet_q_len,
- (pcap_handler)PcapFileCallbackLoop, (u_char *)ptv);
- if (unlikely(r == -1)) {
- SCLogError(SC_ERR_PCAP_DISPATCH, "error code %" PRId32 " %s",
- r, pcap_geterr(pcap_g.pcap_handle));
- if (! RunModeUnixSocketIsActive()) {
- /* in the error state we just kill the engine */
- EngineKill();
- SCReturnInt(TM_ECODE_FAILED);
- } else {
- pcap_close(pcap_g.pcap_handle);
- pcap_g.pcap_handle = NULL;
- UnixSocketPcapFile(TM_ECODE_DONE);
- SCReturnInt(TM_ECODE_DONE);
- }
- } else if (unlikely(r == 0)) {
- SCLogInfo("pcap file end of file reached (pcap err code %" PRId32 ")", r);
- if (! RunModeUnixSocketIsActive()) {
- EngineStop();
- } else {
- pcap_close(pcap_g.pcap_handle);
- pcap_g.pcap_handle = NULL;
- UnixSocketPcapFile(TM_ECODE_DONE);
- SCReturnInt(TM_ECODE_DONE);
- }
- break;
- } else if (ptv->cb_result == TM_ECODE_FAILED) {
- SCLogError(SC_ERR_PCAP_DISPATCH, "Pcap callback PcapFileCallbackLoop failed");
- if (! RunModeUnixSocketIsActive()) {
- EngineKill();
- SCReturnInt(TM_ECODE_FAILED);
- } else {
- pcap_close(pcap_g.pcap_handle);
- pcap_g.pcap_handle = NULL;
- UnixSocketPcapFile(TM_ECODE_DONE);
- SCReturnInt(TM_ECODE_DONE);
- }
- }
- StatsSyncCountersIfSignalled(tv);
- }
-
- SCReturnInt(TM_ECODE_OK);
-}
-
-TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data)
-{
- SCEnter();
- char *tmpbpfstring = NULL;
- char *tmpstring = NULL;
- if (initdata == NULL) {
- SCLogError(SC_ERR_INVALID_ARGUMENT, "error: initdata == NULL");
- SCReturnInt(TM_ECODE_FAILED);
- }
-
- SCLogInfo("reading pcap file %s", (char *)initdata);
-
- PcapFileThreadVars *ptv = SCMalloc(sizeof(PcapFileThreadVars));
- if (unlikely(ptv == NULL))
- SCReturnInt(TM_ECODE_FAILED);
- memset(ptv, 0, sizeof(PcapFileThreadVars));
-
- intmax_t tenant = 0;
- if (ConfGetInt("pcap-file.tenant-id", &tenant) == 1) {
- if (tenant > 0 && tenant < UINT_MAX) {
- ptv->tenant_id = (uint32_t)tenant;
- SCLogInfo("tenant %u", ptv->tenant_id);
- } else {
- SCLogError(SC_ERR_INVALID_ARGUMENT, "tenant out of range");
- }
- }
-
- char errbuf[PCAP_ERRBUF_SIZE] = "";
- pcap_g.pcap_handle = pcap_open_offline((char *)initdata, errbuf);
- if (pcap_g.pcap_handle == NULL) {
- SCLogError(SC_ERR_FOPEN, "%s\n", errbuf);
- SCFree(ptv);
- if (! RunModeUnixSocketIsActive()) {
- return TM_ECODE_FAILED;
- } else {
- UnixSocketPcapFile(TM_ECODE_FAILED);
- SCReturnInt(TM_ECODE_DONE);
- }
- }
-
- if (ConfGet("bpf-filter", &tmpbpfstring) != 1) {
- SCLogDebug("could not get bpf or none specified");
- } else {
- SCLogInfo("using bpf-filter \"%s\"", tmpbpfstring);
-
- if(pcap_compile(pcap_g.pcap_handle,&pcap_g.filter,tmpbpfstring,1,0) < 0) {
- SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(pcap_g.pcap_handle));
- SCFree(ptv);
- return TM_ECODE_FAILED;
- }
-
- if(pcap_setfilter(pcap_g.pcap_handle,&pcap_g.filter) < 0) {
- SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(pcap_g.pcap_handle));
- SCFree(ptv);
- return TM_ECODE_FAILED;
- }
- }
-
- pcap_g.datalink = pcap_datalink(pcap_g.pcap_handle);
- SCLogDebug("datalink %" PRId32 "", pcap_g.datalink);
-
- switch(pcap_g.datalink) {
- case LINKTYPE_LINUX_SLL:
- pcap_g.Decoder = DecodeSll;
- break;
- case LINKTYPE_ETHERNET:
- pcap_g.Decoder = DecodeEthernet;
- break;
- case LINKTYPE_PPP:
- pcap_g.Decoder = DecodePPP;
- break;
- case LINKTYPE_RAW:
- pcap_g.Decoder = DecodeRaw;
- break;
- case LINKTYPE_NULL:
- pcap_g.Decoder = DecodeNull;
- break;
-
- default:
- SCLogError(SC_ERR_UNIMPLEMENTED, "datalink type %" PRId32 " not "
- "(yet) supported in module PcapFile.\n", pcap_g.datalink);
- SCFree(ptv);
- if (! RunModeUnixSocketIsActive()) {
- SCReturnInt(TM_ECODE_FAILED);
- } else {
- pcap_close(pcap_g.pcap_handle);
- pcap_g.pcap_handle = NULL;
- UnixSocketPcapFile(TM_ECODE_DONE);
- SCReturnInt(TM_ECODE_DONE);
- }
- }
-
- if (ConfGet("pcap-file.checksum-checks", &tmpstring) != 1) {
- pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_AUTO;
- } else {
- if (strcmp(tmpstring, "auto") == 0) {
- pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_AUTO;
- } else if (strcmp(tmpstring, "yes") == 0) {
- pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_ENABLE;
- } else if (strcmp(tmpstring, "no") == 0) {
- pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_DISABLE;
- }
- }
- pcap_g.checksum_mode = pcap_g.conf_checksum_mode;
-
- ptv->tv = tv;
- *data = (void *)ptv;
-
- SCReturnInt(TM_ECODE_OK);
-}
-
-void ReceivePcapFileThreadExitStats(ThreadVars *tv, void *data)
-{
- SCEnter();
- PcapFileThreadVars *ptv = (PcapFileThreadVars *)data;
-
- if (pcap_g.conf_checksum_mode == CHECKSUM_VALIDATION_AUTO &&
- pcap_g.cnt < CHECKSUM_SAMPLE_COUNT &&
- SC_ATOMIC_GET(pcap_g.invalid_checksums)) {
- uint64_t chrate = pcap_g.cnt / SC_ATOMIC_GET(pcap_g.invalid_checksums);
- if (chrate < CHECKSUM_INVALID_RATIO)
- SCLogWarning(SC_ERR_INVALID_CHECKSUM,
- "1/%" PRIu64 "th of packets have an invalid checksum,"
- " consider setting pcap-file.checksum-checks variable to no"
- " or use '-k none' option on command line.",
- chrate);
- else
- SCLogInfo("1/%" PRIu64 "th of packets have an invalid checksum",
- chrate);
- }
- SCLogNotice("Pcap-file module read %" PRIu32 " packets, %" PRIu64 " bytes", ptv->pkts, ptv->bytes);
- return;
-}
-
-TmEcode ReceivePcapFileThreadDeinit(ThreadVars *tv, void *data)
-{
- SCEnter();
- PcapFileThreadVars *ptv = (PcapFileThreadVars *)data;
- if (ptv) {
- SCFree(ptv);
- }
- SCReturnInt(TM_ECODE_OK);
-}
-
-double prev_signaled_ts = 0;
-
-TmEcode DecodePcapFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
-{
- SCEnter();
- DecodeThreadVars *dtv = (DecodeThreadVars *)data;
-
- /* XXX HACK: flow timeout can call us for injected pseudo packets
- * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
- if (p->flags & PKT_PSEUDO_STREAM_END)
- return TM_ECODE_OK;
-
- /* update counters */
- DecodeUpdatePacketCounters(tv, dtv, p);
-
- double curr_ts = p->ts.tv_sec + p->ts.tv_usec / 1000.0;
- if (curr_ts < prev_signaled_ts || (curr_ts - prev_signaled_ts) > 60.0) {
- prev_signaled_ts = curr_ts;
- FlowWakeupFlowManagerThread();
- }
-
- /* update the engine time representation based on the timestamp
- * of the packet. */
- TimeSet(&p->ts);
-
- /* call the decoder */
- pcap_g.Decoder(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
-
-#ifdef DEBUG
- BUG_ON(p->pkt_src != PKT_SRC_WIRE && p->pkt_src != PKT_SRC_FFR);
-#endif
-
- PacketDecodeFinalize(tv, dtv, p);
-
- SCReturnInt(TM_ECODE_OK);
-}
-
-TmEcode DecodePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data)
-{
- SCEnter();
- DecodeThreadVars *dtv = NULL;
- dtv = DecodeThreadVarsAlloc(tv);
-
- if (dtv == NULL)
- SCReturnInt(TM_ECODE_FAILED);
-
- DecodeRegisterPerfCounters(dtv, tv);
-
-#ifdef __SC_CUDA_SUPPORT__
- if (CudaThreadVarsInit(&dtv->cuda_vars) < 0)
- SCReturnInt(TM_ECODE_FAILED);
-#endif
-
- *data = (void *)dtv;
-
- SCReturnInt(TM_ECODE_OK);
-}
-
-TmEcode DecodePcapFileThreadDeinit(ThreadVars *tv, void *data)
-{
- if (data != NULL)
- DecodeThreadVarsFree(tv, data);
- SCReturnInt(TM_ECODE_OK);
-}
-
-void PcapIncreaseInvalidChecksum()
-{
- (void) SC_ATOMIC_ADD(pcap_g.invalid_checksums, 1);
-}
-
-/* eof */
-