diff options
Diffstat (limited to 'framework/src/suricata/src/suricata.c')
-rw-r--r-- | framework/src/suricata/src/suricata.c | 2564 |
1 files changed, 0 insertions, 2564 deletions
diff --git a/framework/src/suricata/src/suricata.c b/framework/src/suricata/src/suricata.c deleted file mode 100644 index b368f21d..00000000 --- a/framework/src/suricata/src/suricata.c +++ /dev/null @@ -1,2564 +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> - */ - -#include "suricata-common.h" -#include "config.h" - -#if HAVE_GETOPT_H -#include <getopt.h> -#endif - -#if HAVE_SIGNAL_H -#include <signal.h> -#endif - -#ifdef HAVE_NSS -#include <prinit.h> -#include <nss.h> -#endif - -#include "suricata.h" -#include "decode.h" -#include "detect.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" - -#include "util-atomic.h" -#include "util-spm.h" -#include "util-cpu.h" -#include "util-action.h" -#include "util-pidfile.h" -#include "util-ioctl.h" -#include "util-device.h" -#include "util-misc.h" -#include "util-running-modes.h" - -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-fast-pattern.h" -#include "detect-engine-tag.h" -#include "detect-engine-threshold.h" -#include "detect-engine-address.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" - -#include "tm-queuehandlers.h" -#include "tm-queues.h" -#include "tm-threads.h" - -#include "tmqh-flow.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "alert-fastlog.h" -#include "alert-unified2-alert.h" -#include "alert-debuglog.h" -#include "alert-prelude.h" -#include "alert-syslog.h" -#include "output-json-alert.h" - -#include "output-json-flow.h" -#include "output-json-netflow.h" -#include "log-droplog.h" -#include "output-json-drop.h" -#include "log-httplog.h" -#include "output-json-http.h" -#include "log-dnslog.h" -#include "output-json-dns.h" -#include "log-tlslog.h" -#include "log-tlsstore.h" -#include "output-json-tls.h" -#include "output-json-ssh.h" -#include "log-pcap.h" -#include "log-file.h" -#include "output-json-file.h" -#include "output-json-smtp.h" -#include "output-json-stats.h" -#include "log-filestore.h" -#include "log-tcp-data.h" -#include "log-stats.h" - -#include "output-json.h" - -#include "output-json-template.h" - -#include "stream-tcp.h" - -#include "source-nfq.h" -#include "source-nfq-prototypes.h" - -#include "source-nflog.h" - -#include "source-ipfw.h" - -#include "source-pcap.h" -#include "source-pcap-file.h" - -#include "source-pfring.h" - -#include "source-erf-file.h" -#include "source-erf-dag.h" -#include "source-napatech.h" - -#include "source-af-packet.h" -#include "source-netmap.h" -#include "source-mpipe.h" - -#include "respond-reject.h" - -#include "flow.h" -#include "flow-timeout.h" -#include "flow-manager.h" -#include "flow-var.h" -#include "flow-bit.h" -#include "pkt-var.h" -#include "host-bit.h" - -#include "ippair.h" -#include "ippair-bit.h" - -#include "host.h" -#include "unix-manager.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" - -#include "util-radix-tree.h" -#include "util-host-os-info.h" -#include "util-cidr.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-time.h" -#include "util-rule-vars.h" -#include "util-classification-config.h" -#include "util-threshold-config.h" -#include "util-reference-config.h" -#include "util-profiling.h" -#include "util-magic.h" -#include "util-signal.h" - -#include "util-coredump-config.h" - -#include "util-decode-mime.h" - -#include "defrag.h" - -#include "runmodes.h" -#include "runmode-unittests.h" - -#include "util-cuda.h" -#include "util-decode-asn1.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-daemon.h" -#include "reputation.h" - -#include "output.h" -#include "output-lua.h" - -#include "output-packet.h" -#include "output-tx.h" -#include "output-file.h" -#include "output-filedata.h" -#include "output-streaming.h" - -#include "util-privs.h" - -#include "tmqh-packetpool.h" - -#include "util-proto-name.h" -#ifdef __SC_CUDA_SUPPORT__ -#include "util-cuda-buffer.h" -#include "util-mpm-ac.h" -#endif -#include "util-storage.h" -#include "host-storage.h" - -/* - * we put this here, because we only use it here in main. - */ -volatile sig_atomic_t sigint_count = 0; -volatile sig_atomic_t sighup_count = 0; -volatile sig_atomic_t sigterm_count = 0; -volatile sig_atomic_t sigusr2_count = 0; - -/* - * Flag to indicate if the engine is at the initialization - * or already processing packets. 3 stages: SURICATA_INIT, - * SURICATA_RUNTIME and SURICATA_FINALIZE - */ -SC_ATOMIC_DECLARE(unsigned int, engine_stage); - -/* Max packets processed simultaniously per thread. */ -#define DEFAULT_MAX_PENDING_PACKETS 1024 - -/** suricata engine control flags */ -volatile uint8_t suricata_ctl_flags = 0; - -/** Run mode selected */ -int run_mode = RUNMODE_UNKNOWN; - -/** Engine mode: inline (ENGINE_MODE_IPS) or just - * detection mode (ENGINE_MODE_IDS by default) */ -static enum EngineMode g_engine_mode = ENGINE_MODE_IDS; - -/** Host mode: set if box is sniffing only - * or is a router */ -uint8_t host_mode = SURI_HOST_IS_SNIFFER_ONLY; - -/** Maximum packets to simultaneously process. */ -intmax_t max_pending_packets; - -/** global indicating if detection is enabled */ -int g_detect_disabled = 0; - -/** set caps or not */ -int sc_set_caps; - -char *conf_filename = NULL; - -int EngineModeIsIPS(void) -{ - return (g_engine_mode == ENGINE_MODE_IPS); -} - -int EngineModeIsIDS(void) -{ - return (g_engine_mode == ENGINE_MODE_IDS); -} - -void EngineModeSetIPS(void) -{ - g_engine_mode = ENGINE_MODE_IPS; -} - -void EngineModeSetIDS(void) -{ - g_engine_mode = ENGINE_MODE_IDS; -} - -int RunmodeIsUnittests(void) -{ - if (run_mode == RUNMODE_UNITTEST) - return 1; - - return 0; -} - -int RunmodeGetCurrent(void) -{ - return run_mode; -} - -static void SignalHandlerSigint(/*@unused@*/ int sig) -{ - sigint_count = 1; - suricata_ctl_flags |= SURICATA_STOP; -} -static void SignalHandlerSigterm(/*@unused@*/ int sig) -{ - sigterm_count = 1; - suricata_ctl_flags |= SURICATA_KILL; -} - -void SignalHandlerSigusr2StartingUp(int sig) -{ - SCLogInfo("Live rule reload only possible after engine completely started."); -} - -void SignalHandlerSigusr2DelayedDetect(int sig) -{ - SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload blocked while delayed detect is still loading."); -} - -void SignalHandlerSigusr2SigFileStartup(int sig) -{ - SCLogInfo("Live rule reload not possible if -s or -S option used at runtime."); -} - -/** - * SIGUSR2 handler. Just set sigusr2_count. The main loop will act on - * it. - */ -void SignalHandlerSigusr2(int sig) -{ - sigusr2_count = 1; -} - -/** - * SIGHUP handler. Just set sighup_count. The main loop will act on - * it. - */ -static void SignalHandlerSigHup(/*@unused@*/ int sig) -{ - sighup_count = 1; -} - -#ifdef DBG_MEM_ALLOC -#ifndef _GLOBAL_MEM_ -#define _GLOBAL_MEM_ -/* This counter doesn't complain realloc's(), it's gives - * an aproximation for the startup */ -size_t global_mem = 0; -#ifdef DBG_MEM_ALLOC_SKIP_STARTUP -uint8_t print_mem_flag = 0; -#else -uint8_t print_mem_flag = 1; -#endif -#endif -#endif - -void CreateLowercaseTable() -{ - /* create table for O(1) lowercase conversion lookup. It was removed, but - * we still need it for cuda. So resintalling it back into the codebase */ - int c = 0; - memset(g_u8_lowercasetable, 0x00, sizeof(g_u8_lowercasetable)); - for ( ; c < 256; c++) { - if (c >= 'A' && c <= 'Z') - g_u8_lowercasetable[c] = (c + ('a' - 'A')); - else - g_u8_lowercasetable[c] = c; - } -} - -void GlobalInits() -{ - memset(trans_q, 0, sizeof(trans_q)); - memset(data_queues, 0, sizeof(data_queues)); - - /* Initialize the trans_q mutex */ - int blah; - int r = 0; - for(blah=0;blah<256;blah++) { - r |= SCMutexInit(&trans_q[blah].mutex_q, NULL); - r |= SCCondInit(&trans_q[blah].cond_q, NULL); - - r |= SCMutexInit(&data_queues[blah].mutex_q, NULL); - r |= SCCondInit(&data_queues[blah].cond_q, NULL); - } - - if (r != 0) { - SCLogInfo("Trans_Q Mutex not initialized correctly"); - exit(EXIT_FAILURE); - } - - CreateLowercaseTable(); -} - -/* XXX hack: make sure threads can stop the engine by calling this - function. Purpose: pcap file mode needs to be able to tell the - engine the file eof is reached. */ -void EngineStop(void) -{ - suricata_ctl_flags |= SURICATA_STOP; -} - -void EngineKill(void) -{ - suricata_ctl_flags |= SURICATA_KILL; -} - -/** - * \brief Used to indicate that the current task is done. - * - * This is mainly used by pcap-file to tell it has finished - * to treat a pcap files when running in unix-socket mode. - */ -void EngineDone(void) -{ - suricata_ctl_flags |= SURICATA_DONE; -} - -static int SetBpfString(int optind, char *argv[]) -{ - char *bpf_filter = NULL; - uint32_t bpf_len = 0; - int tmpindex = 0; - - /* attempt to parse remaining args as bpf filter */ - tmpindex = optind; - while(argv[tmpindex] != NULL) { - bpf_len+=strlen(argv[tmpindex]) + 1; - tmpindex++; - } - - if (bpf_len == 0) - return TM_ECODE_OK; - - if (EngineModeIsIPS()) { - SCLogError(SC_ERR_NOT_SUPPORTED, - "BPF filter not available in IPS mode." - " Use firewall filtering if possible."); - return TM_ECODE_FAILED; - } - - bpf_filter = SCMalloc(bpf_len); - if (unlikely(bpf_filter == NULL)) - return TM_ECODE_OK; - memset(bpf_filter, 0x00, bpf_len); - - tmpindex = optind; - while(argv[tmpindex] != NULL) { - strlcat(bpf_filter, argv[tmpindex],bpf_len); - if(argv[tmpindex + 1] != NULL) { - strlcat(bpf_filter," ", bpf_len); - } - tmpindex++; - } - - if(strlen(bpf_filter) > 0) { - if (ConfSetFinal("bpf-filter", bpf_filter) != 1) { - SCLogError(SC_ERR_FATAL, "Failed to set bpf filter."); - return TM_ECODE_FAILED; - } - } - SCFree(bpf_filter); - - return TM_ECODE_OK; -} - -static void SetBpfStringFromFile(char *filename) -{ - char *bpf_filter = NULL; - char *bpf_comment_tmp = NULL; - char *bpf_comment_start = NULL; - uint32_t bpf_len = 0; -#ifdef OS_WIN32 - struct _stat st; -#else - struct stat st; -#endif /* OS_WIN32 */ - FILE *fp = NULL; - size_t nm = 0; - - if (EngineModeIsIPS()) { - SCLogError(SC_ERR_NOT_SUPPORTED, - "BPF filter not available in IPS mode." - " Use firewall filtering if possible."); - exit(EXIT_FAILURE); - } - -#ifdef OS_WIN32 - if(_stat(filename, &st) != 0) { -#else - if(stat(filename, &st) != 0) { -#endif /* OS_WIN32 */ - SCLogError(SC_ERR_FOPEN, "Failed to stat file %s", filename); - exit(EXIT_FAILURE); - } - bpf_len = st.st_size + 1; - - fp = fopen(filename,"r"); - if (fp == NULL) { - SCLogError(SC_ERR_FOPEN, "Failed to open file %s", filename); - exit(EXIT_FAILURE); - } - - bpf_filter = SCMalloc(bpf_len * sizeof(char)); - if (unlikely(bpf_filter == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate buffer for bpf filter in file %s", filename); - exit(EXIT_FAILURE); - } - memset(bpf_filter, 0x00, bpf_len); - - nm = fread(bpf_filter, bpf_len - 1, 1, fp); - if((ferror(fp) != 0)||( nm != 1)) { - *bpf_filter='\0'; - } - fclose(fp); - - if(strlen(bpf_filter) > 0) { - /*replace comments with space*/ - bpf_comment_start = bpf_filter; - while((bpf_comment_tmp = strchr(bpf_comment_start, '#')) != NULL) { - while((*bpf_comment_tmp !='\0') && - (*bpf_comment_tmp != '\r') && (*bpf_comment_tmp != '\n')) - { - *bpf_comment_tmp++ = ' '; - } - bpf_comment_start = bpf_comment_tmp; - } - /*remove remaining '\r' and '\n' */ - while((bpf_comment_tmp = strchr(bpf_filter, '\r')) != NULL) { - *bpf_comment_tmp = ' '; - } - while((bpf_comment_tmp = strchr(bpf_filter, '\n')) != NULL) { - *bpf_comment_tmp = ' '; - } - if(ConfSetFinal("bpf-filter", bpf_filter) != 1) { - SCLogError(SC_ERR_FOPEN, "ERROR: Failed to set bpf filter!"); - SCFree(bpf_filter); - exit(EXIT_FAILURE); - } - } - SCFree(bpf_filter); -} - -void usage(const char *progname) -{ -#ifdef REVISION - printf("%s %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION)); -#else - printf("%s %s\n", PROG_NAME, PROG_VER); -#endif - printf("USAGE: %s [OPTIONS] [BPF FILTER]\n\n", progname); - printf("\t-c <path> : path to configuration file\n"); - printf("\t-T : test configuration file (use with -c)\n"); - printf("\t-i <dev or ip> : run in pcap live mode\n"); - printf("\t-F <bpf filter file> : bpf filter file\n"); - printf("\t-r <path> : run in pcap file/offline mode\n"); -#ifdef NFQ - printf("\t-q <qid> : run in inline nfqueue mode\n"); -#endif /* NFQ */ -#ifdef IPFW - printf("\t-d <divert port> : run in inline ipfw divert mode\n"); -#endif /* IPFW */ - printf("\t-s <path> : path to signature file loaded in addition to suricata.yaml settings (optional)\n"); - printf("\t-S <path> : path to signature file loaded exclusively (optional)\n"); - printf("\t-l <dir> : default log directory\n"); -#ifndef OS_WIN32 - printf("\t-D : run as daemon\n"); -#else - printf("\t--service-install : install as service\n"); - printf("\t--service-remove : remove service\n"); - printf("\t--service-change-params : change service startup parameters\n"); -#endif /* OS_WIN32 */ - printf("\t-k [all|none] : force checksum check (all) or disabled it (none)\n"); - printf("\t-V : display Suricata version\n"); - printf("\t-v[v] : increase default Suricata verbosity\n"); -#ifdef UNITTESTS - printf("\t-u : run the unittests and exit\n"); - printf("\t-U, --unittest-filter=REGEX : filter unittests with a regex\n"); - printf("\t--list-unittests : list unit tests\n"); - printf("\t--fatal-unittests : enable fatal failure on unittest error\n"); - printf("\t--unittests-coverage : display unittest coverage report\n"); -#endif /* UNITTESTS */ - printf("\t--list-app-layer-protos : list supported app layer protocols\n"); - printf("\t--list-keywords[=all|csv|<kword>] : list keywords implemented by the engine\n"); -#ifdef __SC_CUDA_SUPPORT__ - printf("\t--list-cuda-cards : list cuda supported cards\n"); -#endif - printf("\t--list-runmodes : list supported runmodes\n"); - printf("\t--runmode <runmode_id> : specific runmode modification the engine should run. The argument\n" - "\t supplied should be the id for the runmode obtained by running\n" - "\t --list-runmodes\n"); - printf("\t--engine-analysis : print reports on analysis of different sections in the engine and exit.\n" - "\t Please have a look at the conf parameter engine-analysis on what reports\n" - "\t can be printed\n"); - printf("\t--pidfile <file> : write pid to this file\n"); - printf("\t--init-errors-fatal : enable fatal failure on signature init error\n"); - printf("\t--disable-detection : disable detection engine\n"); - printf("\t--dump-config : show the running configuration\n"); - printf("\t--build-info : display build information\n"); - printf("\t--pcap[=<dev>] : run in pcap mode, no value select interfaces from suricata.yaml\n"); -#ifdef HAVE_PCAP_SET_BUFF - printf("\t--pcap-buffer-size : size of the pcap buffer value from 0 - %i\n",INT_MAX); -#endif /* HAVE_SET_PCAP_BUFF */ -#ifdef HAVE_AF_PACKET - printf("\t--af-packet[=<dev>] : run in af-packet mode, no value select interfaces from suricata.yaml\n"); -#endif -#ifdef HAVE_NETMAP - printf("\t--netmap[=<dev>] : run in netmap mode, no value select interfaces from suricata.yaml\n"); -#endif -#ifdef HAVE_PFRING - printf("\t--pfring[=<dev>] : run in pfring mode, use interfaces from suricata.yaml\n"); - printf("\t--pfring-int <dev> : run in pfring mode, use interface <dev>\n"); - printf("\t--pfring-cluster-id <id> : pfring cluster id \n"); - printf("\t--pfring-cluster-type <type> : pfring cluster type for PF_RING 4.1.2 and later cluster_round_robin|cluster_flow\n"); -#endif /* HAVE_PFRING */ -#ifdef HAVE_LIBCAP_NG - printf("\t--user <user> : run suricata as this user after init\n"); - printf("\t--group <group> : run suricata as this group after init\n"); -#endif /* HAVE_LIBCAP_NG */ - printf("\t--erf-in <path> : process an ERF file\n"); -#ifdef HAVE_DAG - printf("\t--dag <dagX:Y> : process ERF records from DAG interface X, stream Y\n"); -#endif -#ifdef HAVE_NAPATECH - printf("\t--napatech : run Napatech Streams using the API\n"); -#endif -#ifdef BUILD_UNIX_SOCKET - printf("\t--unix-socket[=<file>] : use unix socket to control suricata work\n"); -#endif -#ifdef HAVE_MPIPE - printf("\t--mpipe : run with tilegx mpipe interface(s)\n"); -#endif - printf("\t--set name=value : set a configuration value\n"); - printf("\n"); - printf("\nTo run the engine with default configuration on " - "interface eth0 with signature file \"signatures.rules\", run the " - "command as:\n\n%s -c suricata.yaml -s signatures.rules -i eth0 \n\n", - progname); -} - -void SCPrintBuildInfo(void) -{ - char *bits = "<unknown>-bits"; - char *endian = "<unknown>-endian"; - char features[2048] = ""; - char *tls = "pthread key"; - -#ifdef REVISION - printf("This is %s version %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION)); -#elif defined RELEASE - printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER); -#else - printf("This is %s version %s\n", PROG_NAME, PROG_VER); -#endif - -#ifdef DEBUG - strlcat(features, "DEBUG ", sizeof(features)); -#endif -#ifdef DEBUG_VALIDATION - strlcat(features, "DEBUG_VALIDATION ", sizeof(features)); -#endif -#ifdef UNITTESTS - strlcat(features, "UNITTESTS ", sizeof(features)); -#endif -#ifdef NFQ - strlcat(features, "NFQ ", sizeof(features)); -#endif -#ifdef IPFW - strlcat(features, "IPFW ", sizeof(features)); -#endif -#ifdef HAVE_PCAP_SET_BUFF - strlcat(features, "PCAP_SET_BUFF ", sizeof(features)); -#endif -#if LIBPCAP_VERSION_MAJOR == 1 - strlcat(features, "LIBPCAP_VERSION_MAJOR=1 ", sizeof(features)); -#elif LIBPCAP_VERSION_MAJOR == 0 - strlcat(features, "LIBPCAP_VERSION_MAJOR=0 ", sizeof(features)); -#endif -#ifdef __SC_CUDA_SUPPORT__ - strlcat(features, "CUDA ", sizeof(features)); -#endif -#ifdef HAVE_PFRING - strlcat(features, "PF_RING ", sizeof(features)); -#endif -#ifdef HAVE_AF_PACKET - strlcat(features, "AF_PACKET ", sizeof(features)); -#endif -#ifdef HAVE_NETMAP - strlcat(features, "NETMAP ", sizeof(features)); -#endif -#ifdef HAVE_PACKET_FANOUT - strlcat(features, "HAVE_PACKET_FANOUT ", sizeof(features)); -#endif -#ifdef HAVE_DAG - strlcat(features, "DAG ", sizeof(features)); -#endif -#ifdef HAVE_LIBCAP_NG - strlcat(features, "LIBCAP_NG ", sizeof(features)); -#endif -#ifdef HAVE_LIBNET11 - strlcat(features, "LIBNET1.1 ", sizeof(features)); -#endif -#ifdef HAVE_HTP_URI_NORMALIZE_HOOK - strlcat(features, "HAVE_HTP_URI_NORMALIZE_HOOK ", sizeof(features)); -#endif -#ifdef PCRE_HAVE_JIT - strlcat(features, "PCRE_JIT ", sizeof(features)); -#endif -#ifdef HAVE_NSS - strlcat(features, "HAVE_NSS ", sizeof(features)); -#endif -#ifdef HAVE_LUA - strlcat(features, "HAVE_LUA ", sizeof(features)); -#endif -#ifdef HAVE_LUAJIT - strlcat(features, "HAVE_LUAJIT ", sizeof(features)); -#endif -#ifdef HAVE_LIBJANSSON - strlcat(features, "HAVE_LIBJANSSON ", sizeof(features)); -#endif -#ifdef PROFILING - strlcat(features, "PROFILING ", sizeof(features)); -#endif -#ifdef PROFILE_LOCKING - strlcat(features, "PROFILE_LOCKING ", sizeof(features)); -#endif -#ifdef TLS - strlcat(features, "TLS ", sizeof(features)); -#endif - if (strlen(features) == 0) { - strlcat(features, "none", sizeof(features)); - } - - printf("Features: %s\n", features); - - /* SIMD stuff */ - memset(features, 0x00, sizeof(features)); -#if defined(__SSE4_2__) - strlcat(features, "SSE_4_2 ", sizeof(features)); -#endif -#if defined(__SSE4_1__) - strlcat(features, "SSE_4_1 ", sizeof(features)); -#endif -#if defined(__SSE3__) - strlcat(features, "SSE_3 ", sizeof(features)); -#endif -#if defined(__tile__) - strlcat(features, "Tilera ", sizeof(features)); -#endif - if (strlen(features) == 0) { - strlcat(features, "none", sizeof(features)); - } - printf("SIMD support: %s\n", features); - - /* atomics stuff */ - memset(features, 0x00, sizeof(features)); -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) - strlcat(features, "1 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) - strlcat(features, "2 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) - strlcat(features, "4 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) - strlcat(features, "8 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) - strlcat(features, "16 ", sizeof(features)); -#endif - if (strlen(features) == 0) { - strlcat(features, "none", sizeof(features)); - } else { - strlcat(features, "byte(s)", sizeof(features)); - } - printf("Atomic intrisics: %s\n", features); - -#if __WORDSIZE == 64 - bits = "64-bits"; -#elif __WORDSIZE == 32 - bits = "32-bits"; -#endif - -#if __BYTE_ORDER == __BIG_ENDIAN - endian = "Big-endian"; -#elif __BYTE_ORDER == __LITTLE_ENDIAN - endian = "Little-endian"; -#endif - - printf("%s, %s architecture\n", bits, endian); -#ifdef __GNUC__ - printf("GCC version %s, C version %"PRIiMAX"\n", __VERSION__, (intmax_t)__STDC_VERSION__); -#else - printf("C version %"PRIiMAX"\n", (intmax_t)__STDC_VERSION__); -#endif - -#if __SSP__ == 1 - printf("compiled with -fstack-protector\n"); -#endif -#if __SSP_ALL__ == 2 - printf("compiled with -fstack-protector-all\n"); -#endif -#ifdef _FORTIFY_SOURCE - printf("compiled with _FORTIFY_SOURCE=%d\n", _FORTIFY_SOURCE); -#endif -#ifdef CLS - printf("L1 cache line size (CLS)=%d\n", CLS); -#endif -#ifdef TLS - tls = "__thread"; -#endif - printf("thread local storage method: %s\n", tls); - - printf("compiled with %s, linked against %s\n", - HTP_VERSION_STRING_FULL, htp_get_version()); - printf("\n"); -#include "build-info.h" -} - -int coverage_unittests; -int g_ut_modules; -int g_ut_covered; - -void RegisterAllModules() -{ - /* commanders */ - TmModuleUnixManagerRegister(); - /* managers */ - TmModuleFlowManagerRegister(); - TmModuleFlowRecyclerRegister(); - /* nfq */ - TmModuleReceiveNFQRegister(); - TmModuleVerdictNFQRegister(); - TmModuleDecodeNFQRegister(); - /* ipfw */ - TmModuleReceiveIPFWRegister(); - TmModuleVerdictIPFWRegister(); - TmModuleDecodeIPFWRegister(); - /* pcap live */ - TmModuleReceivePcapRegister(); - TmModuleDecodePcapRegister(); - /* pcap file */ - TmModuleReceivePcapFileRegister(); - TmModuleDecodePcapFileRegister(); -#ifdef HAVE_MPIPE - /* mpipe */ - TmModuleReceiveMpipeRegister(); - TmModuleDecodeMpipeRegister(); -#endif - /* af-packet */ - TmModuleReceiveAFPRegister(); - TmModuleDecodeAFPRegister(); - /* netmap */ - TmModuleReceiveNetmapRegister(); - TmModuleDecodeNetmapRegister(); - /* pfring */ - TmModuleReceivePfringRegister(); - TmModuleDecodePfringRegister(); - /* dag file */ - TmModuleReceiveErfFileRegister(); - TmModuleDecodeErfFileRegister(); - /* dag live */ - TmModuleReceiveErfDagRegister(); - TmModuleDecodeErfDagRegister(); - /* napatech */ - TmModuleNapatechStreamRegister(); - TmModuleNapatechDecodeRegister(); - - /* stream engine */ - TmModuleStreamTcpRegister(); - /* detection */ - TmModuleDetectRegister(); - /* respond-reject */ - TmModuleRespondRejectRegister(); - - TmModuleLuaLogRegister(); - /* fast log */ - TmModuleAlertFastLogRegister(); - /* debug log */ - TmModuleAlertDebugLogRegister(); - /* prelue log */ - TmModuleAlertPreludeRegister(); - /* syslog log */ - TmModuleAlertSyslogRegister(); - /* unified2 log */ - TmModuleUnified2AlertRegister(); - /* drop log */ - TmModuleLogDropLogRegister(); - TmModuleJsonDropLogRegister(); - /* json log */ - TmModuleOutputJsonRegister(); - /* email logs */ - TmModuleJsonSmtpLogRegister(); - /* http log */ - TmModuleLogHttpLogRegister(); - TmModuleJsonHttpLogRegister(); - /* tls log */ - TmModuleLogTlsLogRegister(); - TmModuleJsonTlsLogRegister(); - TmModuleLogTlsStoreRegister(); - /* ssh */ - TmModuleJsonSshLogRegister(); - /* pcap log */ - TmModulePcapLogRegister(); - /* file log */ - TmModuleLogFileLogRegister(); - TmModuleJsonFileLogRegister(); - TmModuleLogFilestoreRegister(); - /* dns log */ - TmModuleLogDnsLogRegister(); - TmModuleJsonDnsLogRegister(); - /* tcp streaming data */ - TmModuleLogTcpDataLogRegister(); - /* log stats */ - TmModuleLogStatsLogRegister(); - - TmModuleJsonAlertLogRegister(); - /* flow/netflow */ - TmModuleJsonFlowLogRegister(); - TmModuleJsonNetFlowLogRegister(); - /* json stats */ - TmModuleJsonStatsLogRegister(); - - /* Template JSON logger. */ - TmModuleJsonTemplateLogRegister(); - - /* log api */ - TmModulePacketLoggerRegister(); - TmModuleTxLoggerRegister(); - TmModuleFileLoggerRegister(); - TmModuleFiledataLoggerRegister(); - TmModuleStreamingLoggerRegister(); - TmModuleStatsLoggerRegister(); - TmModuleDebugList(); - /* nflog */ - TmModuleReceiveNFLOGRegister(); - TmModuleDecodeNFLOGRegister(); - -} - -TmEcode LoadYamlConfig(char *conf_filename) -{ - SCEnter(); - - if (conf_filename == NULL) - SCReturnInt(TM_ECODE_OK); - - if (ConfYamlLoadFile(conf_filename) != 0) { - /* Error already displayed. */ - SCReturnInt(TM_ECODE_FAILED); - } - - SCReturnInt(TM_ECODE_OK); -} - -static TmEcode ParseInterfacesList(int run_mode, char *pcap_dev) -{ - SCEnter(); - - /* run the selected runmode */ - if (run_mode == RUNMODE_PCAP_DEV) { - if (strlen(pcap_dev) == 0) { - int ret = LiveBuildDeviceList("pcap"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for pcap"); - SCReturnInt(TM_ECODE_FAILED); - } - } -#ifdef HAVE_MPIPE - } else if (run_mode == RUNMODE_TILERA_MPIPE) { - if (strlen(pcap_dev)) { - if (ConfSetFinal("mpipe.single_mpipe_dev", pcap_dev) != 1) { - fprintf(stderr, "ERROR: Failed to set mpipe.single_mpipe_dev\n"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - int ret = LiveBuildDeviceList("mpipe.inputs"); - if (ret == 0) { - fprintf(stderr, "ERROR: No interface found in config for mpipe\n"); - SCReturnInt(TM_ECODE_FAILED); - } - } -#endif - } else if (run_mode == RUNMODE_PFRING) { - /* FIXME add backward compat support */ - /* iface has been set on command line */ - if (strlen(pcap_dev)) { - if (ConfSetFinal("pfring.live-interface", pcap_dev) != 1) { - SCLogError(SC_ERR_INITIALIZATION, "Failed to set pfring.live-interface"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - /* not an error condition if we have a 1.0 config */ - LiveBuildDeviceList("pfring"); - } - } else if (run_mode == RUNMODE_AFP_DEV) { - /* iface has been set on command line */ - if (strlen(pcap_dev)) { - if (ConfSetFinal("af-packet.live-interface", pcap_dev) != 1) { - SCLogError(SC_ERR_INITIALIZATION, "Failed to set af-packet.live-interface"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - int ret = LiveBuildDeviceList("af-packet"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for af-packet"); - SCReturnInt(TM_ECODE_FAILED); - } - if (AFPRunModeIsIPS()) { - SCLogInfo("AF_PACKET: Setting IPS mode"); - EngineModeSetIPS(); - } - } -#ifdef HAVE_NETMAP - } else if (run_mode == RUNMODE_NETMAP) { - /* iface has been set on command line */ - if (strlen(pcap_dev)) { - if (ConfSetFinal("netmap.live-interface", pcap_dev) != 1) { - SCLogError(SC_ERR_INITIALIZATION, "Failed to set netmap.live-interface"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - int ret = LiveBuildDeviceList("netmap"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for netmap"); - SCReturnInt(TM_ECODE_FAILED); - } - if (NetmapRunModeIsIPS()) { - SCLogInfo("Netmap: Setting IPS mode"); - EngineModeSetIPS(); - } - } -#endif -#ifdef HAVE_NFLOG - } else if (run_mode == RUNMODE_NFLOG) { - int ret = LiveBuildDeviceListCustom("nflog", "group"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No group found in config for nflog"); - SCReturnInt(TM_ECODE_FAILED); - } -#endif - } - - SCReturnInt(TM_ECODE_OK); -} - -static void SCInstanceInit(SCInstance *suri) -{ - suri->run_mode = RUNMODE_UNKNOWN; - - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - suri->sig_file = NULL; - suri->sig_file_exclusive = FALSE; - suri->pid_filename = NULL; - suri->regex_arg = NULL; - - suri->keyword_info = NULL; - suri->runmode_custom_mode = NULL; -#ifndef OS_WIN32 - suri->user_name = NULL; - suri->group_name = NULL; - suri->do_setuid = FALSE; - suri->do_setgid = FALSE; - suri->userid = 0; - suri->groupid = 0; -#endif /* OS_WIN32 */ - suri->delayed_detect = 0; - suri->daemon = 0; - suri->offline = 0; - suri->verbose = 0; - /* use -1 as unknown */ - suri->checksum_validation = -1; -#if HAVE_DETECT_DISABLED==1 - g_detect_disabled = suri->disabled_detect = 1; -#else - g_detect_disabled = suri->disabled_detect = 0; -#endif -} - -static TmEcode PrintVersion() -{ -#ifdef REVISION - printf("This is %s version %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION)); -#elif defined RELEASE - printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER); -#else - printf("This is %s version %s\n", PROG_NAME, PROG_VER); -#endif - return TM_ECODE_OK; -} - -static TmEcode SCPrintVersion() -{ -#ifdef REVISION - SCLogNotice("This is %s version %s (rev %s)", PROG_NAME, PROG_VER, xstr(REVISION)); -#elif defined RELEASE - SCLogNotice("This is %s version %s RELEASE", PROG_NAME, PROG_VER); -#else - SCLogNotice("This is %s version %s", PROG_NAME, PROG_VER); -#endif - return TM_ECODE_OK; -} - -static void SCSetStartTime(SCInstance *suri) -{ - memset(&suri->start_time, 0, sizeof(suri->start_time)); - gettimeofday(&suri->start_time, NULL); -} - -static void SCPrintElapsedTime(SCInstance *suri) -{ - struct timeval end_time; - memset(&end_time, 0, sizeof(end_time)); - gettimeofday(&end_time, NULL); - uint64_t milliseconds = ((end_time.tv_sec - suri->start_time.tv_sec) * 1000) + - (((1000000 + end_time.tv_usec - suri->start_time.tv_usec) / 1000) - 1000); - SCLogInfo("time elapsed %.3fs", (float)milliseconds/(float)1000); -} - -static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) -{ - int opt; - - int dump_config = 0; - int list_app_layer_protocols = 0; - int list_unittests = 0; - int list_cuda_cards = 0; - int list_runmodes = 0; - int list_keywords = 0; - int build_info = 0; - int conf_test = 0; - int engine_analysis = 0; - int ret = TM_ECODE_OK; - -#ifdef UNITTESTS - coverage_unittests = 0; - g_ut_modules = 0; - g_ut_covered = 0; -#endif - - struct option long_opts[] = { - {"dump-config", 0, &dump_config, 1}, - {"pfring", optional_argument, 0, 0}, - {"pfring-int", required_argument, 0, 0}, - {"pfring-cluster-id", required_argument, 0, 0}, - {"pfring-cluster-type", required_argument, 0, 0}, - {"af-packet", optional_argument, 0, 0}, - {"netmap", optional_argument, 0, 0}, - {"pcap", optional_argument, 0, 0}, -#ifdef BUILD_UNIX_SOCKET - {"unix-socket", optional_argument, 0, 0}, -#endif - {"pcap-buffer-size", required_argument, 0, 0}, - {"unittest-filter", required_argument, 0, 'U'}, - {"list-app-layer-protos", 0, &list_app_layer_protocols, 1}, - {"list-unittests", 0, &list_unittests, 1}, - {"list-cuda-cards", 0, &list_cuda_cards, 1}, - {"list-runmodes", 0, &list_runmodes, 1}, - {"list-keywords", optional_argument, &list_keywords, 1}, - {"runmode", required_argument, NULL, 0}, - {"engine-analysis", 0, &engine_analysis, 1}, -#ifdef OS_WIN32 - {"service-install", 0, 0, 0}, - {"service-remove", 0, 0, 0}, - {"service-change-params", 0, 0, 0}, -#endif /* OS_WIN32 */ - {"pidfile", required_argument, 0, 0}, - {"init-errors-fatal", 0, 0, 0}, - {"disable-detection", 0, 0, 0}, - {"fatal-unittests", 0, 0, 0}, - {"unittests-coverage", 0, &coverage_unittests, 1}, - {"user", required_argument, 0, 0}, - {"group", required_argument, 0, 0}, - {"erf-in", required_argument, 0, 0}, - {"dag", required_argument, 0, 0}, - {"napatech", 0, 0, 0}, - {"build-info", 0, &build_info, 1}, -#ifdef HAVE_MPIPE - {"mpipe", optional_argument, 0, 0}, -#endif - {"set", required_argument, 0, 0}, -#ifdef HAVE_NFLOG - {"nflog", optional_argument, 0, 0}, -#endif - {NULL, 0, NULL, 0} - }; - - /* getopt_long stores the option index here. */ - int option_index = 0; - - char short_opts[] = "c:TDhi:l:q:d:r:us:S:U:VF:vk:"; - - while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) { - switch (opt) { - case 0: - if (strcmp((long_opts[option_index]).name , "pfring") == 0 || - strcmp((long_opts[option_index]).name , "pfring-int") == 0) { -#ifdef HAVE_PFRING - suri->run_mode = RUNMODE_PFRING; - if (optarg != NULL) { - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - LiveRegisterDevice(optarg); - } -#else - SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if(strcmp((long_opts[option_index]).name , "pfring-cluster-id") == 0){ -#ifdef HAVE_PFRING - if (ConfSetFinal("pfring.cluster-id", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pfring.cluster-id.\n"); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if(strcmp((long_opts[option_index]).name , "pfring-cluster-type") == 0){ -#ifdef HAVE_PFRING - if (ConfSetFinal("pfring.cluster-type", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pfring.cluster-type.\n"); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if (strcmp((long_opts[option_index]).name , "af-packet") == 0){ -#ifdef HAVE_AF_PACKET - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_AFP_DEV; - if (optarg) { - LiveRegisterDevice(optarg); - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - } - } else if (suri->run_mode == RUNMODE_AFP_DEV) { - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple devices to get packets is experimental."); - if (optarg) { - LiveRegisterDevice(optarg); - } else { - SCLogInfo("Multiple af-packet option without interface on each is useless"); - break; - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_AF_PACKET,"AF_PACKET not enabled. On Linux " - "host, make sure to pass --enable-af-packet to " - "configure when building."); - return TM_ECODE_FAILED; -#endif - } else if (strcmp((long_opts[option_index]).name , "netmap") == 0){ -#ifdef HAVE_NETMAP - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_NETMAP; - if (optarg) { - LiveRegisterDevice(optarg); - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - } - } else if (suri->run_mode == RUNMODE_NETMAP) { - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple devices to get packets is experimental."); - if (optarg) { - LiveRegisterDevice(optarg); - } else { - SCLogInfo("Multiple netmap option without interface on each is useless"); - break; - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_NETMAP, "NETMAP not enabled."); - return TM_ECODE_FAILED; -#endif - } else if (strcmp((long_opts[option_index]).name, "nflog") == 0) { -#ifdef HAVE_NFLOG - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_NFLOG; - LiveBuildDeviceListCustom("nflog", "group"); - } -#else - SCLogError(SC_ERR_NFLOG_NOSUPPORT, "NFLOG not enabled."); - return TM_ECODE_FAILED; -#endif /* HAVE_NFLOG */ - } else if (strcmp((long_opts[option_index]).name , "pcap") == 0) { - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_PCAP_DEV; - if (optarg) { - LiveRegisterDevice(optarg); - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - } - } else if (suri->run_mode == RUNMODE_PCAP_DEV) { -#ifdef OS_WIN32 - SCLogError(SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT, "pcap multi dev " - "support is not (yet) supported on Windows."); - return TM_ECODE_FAILED; -#else - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple pcap devices to get packets is experimental."); - LiveRegisterDevice(optarg); -#endif - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - } else if(strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) { - if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) { - fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n"); - return TM_ECODE_FAILED; - } -#ifdef BUILD_UNIX_SOCKET - } else if (strcmp((long_opts[option_index]).name , "unix-socket") == 0) { - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_UNIX_SOCKET; - if (optarg) { - if (ConfSetFinal("unix-command.filename", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set unix-command.filename.\n"); - return TM_ECODE_FAILED; - } - - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#endif - } - else if(strcmp((long_opts[option_index]).name, "list-app-layer-protocols") == 0) { - /* listing all supported app layer protocols */ - } - else if(strcmp((long_opts[option_index]).name, "list-unittests") == 0) { -#ifdef UNITTESTS - suri->run_mode = RUNMODE_LIST_UNITTEST; -#else - fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - } else if(strcmp((long_opts[option_index]).name, "list-cuda-cards") == 0) { -#ifndef __SC_CUDA_SUPPORT__ - fprintf(stderr, "ERROR: Cuda not enabled. Make sure to pass " - "--enable-cuda to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - } else if (strcmp((long_opts[option_index]).name, "list-runmodes") == 0) { - suri->run_mode = RUNMODE_LIST_RUNMODES; - return TM_ECODE_OK; - } else if (strcmp((long_opts[option_index]).name, "list-keywords") == 0) { - if (optarg) { - if (strcmp("short",optarg)) { - suri->keyword_info = optarg; - } - } - } else if (strcmp((long_opts[option_index]).name, "runmode") == 0) { - suri->runmode_custom_mode = optarg; - } else if(strcmp((long_opts[option_index]).name, "engine-analysis") == 0) { - // do nothing for now - } -#ifdef OS_WIN32 - else if(strcmp((long_opts[option_index]).name, "service-install") == 0) { - suri->run_mode = RUNMODE_INSTALL_SERVICE; - return TM_ECODE_OK; - } - else if(strcmp((long_opts[option_index]).name, "service-remove") == 0) { - suri->run_mode = RUNMODE_REMOVE_SERVICE; - return TM_ECODE_OK; - } - else if(strcmp((long_opts[option_index]).name, "service-change-params") == 0) { - suri->run_mode = RUNMODE_CHANGE_SERVICE_PARAMS; - return TM_ECODE_OK; - } -#endif /* OS_WIN32 */ - else if(strcmp((long_opts[option_index]).name, "pidfile") == 0) { - suri->pid_filename = optarg; - } - else if(strcmp((long_opts[option_index]).name, "disable-detection") == 0) { - g_detect_disabled = suri->disabled_detect = 1; - SCLogInfo("detection engine disabled"); - } - else if(strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) { -#ifdef UNITTESTS - if (ConfSetFinal("unittests.failure-fatal", "1") != 1) { - fprintf(stderr, "ERROR: Failed to set unittests failure-fatal.\n"); - return TM_ECODE_FAILED; - } -#else - fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - } - else if(strcmp((long_opts[option_index]).name, "user") == 0) { -#ifndef HAVE_LIBCAP_NG - SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to" - " drop privileges, but it was not compiled into Suricata."); - return TM_ECODE_FAILED; -#else - suri->user_name = optarg; - suri->do_setuid = TRUE; -#endif /* HAVE_LIBCAP_NG */ - } - else if(strcmp((long_opts[option_index]).name, "group") == 0) { -#ifndef HAVE_LIBCAP_NG - SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to" - " drop privileges, but it was not compiled into Suricata."); - return TM_ECODE_FAILED; -#else - suri->group_name = optarg; - suri->do_setgid = TRUE; -#endif /* HAVE_LIBCAP_NG */ - } - else if (strcmp((long_opts[option_index]).name, "erf-in") == 0) { - suri->run_mode = RUNMODE_ERF_FILE; - if (ConfSetFinal("erf-file.file", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set erf-file.file\n"); - return TM_ECODE_FAILED; - } - } - else if (strcmp((long_opts[option_index]).name, "dag") == 0) { -#ifdef HAVE_DAG - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_DAG; - } - else if (suri->run_mode != RUNMODE_DAG) { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, - "more than one run mode has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - LiveRegisterDevice(optarg); -#else - SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required" - " to receieve packets using --dag."); - return TM_ECODE_FAILED; -#endif /* HAVE_DAG */ - } - else if (strcmp((long_opts[option_index]).name, "napatech") == 0) { -#ifdef HAVE_NAPATECH - suri->run_mode = RUNMODE_NAPATECH; -#else - SCLogError(SC_ERR_NAPATECH_REQUIRED, "libntapi and a Napatech adapter are required" - " to capture packets using --napatech."); - return TM_ECODE_FAILED; -#endif /* HAVE_NAPATECH */ - } - else if(strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) { -#ifdef HAVE_PCAP_SET_BUFF - if (ConfSetFinal("pcap.buffer-size", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pcap-buffer-size.\n"); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_PCAP_SET_BUFFER_SIZE, "The version of libpcap you have" - " doesn't support setting buffer size."); -#endif /* HAVE_PCAP_SET_BUFF */ - } - else if(strcmp((long_opts[option_index]).name, "build-info") == 0) { - suri->run_mode = RUNMODE_PRINT_BUILDINFO; - return TM_ECODE_OK; - } -#ifdef HAVE_MPIPE - else if(strcmp((long_opts[option_index]).name , "mpipe") == 0) { - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_TILERA_MPIPE; - if (optarg != NULL) { - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - LiveRegisterDevice(optarg); - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, - "more than one run mode has been specified"); - usage(argv[0]); - exit(EXIT_FAILURE); - } - } -#endif - else if (strcmp((long_opts[option_index]).name, "set") == 0) { - if (optarg != NULL) { - /* Quick validation. */ - char *val = strchr(optarg, '='); - if (val == NULL) { - SCLogError(SC_ERR_CMD_LINE, - "Invalid argument for --set, must be key=val."); - exit(EXIT_FAILURE); - } - if (!ConfSetFromString(optarg, 1)) { - fprintf(stderr, "Failed to set configuration value %s.", - optarg); - exit(EXIT_FAILURE); - } - } - } - break; - case 'c': - conf_filename = optarg; - break; - case 'T': - SCLogInfo("Running suricata under test mode"); - conf_test = 1; - if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) { - fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n"); - return TM_ECODE_FAILED; - } - break; -#ifndef OS_WIN32 - case 'D': - suri->daemon = 1; - break; -#endif /* OS_WIN32 */ - case 'h': - suri->run_mode = RUNMODE_PRINT_USAGE; - return TM_ECODE_OK; - case 'i': - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -i"); - return TM_ECODE_FAILED; - } - - /* some windows shells require escaping of the \ in \Device. Otherwise - * the backslashes are stripped. We put them back here. */ - if (strlen(optarg) > 9 && strncmp(optarg, "DeviceNPF", 9) == 0) { - snprintf(suri->pcap_dev, sizeof(suri->pcap_dev), "\\Device\\NPF%s", optarg+9); - } else { - strlcpy(suri->pcap_dev, optarg, ((strlen(optarg) < sizeof(suri->pcap_dev)) ? (strlen(optarg)+1) : (sizeof(suri->pcap_dev)))); - PcapTranslateIPToDevice(suri->pcap_dev, sizeof(suri->pcap_dev)); - } - - if (strcmp(suri->pcap_dev, optarg) != 0) { - SCLogInfo("translated %s to pcap device %s", optarg, suri->pcap_dev); - } else if (strlen(suri->pcap_dev) > 0 && isdigit((unsigned char)suri->pcap_dev[0])) { - SCLogError(SC_ERR_PCAP_TRANSLATE, "failed to find a pcap device for IP %s", optarg); - return TM_ECODE_FAILED; - } - - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_PCAP_DEV; - LiveRegisterDevice(suri->pcap_dev); - } else if (suri->run_mode == RUNMODE_PCAP_DEV) { -#ifdef OS_WIN32 - SCLogError(SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT, "pcap multi dev " - "support is not (yet) supported on Windows."); - return TM_ECODE_FAILED; -#else - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple pcap devices to get packets is experimental."); - LiveRegisterDevice(suri->pcap_dev); -#endif - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - break; - case 'l': - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -l"); - return TM_ECODE_FAILED; - } - - if (ConfigSetLogDirectory(optarg) != TM_ECODE_OK) { - SCLogError(SC_ERR_FATAL, "Failed to set log directory.\n"); - return TM_ECODE_FAILED; - } - if (ConfigCheckLogDirectory(optarg) != TM_ECODE_OK) { - SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\"" - " supplied at the commandline (-l %s) doesn't " - "exist. Shutting down the engine.", optarg, optarg); - return TM_ECODE_FAILED; - } - break; - case 'q': -#ifdef NFQ - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_NFQ; - EngineModeSetIPS(); - if (NFQRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else if (suri->run_mode == RUNMODE_NFQ) { - if (NFQRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NFQ_NOSUPPORT,"NFQUEUE not enabled. Make sure to pass --enable-nfqueue to configure when building."); - return TM_ECODE_FAILED; -#endif /* NFQ */ - break; - case 'd': -#ifdef IPFW - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_IPFW; - EngineModeSetIPS(); - if (IPFWRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else if (suri->run_mode == RUNMODE_IPFW) { - if (IPFWRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_IPFW_NOSUPPORT,"IPFW not enabled. Make sure to pass --enable-ipfw to configure when building."); - return TM_ECODE_FAILED; -#endif /* IPFW */ - break; - case 'r': - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_PCAP_FILE; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - if (ConfSetFinal("pcap-file.file", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pcap-file.file\n"); - return TM_ECODE_FAILED; - } - break; - case 's': - if (suri->sig_file != NULL) { - SCLogError(SC_ERR_CMD_LINE, "can't have multiple -s options or mix -s and -S."); - return TM_ECODE_FAILED; - } - suri->sig_file = optarg; - break; - case 'S': - if (suri->sig_file != NULL) { - SCLogError(SC_ERR_CMD_LINE, "can't have multiple -S options or mix -s and -S."); - return TM_ECODE_FAILED; - } - suri->sig_file = optarg; - suri->sig_file_exclusive = TRUE; - break; - case 'u': -#ifdef UNITTESTS - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_UNITTEST; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode has" - " been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - break; - case 'U': -#ifdef UNITTESTS - suri->regex_arg = optarg; - - if(strlen(suri->regex_arg) == 0) - suri->regex_arg = NULL; -#endif - break; - case 'V': - suri->run_mode = RUNMODE_PRINT_VERSION; - return TM_ECODE_OK; - case 'F': - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -F"); - return TM_ECODE_FAILED; - } - - SetBpfStringFromFile(optarg); - break; - case 'v': - suri->verbose++; - break; - case 'k': - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -k"); - return TM_ECODE_FAILED; - } - if (!strcmp("all", optarg)) - suri->checksum_validation = 1; - else if (!strcmp("none", optarg)) - suri->checksum_validation = 0; - else { - SCLogError(SC_ERR_INITIALIZATION, "option '%s' invalid for -k", optarg); - return TM_ECODE_FAILED; - } - break; - default: - usage(argv[0]); - return TM_ECODE_FAILED; - } - } - - if (suri->disabled_detect && suri->sig_file != NULL) { - SCLogError(SC_ERR_INITIALIZATION, "can't use -s/-S when detection is disabled"); - return TM_ECODE_FAILED; - } - - if (list_app_layer_protocols) - suri->run_mode = RUNMODE_LIST_APP_LAYERS; - if (list_cuda_cards) - suri->run_mode = RUNMODE_LIST_CUDA_CARDS; - if (list_keywords) - suri->run_mode = RUNMODE_LIST_KEYWORDS; - if (list_unittests) - suri->run_mode = RUNMODE_LIST_UNITTEST; - if (dump_config) - suri->run_mode = RUNMODE_DUMP_CONFIG; - if (conf_test) - suri->run_mode = RUNMODE_CONF_TEST; - if (engine_analysis) - suri->run_mode = RUNMODE_ENGINE_ANALYSIS; - - ret = SetBpfString(optind, argv); - if (ret != TM_ECODE_OK) - return ret; - - return TM_ECODE_OK; -} - -#ifdef OS_WIN32 -static int WindowsInitService(int argc, char **argv) -{ - if (SCRunningAsService()) { - char path[MAX_PATH]; - char *p = NULL; - strlcpy(path, argv[0], MAX_PATH); - if ((p = strrchr(path, '\\'))) { - *p = '\0'; - } - if (!SetCurrentDirectory(path)) { - SCLogError(SC_ERR_FATAL, "Can't set current directory to: %s", path); - return -1; - } - SCLogInfo("Current directory is set to: %s", path); - daemon = 1; - SCServiceInit(argc, argv); - } - - /* Windows socket subsystem initialization */ - WSADATA wsaData; - if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { - SCLogError(SC_ERR_FATAL, "Can't initialize Windows sockets: %d", WSAGetLastError()); - return -1; - } - - return 0; -} -#endif /* OS_WIN32 */ - -static int MayDaemonize(SCInstance *suri) -{ - if (suri->daemon == 1 && suri->pid_filename == NULL) { - if (ConfGet("pid-file", &suri->pid_filename) == 1) { - SCLogInfo("Use pid file %s from config file.", suri->pid_filename); - } else { - suri->pid_filename = DEFAULT_PID_FILENAME; - } - } - - if (suri->pid_filename != NULL && SCPidfileTestRunning(suri->pid_filename) != 0) { - suri->pid_filename = NULL; - return TM_ECODE_FAILED; - } - - if (suri->daemon == 1) { - Daemonize(); - } - - if (suri->pid_filename != NULL) { - if (SCPidfileCreate(suri->pid_filename) != 0) { - suri->pid_filename = NULL; - SCLogError(SC_ERR_PIDFILE_DAEMON, - "Unable to create PID file, concurrent run of" - " Suricata can occur."); - SCLogError(SC_ERR_PIDFILE_DAEMON, - "PID file creation WILL be mandatory for daemon mode" - " in future version"); - } - } - - return TM_ECODE_OK; -} - -static int InitSignalHandler(SCInstance *suri) -{ - /* registering signals we use */ - UtilSignalHandlerSetup(SIGINT, SignalHandlerSigint); - UtilSignalHandlerSetup(SIGTERM, SignalHandlerSigterm); - UtilSignalHandlerSetup(SIGPIPE, SIG_IGN); - UtilSignalHandlerSetup(SIGSYS, SIG_IGN); - -#ifndef OS_WIN32 - /* SIGHUP is not implemented on WIN32 */ - UtilSignalHandlerSetup(SIGHUP, SignalHandlerSigHup); - - /* Try to get user/group to run suricata as if - command line as not decide of that */ - if (suri->do_setuid == FALSE && suri->do_setgid == FALSE) { - char *id; - if (ConfGet("run-as.user", &id) == 1) { - suri->do_setuid = TRUE; - suri->user_name = id; - } - if (ConfGet("run-as.group", &id) == 1) { - suri->do_setgid = TRUE; - suri->group_name = id; - } - } - /* Get the suricata user ID to given user ID */ - if (suri->do_setuid == TRUE) { - if (SCGetUserID(suri->user_name, suri->group_name, - &suri->userid, &suri->groupid) != 0) { - SCLogError(SC_ERR_UID_FAILED, "failed in getting user ID"); - return TM_ECODE_FAILED; - } - - sc_set_caps = TRUE; - /* Get the suricata group ID to given group ID */ - } else if (suri->do_setgid == TRUE) { - if (SCGetGroupID(suri->group_name, &suri->groupid) != 0) { - SCLogError(SC_ERR_GID_FAILED, "failed in getting group ID"); - return TM_ECODE_FAILED; - } - - sc_set_caps = TRUE; - } -#endif /* OS_WIN32 */ - - return TM_ECODE_OK; -} - -int StartInternalRunMode(SCInstance *suri, int argc, char **argv) -{ - /* Treat internal running mode */ - switch(suri->run_mode) { - case RUNMODE_LIST_KEYWORDS: - ListKeywords(suri->keyword_info); - return TM_ECODE_DONE; - case RUNMODE_LIST_APP_LAYERS: - ListAppLayerProtocols(); - return TM_ECODE_DONE; - case RUNMODE_PRINT_VERSION: - PrintVersion(); - return TM_ECODE_DONE; - case RUNMODE_PRINT_BUILDINFO: - SCPrintBuildInfo(); - return TM_ECODE_DONE; - case RUNMODE_PRINT_USAGE: - usage(argv[0]); - return TM_ECODE_DONE; -#ifdef __SC_CUDA_SUPPORT__ - case RUNMODE_LIST_CUDA_CARDS: - return ListCudaCards(); -#endif - case RUNMODE_LIST_RUNMODES: - RunModeListRunmodes(); - return TM_ECODE_DONE; - case RUNMODE_LIST_UNITTEST: - RunUnittests(1, suri->regex_arg); -#ifdef OS_WIN32 - case RUNMODE_INSTALL_SERVICE: - if (SCServiceInstall(argc, argv)) { - return TM_ECODE_FAILED; - } - SCLogInfo("Suricata service has been successfuly installed."); - return TM_ECODE_DONE; - case RUNMODE_REMOVE_SERVICE: - if (SCServiceRemove(argc, argv)) { - return TM_ECODE_FAILED; - } - SCLogInfo("Suricata service has been successfuly removed."); - return TM_ECODE_DONE; - case RUNMODE_CHANGE_SERVICE_PARAMS: - if (SCServiceChangeParams(argc, argv)) { - return TM_ECODE_FAILED; - } - SCLogInfo("Suricata service startup parameters has been successfuly changed."); - return TM_ECODE_DONE; -#endif /* OS_WIN32 */ - default: - /* simply continue for other running mode */ - break; - } - return TM_ECODE_OK; -} - -static int FinalizeRunMode(SCInstance *suri, char **argv) -{ - switch (suri->run_mode) { - case RUNMODE_PCAP_FILE: - case RUNMODE_ERF_FILE: - case RUNMODE_ENGINE_ANALYSIS: - suri->offline = 1; - break; - case RUNMODE_UNKNOWN: - usage(argv[0]); - return TM_ECODE_FAILED; - } - /* Set the global run mode */ - run_mode = suri->run_mode; - - - return TM_ECODE_OK; -} - -static void SetupDelayedDetect(SCInstance *suri) -{ - /* In offline mode delayed init of detect is a bad idea */ - if (suri->offline) { - suri->delayed_detect = 0; - } else { - ConfNode *denode = NULL; - ConfNode *decnf = ConfGetNode("detect-engine"); - if (decnf != NULL) { - TAILQ_FOREACH(denode, &decnf->head, next) { - if (strcmp(denode->val, "delayed-detect") == 0) { - (void)ConfGetChildValueBool(denode, "delayed-detect", &suri->delayed_detect); - } - } - } - } - - SCLogInfo("Delayed detect %s", suri->delayed_detect ? "enabled" : "disabled"); - if (suri->delayed_detect) { - SCLogInfo("Packets will start being processed before signatures are active."); - } - -} - -static int LoadSignatures(DetectEngineCtx *de_ctx, SCInstance *suri) -{ - if (SigLoadSignatures(de_ctx, suri->sig_file, suri->sig_file_exclusive) < 0) { - SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed."); - if (de_ctx->failure_fatal) - return TM_ECODE_FAILED; - } - - SCThresholdConfInitContext(de_ctx, NULL); - return TM_ECODE_OK; -} - -static int ConfigGetCaptureValue(SCInstance *suri) -{ - /* Pull the max pending packets from the config, if not found fall - * back on a sane default. */ - if (ConfGetInt("max-pending-packets", &max_pending_packets) != 1) - max_pending_packets = DEFAULT_MAX_PENDING_PACKETS; - if (max_pending_packets >= 65535) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "Maximum max-pending-packets setting is 65534. " - "Please check %s for errors", conf_filename); - return TM_ECODE_FAILED; - } - - SCLogDebug("Max pending packets set to %"PRIiMAX, max_pending_packets); - - /* Pull the default packet size from the config, if not found fall - * back on a sane default. */ - char *temp_default_packet_size; - if ((ConfGet("default-packet-size", &temp_default_packet_size)) != 1) { - int lthread; - int nlive; - switch (suri->run_mode) { - case RUNMODE_PCAP_DEV: - case RUNMODE_AFP_DEV: - case RUNMODE_NETMAP: - case RUNMODE_PFRING: - nlive = LiveGetDeviceCount(); - for (lthread = 0; lthread < nlive; lthread++) { - char *live_dev = LiveGetDeviceName(lthread); - unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(live_dev); - if (iface_max_packet_size > default_packet_size) - default_packet_size = iface_max_packet_size; - } - if (default_packet_size) - break; - /* fall through */ - default: - default_packet_size = DEFAULT_PACKET_SIZE; - } - } else { - if (ParseSizeStringU32(temp_default_packet_size, &default_packet_size) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing max-pending-packets " - "from conf file - %s. Killing engine", - temp_default_packet_size); - return TM_ECODE_FAILED; - } - } - - SCLogDebug("Default packet size set to %"PRIu32, default_packet_size); - - return TM_ECODE_OK; -} -/** - * This function is meant to contain code that needs - * to be run once the configuration has been loaded. - */ -static int PostConfLoadedSetup(SCInstance *suri) -{ - char *hostmode = NULL; - - /* load the pattern matchers */ - MpmTableSetup(); -#ifdef __SC_CUDA_SUPPORT__ - MpmCudaEnvironmentSetup(); -#endif - - switch (suri->checksum_validation) { - case 0: - ConfSet("stream.checksum-validation", "0"); - break; - case 1: - ConfSet("stream.checksum-validation", "1"); - break; - } - - AppLayerSetup(); - - /* Check for the existance of the default logging directory which we pick - * from suricata.yaml. If not found, shut the engine down */ - suri->log_dir = ConfigGetLogDirectory(); - - if (ConfigCheckLogDirectory(suri->log_dir) != TM_ECODE_OK) { - SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" " - "supplied by %s (default-log-dir) doesn't exist. " - "Shutting down the engine", suri->log_dir, conf_filename); - SCReturnInt(TM_ECODE_FAILED); - } - - if (ConfigGetCaptureValue(suri) != TM_ECODE_OK) { - SCReturnInt(TM_ECODE_FAILED); - } - - if (ConfGet("host-mode", &hostmode) == 1) { - if (!strcmp(hostmode, "router")) { - host_mode = SURI_HOST_IS_ROUTER; - } else if (!strcmp(hostmode, "sniffer-only")) { - host_mode = SURI_HOST_IS_SNIFFER_ONLY; - } else { - if (strcmp(hostmode, "auto") != 0) { - WarnInvalidConfEntry("host-mode", "%s", "auto"); - } - if (EngineModeIsIPS()) { - host_mode = SURI_HOST_IS_ROUTER; - } else { - host_mode = SURI_HOST_IS_SNIFFER_ONLY; - } - } - } else { - if (EngineModeIsIPS()) { - host_mode = SURI_HOST_IS_ROUTER; - SCLogInfo("No 'host-mode': suricata is in IPS mode, using " - "default setting 'router'"); - } else { - host_mode = SURI_HOST_IS_SNIFFER_ONLY; - SCLogInfo("No 'host-mode': suricata is in IDS mode, using " - "default setting 'sniffer-only'"); - } - } - -#ifdef NFQ - if (suri->run_mode == RUNMODE_NFQ) - NFQInitConfig(FALSE); -#endif - - /* Load the Host-OS lookup. */ - SCHInfoLoadFromConfig(); - if (suri->run_mode != RUNMODE_UNIX_SOCKET) { - DefragInit(); - } - - if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) { - SCLogInfo("== Carrying out Engine Analysis =="); - char *temp = NULL; - if (ConfGet("engine-analysis", &temp) == 0) { - SCLogInfo("no engine-analysis parameter(s) defined in conf file. " - "Please define/enable them in the conf to use this " - "feature."); - SCReturnInt(TM_ECODE_FAILED); - } - } - - /* hardcoded initialization code */ - SigTableSetup(); /* load the rule keywords */ - TmqhSetup(); - - StorageInit(); - CIDRInit(); - SigParsePrepare(); -#ifdef PROFILING - if (suri->run_mode != RUNMODE_UNIX_SOCKET) { - SCProfilingRulesGlobalInit(); - SCProfilingKeywordsGlobalInit(); - SCProfilingInit(); - } -#endif /* PROFILING */ - SCReputationInitCtx(); - SCProtoNameInit(); - - TagInitCtx(); - ThresholdInit(); - HostBitInitCtx(); - IPPairBitInitCtx(); - - if (DetectAddressTestConfVars() < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "basic address vars test failed. Please check %s for errors", conf_filename); - SCReturnInt(TM_ECODE_FAILED); - } - if (DetectPortTestConfVars() < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "basic port vars test failed. Please check %s for errors", conf_filename); - SCReturnInt(TM_ECODE_FAILED); - } - - RegisterAllModules(); - - AppLayerHtpNeedFileInspection(); - - DetectEngineRegisterAppInspectionEngines(); - - if (suri->sig_file != NULL) - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2SigFileStartup); - else - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2StartingUp); - - StorageFinalize(); - - TmModuleRunInit(); - - PcapLogProfileSetup(); - SCReturnInt(TM_ECODE_OK); -} - -int main(int argc, char **argv) -{ - SCInstance suri; - - SCInstanceInit(&suri); - - sc_set_caps = FALSE; - - SC_ATOMIC_INIT(engine_stage); - - /* initialize the logging subsys */ - SCLogInitLogModule(NULL); - - if (SCSetThreadName("Suricata-Main") < 0) { - SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name"); - } - - ParseSizeInit(); - - RunModeRegisterRunModes(); - - /* By default use IDS mode, but if nfq or ipfw - * are specified, IPS mode will overwrite this */ - EngineModeSetIDS(); - - -#ifdef OS_WIN32 - /* service initialization */ - if (WindowsInit(argc, argv) != 0) { - exit(EXIT_FAILURE); - } -#endif /* OS_WIN32 */ - - /* Initialize the configuration module. */ - ConfInit(); - - if (ParseCommandLine(argc, argv, &suri) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - switch (StartInternalRunMode(&suri, argc, argv)) { - case TM_ECODE_DONE: - exit(EXIT_SUCCESS); - case TM_ECODE_FAILED: - exit(EXIT_FAILURE); - } - - if (FinalizeRunMode(&suri, argv) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (suri.run_mode == RUNMODE_UNITTEST) - RunUnittests(0, suri.regex_arg); - -#ifdef __SC_CUDA_SUPPORT__ - /* Init the CUDA environment */ - SCCudaInitCudaEnvironment(); - CudaBufferInit(); -#endif - - if (!CheckValidDaemonModes(suri.daemon, suri.run_mode)) { - exit(EXIT_FAILURE); - } - - /* Initializations for global vars, queues, etc (memsets, mutex init..) */ - GlobalInits(); - TimeInit(); - SupportFastPatternForSigMatchTypes(); - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - StatsInit(); - } - - if (conf_filename == NULL) - conf_filename = DEFAULT_CONF_FILE; - - /** \todo we need an api for these */ - /* Load yaml configuration file if provided. */ - if (LoadYamlConfig(conf_filename) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (suri.run_mode == RUNMODE_DUMP_CONFIG) { - ConfDump(); - exit(EXIT_SUCCESS); - } - - /* Since our config is now loaded we can finish configurating the - * logging module. */ - SCLogLoadConfig(suri.daemon, suri.verbose); - - SCPrintVersion(); - - UtilCpuPrintSummary(); - - if (ParseInterfacesList(suri.run_mode, suri.pcap_dev) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (PostConfLoadedSetup(&suri) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (MayDaemonize(&suri) != TM_ECODE_OK) - exit(EXIT_FAILURE); - - if (InitSignalHandler(&suri) != TM_ECODE_OK) - exit(EXIT_FAILURE); - -#ifdef HAVE_NSS - /* init NSS for md5 */ - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - NSS_NoDB_Init(NULL); -#endif - - if (suri.disabled_detect) { - /* disable raw reassembly */ - (void)ConfSetFinal("stream.reassembly.raw", "false"); - } - - HostInitConfig(HOST_VERBOSE); - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - FlowInitConfig(FLOW_VERBOSE); - StreamTcpInitConfig(STREAM_VERBOSE); - IPPairInitConfig(IPPAIR_VERBOSE); - AppLayerRegisterGlobalCounters(); - } - - if (MagicInit() != 0) - exit(EXIT_FAILURE); - - DetectEngineCtx *de_ctx = NULL; - if (!suri.disabled_detect) { - SCClassConfInit(); - SCReferenceConfInit(); - SetupDelayedDetect(&suri); - int mt_enabled = 0; - (void)ConfGetBool("multi-detect.enabled", &mt_enabled); - int default_tenant = 0; - if (mt_enabled) - (void)ConfGetBool("multi-detect.default", &default_tenant); - if (DetectEngineMultiTenantSetup() == -1) { - SCLogError(SC_ERR_INITIALIZATION, "initializing multi-detect " - "detection engine contexts failed."); - exit(EXIT_FAILURE); - } - if (suri.delayed_detect || (mt_enabled && !default_tenant)) { - de_ctx = DetectEngineCtxInitMinimal(); - } else { - de_ctx = DetectEngineCtxInit(); - } - if (de_ctx == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine " - "context failed."); - exit(EXIT_FAILURE); - } - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) - CudaVarsSetDeCtx(de_ctx); -#endif /* __SC_CUDA_SUPPORT__ */ - - if (!de_ctx->minimal) { - if (LoadSignatures(de_ctx, &suri) != TM_ECODE_OK) - exit(EXIT_FAILURE); - if (suri.run_mode == RUNMODE_ENGINE_ANALYSIS) { - exit(EXIT_SUCCESS); - } - } - - DetectEngineAddToMaster(de_ctx); - } else { - /* tell the app layer to consider only the log id */ - RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveLogOnly); - } - - SCAsn1LoadConfig(); - - CoredumpLoadConfig(); - - SCSetStartTime(&suri); - - SCDropMainThreadCaps(suri.userid, suri.groupid); - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - RunModeInitializeOutputs(); - StatsSetupPostConfig(); - } - - if(suri.run_mode == RUNMODE_CONF_TEST){ - SCLogNotice("Configuration provided was successfully loaded. Exiting."); - exit(EXIT_SUCCESS); - } - - RunModeDispatch(suri.run_mode, suri.runmode_custom_mode); - - /* In Unix socket runmode, Flow manager is started on demand */ - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* Spawn the unix socket manager thread */ - int unix_socket = 0; - if (ConfGetBool("unix-command.enabled", &unix_socket) != 1) - unix_socket = 0; - if (unix_socket == 1) { - UnixManagerThreadSpawn(0); -#ifdef BUILD_UNIX_SOCKET - UnixManagerRegisterCommand("iface-stat", LiveDeviceIfaceStat, NULL, - UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("iface-list", LiveDeviceIfaceList, NULL, 0); -#endif - } - /* Spawn the flow manager thread */ - FlowManagerThreadSpawn(); - FlowRecyclerThreadSpawn(); - StatsSpawnThreads(); - } - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) - SCACCudaStartDispatcher(); -#endif - - /* Check if the alloted queues have at least 1 reader and writer */ - TmValidateQueueState(); - - /* Wait till all the threads have been initialized */ - if (TmThreadWaitOnThreadInit() == TM_ECODE_FAILED) { - SCLogError(SC_ERR_INITIALIZATION, "Engine initialization failed, " - "aborting..."); - exit(EXIT_FAILURE); - } - - (void) SC_ATOMIC_CAS(&engine_stage, SURICATA_INIT, SURICATA_RUNTIME); - PacketPoolPostRunmodes(); - - /* Un-pause all the paused threads */ - TmThreadContinueThreads(); - /* registering singal handlers we use. We register usr2 here, so that one - * can't call it during the first sig load phase or while threads are still - * starting up. */ - if (DetectEngineEnabled() && suri.sig_file == NULL && - suri.delayed_detect == 0) - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2); - - if (suri.delayed_detect) { - /* force 'reload', this will load the rules and swap engines */ - DetectEngineReload(NULL, &suri); - - if (suri.sig_file != NULL) - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2SigFileStartup); - else - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2); - SCLogNotice("Signature(s) loaded, Detect thread(s) activated."); - } - - -#ifdef DBG_MEM_ALLOC - SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem); -#ifdef DBG_MEM_ALLOC_SKIP_STARTUP - print_mem_flag = 1; -#endif -#endif - - int engine_retval = EXIT_SUCCESS; - while(1) { - if (suricata_ctl_flags & (SURICATA_KILL | SURICATA_STOP)) { - SCLogNotice("Signal Received. Stopping engine."); - - break; - } - - TmThreadCheckThreadState(); - - if (sighup_count > 0) { - OutputNotifyFileRotation(); - sighup_count--; - } - - if (sigusr2_count > 0) { - DetectEngineReload(conf_filename, &suri); - sigusr2_count--; - } else if (DetectEngineReloadIsStart()) { - DetectEngineReload(conf_filename, &suri); - DetectEngineReloadSetDone(); - } - - usleep(10* 1000); - } - - /* Update the engine stage/status flag */ - (void) SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT); - - UnixSocketKillSocketThread(); - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* First we need to disable the flow manager thread */ - FlowDisableFlowManagerThread(); - } - - - /* Disable packet acquisition first */ - TmThreadDisableReceiveThreads(); - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* we need a packet pool for FlowForceReassembly */ - PacketPoolInit(); - - FlowForceReassembly(); - /* kill receive threads when they have processed all - * flow timeout packets */ - TmThreadDisablePacketThreads(); - } - - SCPrintElapsedTime(&suri); - - /* before TmThreadKillThreads, as otherwise that kills it - * but more slowly */ - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - FlowDisableFlowRecyclerThread(); - } - - /* kill remaining threads */ - TmThreadKillThreads(); - - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* destroy the packet pool for flow reassembly after all - * the other threads are gone. */ - PacketPoolDestroy(); - - StatsReleaseResources(); - IPPairShutdown(); - FlowShutdown(); - StreamTcpFreeConfig(STREAM_VERBOSE); - } - HostShutdown(); - - HTPFreeConfig(); - HTPAtExitPrintStats(); - -#ifdef DBG_MEM_ALLOC - SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem); -#ifdef DBG_MEM_ALLOC_SKIP_STARTUP - print_mem_flag = 0; -#endif -#endif - - SCPidfileRemove(suri.pid_filename); - - AppLayerHtpPrintStats(); - - /** TODO this can do into it's own func */ - de_ctx = DetectEngineGetCurrent(); - if (de_ctx) { - DetectEngineMoveToFreeList(de_ctx); - DetectEngineDeReference(&de_ctx); - } - DetectEnginePruneFreeList(); - - AppLayerDeSetup(); - - TagDestroyCtx(); - - LiveDeviceListClean(); - RunModeShutDown(); - OutputDeregisterAll(); - TimeDeinit(); - SCProtoNameDeInit(); - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - DefragDestroy(); - } - if (!suri.disabled_detect) { - SCReferenceConfDeinit(); - SCClassConfDeinit(); - } - MagicDeinit(); - TmqhCleanup(); - TmModuleRunDeInit(); - ParseSizeDeinit(); -#ifdef HAVE_NSS - NSS_Shutdown(); - PR_Cleanup(); -#endif - -#ifdef HAVE_AF_PACKET - AFPPeersListClean(); -#endif - -#ifdef PROFILING - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - if (profiling_rules_enabled) - SCProfilingDump(); - SCProfilingDestroy(); - } -#endif - -#ifdef OS_WIN32 - if (daemon) { - return 0; - } -#endif /* OS_WIN32 */ - - SC_ATOMIC_DESTROY(engine_stage); - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) - MpmCudaBufferDeSetup(); - CudaHandlerFreeProfiles(); -#endif - ConfDeInit(); - - exit(engine_retval); -} |