suricata
suricata.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2025 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 */
23
24#include "suricata-common.h"
25
26#if HAVE_GETOPT_H
27#include <getopt.h>
28#endif
29
30#if HAVE_SIGNAL_H
31#include <signal.h>
32#endif
33#ifndef OS_WIN32
34#ifdef HAVE_SYS_RESOURCE_H
35// setrlimit
36#include <sys/resource.h>
37#endif
38#endif
39
40#include "suricata.h"
41
42#include "conf.h"
43#include "conf-yaml-loader.h"
44
45#include "decode.h"
46#include "defrag.h"
47#include "flow.h"
48#include "stream-tcp.h"
49#include "ippair.h"
50
51#include "detect.h"
52#include "detect-parse.h"
53#include "detect-engine.h"
55#include "detect-engine-alert.h"
56#include "detect-engine-port.h"
57#include "detect-engine-tag.h"
59#include "detect-fast-pattern.h"
60
61#include "datasets.h"
62
63#include "feature.h"
64
65#include "flow-bypass.h"
66#include "flow-manager.h"
67#include "flow-timeout.h"
68#include "flow-worker.h"
69
70#include "flow-bit.h"
71#include "host-bit.h"
72#include "ippair-bit.h"
73
74#include "app-layer.h"
75#include "app-layer-parser.h"
76#include "app-layer-htp.h"
77#include "app-layer-htp-range.h"
78
79#include "output.h"
80#include "output-filestore.h"
81
82#include "respond-reject.h"
83
84#include "runmode-af-packet.h"
85#include "runmode-af-xdp.h"
86#include "runmode-netmap.h"
87#include "runmode-unittests.h"
88
89#include "source-nfq.h"
91#include "source-nflog.h"
92#include "source-ipfw.h"
93#include "source-lib.h"
94#include "source-pcap.h"
95#include "source-pcap-file.h"
97#include "source-erf-file.h"
98#include "source-erf-dag.h"
99#include "source-af-packet.h"
100#include "source-af-xdp.h"
101#include "source-netmap.h"
102#include "source-dpdk.h"
103#include "source-windivert.h"
105
106#include "unix-manager.h"
107
111
112#include "tmqh-packetpool.h"
113#include "tm-queuehandlers.h"
114
115#include "util-affinity.h"
116#include "util-byte.h"
117#include "util-conf.h"
118#include "util-coredump-config.h"
119#include "util-cpu.h"
120#include "util-daemon.h"
121#include "util-device-private.h"
122#include "util-dpdk.h"
123#include "util-ebpf.h"
125#include "util-host-os-info.h"
126#include "util-hugepages.h"
127#include "util-ioctl.h"
128#include "util-landlock.h"
129#include "util-macset.h"
130#include "util-flow-rate.h"
131#include "util-misc.h"
132#include "util-mpm-hs.h"
133#include "util-path.h"
134#include "util-pidfile.h"
135#include "util-plugin.h"
136#include "util-privs.h"
137#include "util-profiling.h"
138#include "util-proto-name.h"
139#include "util-running-modes.h"
140#include "util-signal.h"
141#include "util-time.h"
142#include "util-validate.h"
143#include "util-var-name.h"
144#ifdef SYSTEMD_NOTIFY
145#include "util-systemd.h"
146#endif
147
148#ifdef WINDIVERT
149#include "decode-sll.h"
150#include "win32-syscall.h"
151#endif
152
153/*
154 * we put this here, because we only use it here in main.
155 */
156volatile sig_atomic_t sigint_count = 0;
157volatile sig_atomic_t sighup_count = 0;
158volatile sig_atomic_t sigterm_count = 0;
159volatile sig_atomic_t sigusr2_count = 0;
160
161/*
162 * Flag to indicate if the engine is at the initialization
163 * or already processing packets. 3 stages: SURICATA_INIT,
164 * SURICATA_RUNTIME and SURICATA_FINALIZE
165 */
166SC_ATOMIC_DECLARE(unsigned int, engine_stage);
167
168/* Max packets processed simultaneously per thread. */
169#define DEFAULT_MAX_PENDING_PACKETS 1024
170
171/** suricata engine control flags */
172volatile uint8_t suricata_ctl_flags = 0;
173
174/** Engine mode: inline (ENGINE_MODE_IPS) or just
175 * detection mode (ENGINE_MODE_IDS by default) */
176static enum EngineMode g_engine_mode = ENGINE_MODE_UNKNOWN;
177
178/** Host mode: set if box is sniffing only
179 * or is a router */
181
182/** Maximum packets to simultaneously process. */
184
185/** global indicating if detection is enabled */
187
188/** set caps or not */
189bool sc_set_caps = false;
190
191bool g_system = false;
192
193/** disable randomness to get reproducible results across runs */
194#ifndef AFLFUZZ_NO_RANDOM
196#else
198#endif
199
200/** determine (without branching) if we include the vlan_ids when hashing or
201 * comparing flows */
202uint16_t g_vlan_mask = 0xffff;
203
204/** determine (without branching) if we include the livedev ids when hashing or
205 * comparing flows */
206uint16_t g_livedev_mask = 0xffff;
207
208/** determine (without branching) if we include the recursion levels when hashing or
209 * comparing flows */
210uint8_t g_recurlvl_mask = 0xff;
211
212/* flag to disable hashing almost globally, to be similar to disabling nss
213 * support */
214bool g_disable_hashing = false;
215
216/* snapshot of the system's hugepages before system intitialization. */
218
219/** add per-proto app-layer error counters for exception policies stats? disabled by default */
221
222/** Suricata instance */
224
226{
227 return (suricata.sig_file != NULL);
228}
229
231{
232 return (g_engine_mode == ENGINE_MODE_UNKNOWN);
233}
234
236{
238 return (g_engine_mode == ENGINE_MODE_FIREWALL);
239}
240
241/* this returns true for firewall mode as well */
243{
245 return (g_engine_mode >= ENGINE_MODE_IPS);
246}
247
249{
251 return (g_engine_mode == ENGINE_MODE_IDS);
252}
253
255{
256 g_engine_mode = ENGINE_MODE_FIREWALL;
257}
258
260{
261 g_engine_mode = ENGINE_MODE_IPS;
262}
263
265{
266 g_engine_mode = ENGINE_MODE_IDS;
267}
268
269#ifdef UNITTESTS
271{
273 return 1;
274
275 return 0;
276}
277#endif
278
280{
281 return suricata.run_mode;
282}
283
285{
286 suricata.run_mode = run_mode;
287}
288
293
294/** signal handlers
295 *
296 * WARNING: don't use the SCLog* API in the handlers. The API is complex
297 * with memory allocation possibly happening, calls to syslog, json message
298 * construction, etc.
299 */
300
301#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
302static void SignalHandlerSigint(/*@unused@*/ int sig)
303{
304 sigint_count = 1;
305}
306static void SignalHandlerSigterm(/*@unused@*/ int sig)
307{
308 sigterm_count = 1;
309}
310#ifndef OS_WIN32
311#if HAVE_LIBUNWIND
312#define UNW_LOCAL_ONLY
313#include <libunwind.h>
314static void SignalHandlerUnexpected(int sig_num, siginfo_t *info, void *context)
315{
316 char msg[SC_LOG_MAX_LOG_MSG_LEN];
317 unw_cursor_t cursor;
318 /* Restore defaults for signals to avoid loops */
319 signal(SIGABRT, SIG_DFL);
320 signal(SIGSEGV, SIG_DFL);
321 int r;
322 if ((r = unw_init_local(&cursor, (unw_context_t *)(context)) != 0)) {
323 SCLogError("unable to obtain stack trace: unw_init_local: %s", unw_strerror(r));
324 goto terminate;
325 }
326
327 char *temp = msg;
328 int cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - msg), "stacktrace:sig %d:", sig_num);
329 temp += cw;
330 r = 1;
331 while (r > 0) {
332 if (unw_is_signal_frame(&cursor) == 0) {
333 unw_word_t off;
334 char name[256];
335 if (unw_get_proc_name(&cursor, name, sizeof(name), &off) == UNW_ENOMEM) {
336 cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - msg), "[unknown]:");
337 } else {
338 cw = snprintf(
339 temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - msg), "%s+0x%08" PRIx64, name, off);
340 }
341 temp += cw;
342 }
343
344 r = unw_step(&cursor);
345 if (r > 0) {
346 cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - msg), ";");
347 temp += cw;
348 }
349 }
350 SCLogError("%s", msg);
351
352terminate:
353 // Propagate signal to watchers, if any
354 kill(getpid(), sig_num);
355}
356#undef UNW_LOCAL_ONLY
357#endif /* HAVE_LIBUNWIND */
358#endif /* !OS_WIN32 */
359#endif
360
361#ifndef OS_WIN32
362/**
363 * SIGUSR2 handler. Just set sigusr2_count. The main loop will act on
364 * it.
365 */
366static void SignalHandlerSigusr2(int sig)
367{
368 if (sigusr2_count < 2)
370}
371
372/**
373 * SIGHUP handler. Just set sighup_count. The main loop will act on
374 * it.
375 */
376static void SignalHandlerSigHup(/*@unused@*/ int sig)
377{
378 sighup_count = 1;
379}
380#endif
381
389
391{
392 SCInstance *suri = &suricata;
394 HostShutdown();
397
399
400 /* TODO this can do into it's own func */
402 if (de_ctx) {
405 }
407
409 DatasetsSave();
413
418 TimeDeinit();
420 TmqhCleanup();
424
425#ifdef HAVE_DPDK
427#endif
428
429#ifdef HAVE_AF_PACKET
431#endif
432
433#ifdef NFQ
435#endif
436
437#ifdef BUILD_HYPERSCAN
439#endif
440
441 SCConfDeInit();
442
444
446 SCFree(suri->pid_filename);
447 suri->pid_filename = NULL;
448
451}
452
453/**
454 * \brief Used to send OS specific notification of running threads
455 *
456 * \retval TmEcode TM_ECODE_OK on success; TM_ECODE_FAILED on failure.
457 */
458static void OnNotifyRunning(void)
459{
460#ifdef SYSTEMD_NOTIFY
461 if (SystemDNotifyReady() < 0) {
462 SCLogWarning("failed to notify systemd");
463 }
464#endif
465}
466
467/** \brief make sure threads can stop the engine by calling this
468 * function. Purpose: pcap file mode needs to be able to tell the
469 * engine the file eof is reached. */
470void EngineStop(void)
471{
473}
474
475/**
476 * \brief Used to indicate that the current task is done.
477 *
478 * This is mainly used by pcap-file to tell it has finished
479 * to treat a pcap files when running in unix-socket mode.
480 */
481void EngineDone(void)
482{
484}
485
486static int SetBpfString(int argc, char *argv[])
487{
488 char *bpf_filter = NULL;
489 uint32_t bpf_len = 0;
490 int tmpindex = 0;
491
492 /* attempt to parse remaining args as bpf filter */
493 tmpindex = argc;
494 while(argv[tmpindex] != NULL) {
495 bpf_len+=strlen(argv[tmpindex]) + 1;
496 tmpindex++;
497 }
498
499 if (bpf_len == 0)
500 return TM_ECODE_OK;
501
502 bpf_filter = SCCalloc(1, bpf_len);
503 if (unlikely(bpf_filter == NULL))
504 return TM_ECODE_FAILED;
505
506 tmpindex = optind;
507 while(argv[tmpindex] != NULL) {
508 strlcat(bpf_filter, argv[tmpindex],bpf_len);
509 if(argv[tmpindex + 1] != NULL) {
510 strlcat(bpf_filter," ", bpf_len);
511 }
512 tmpindex++;
513 }
514
515 if(strlen(bpf_filter) > 0) {
516 if (SCConfSetFinal("bpf-filter", bpf_filter) != 1) {
517 SCLogError("Failed to set bpf filter.");
518 SCFree(bpf_filter);
519 return TM_ECODE_FAILED;
520 }
521 }
522 SCFree(bpf_filter);
523
524 return TM_ECODE_OK;
525}
526
527static void SetBpfStringFromFile(char *filename)
528{
529 char *bpf_filter = NULL;
530 char *bpf_comment_tmp = NULL;
531 char *bpf_comment_start = NULL;
532 size_t bpf_len = 0;
533 SCStat st;
534 FILE *fp = NULL;
535 size_t nm = 0;
536
537 fp = fopen(filename, "r");
538 if (fp == NULL) {
539 SCLogError("Failed to open file %s", filename);
540 exit(EXIT_FAILURE);
541 }
542
543 if (SCFstatFn(fileno(fp), &st) != 0) {
544 SCLogError("Failed to stat file %s", filename);
545 exit(EXIT_FAILURE);
546 }
547 // st.st_size is signed on Windows
548 bpf_len = ((size_t)(st.st_size)) + 1;
549
550 bpf_filter = SCCalloc(1, bpf_len);
551 if (unlikely(bpf_filter == NULL)) {
552 SCLogError("Failed to allocate buffer for bpf filter in file %s", filename);
553 exit(EXIT_FAILURE);
554 }
555
556 nm = fread(bpf_filter, 1, bpf_len - 1, fp);
557 if ((ferror(fp) != 0) || (nm != (bpf_len - 1))) {
558 SCLogError("Failed to read complete BPF file %s", filename);
559 SCFree(bpf_filter);
560 fclose(fp);
561 exit(EXIT_FAILURE);
562 }
563 fclose(fp);
564 bpf_filter[nm] = '\0';
565
566 if(strlen(bpf_filter) > 0) {
567 /*replace comments with space*/
568 bpf_comment_start = bpf_filter;
569 while((bpf_comment_tmp = strchr(bpf_comment_start, '#')) != NULL) {
570 while((*bpf_comment_tmp !='\0') &&
571 (*bpf_comment_tmp != '\r') && (*bpf_comment_tmp != '\n'))
572 {
573 *bpf_comment_tmp++ = ' ';
574 }
575 bpf_comment_start = bpf_comment_tmp;
576 }
577 /*remove remaining '\r' and '\n' */
578 while((bpf_comment_tmp = strchr(bpf_filter, '\r')) != NULL) {
579 *bpf_comment_tmp = ' ';
580 }
581 while((bpf_comment_tmp = strchr(bpf_filter, '\n')) != NULL) {
582 *bpf_comment_tmp = ' ';
583 }
584 /* cut trailing spaces */
585 while (strlen(bpf_filter) > 0 &&
586 bpf_filter[strlen(bpf_filter)-1] == ' ')
587 {
588 bpf_filter[strlen(bpf_filter)-1] = '\0';
589 }
590 if (strlen(bpf_filter) > 0) {
591 if (SCConfSetFinal("bpf-filter", bpf_filter) != 1) {
592 SCFree(bpf_filter);
593 FatalError("failed to set bpf filter");
594 }
595 }
596 }
597 SCFree(bpf_filter);
598}
599
600static void PrintUsage(const char *progname)
601{
602#ifdef REVISION
603 printf("%s %s (%s)\n", PROG_NAME, PROG_VER, xstr(REVISION));
604#else
605 printf("%s %s\n", PROG_NAME, PROG_VER);
606#endif
607 printf("USAGE: %s [OPTIONS] [BPF FILTER]\n\n", progname);
608
609 printf("\n General:\n");
610 printf("\t-v : be more verbose (use multiple times to "
611 "increase verbosity)\n");
612 printf("\t-c <path> : path to configuration file\n");
613 printf("\t-l <dir> : default log directory\n");
614 printf("\t--include <path> : additional configuration file\n");
615 printf("\t--set name=value : set a configuration value\n");
616 printf("\t--pidfile <file> : write pid to this file\n");
617 printf("\t-T : test configuration file (use with -c)\n");
618 printf("\t--init-errors-fatal : enable fatal failure on signature init "
619 "error\n");
620#ifndef OS_WIN32
621 printf("\t-D : run as daemon\n");
622#else
623 printf("\t--service-install : install as service\n");
624 printf("\t--service-remove : remove service\n");
625 printf("\t--service-change-params : change service startup parameters\n");
626#endif /* OS_WIN32 */
627#ifdef HAVE_LIBCAP_NG
628 printf("\t--user <user> : run suricata as this user after init\n");
629 printf("\t--group <group> : run suricata as this group after init\n");
630#endif /* HAVE_LIBCAP_NG */
631#ifdef BUILD_UNIX_SOCKET
632 printf("\t--unix-socket[=<file>] : use unix socket to control suricata work\n");
633#endif
634 printf("\t--runmode <runmode_id> : specific runmode modification the engine should run. The argument\n"
635 "\t supplied should be the id for the runmode obtained by running\n"
636 "\t --list-runmodes\n");
637
638 printf("\n Capture and IPS:\n");
639
640 printf("\t-F <bpf filter file> : bpf filter file\n");
641 printf("\t-k [all|none] : force checksum check (all) or disabled it "
642 "(none)\n");
643 printf("\t-i <dev or ip> : run in pcap live mode\n");
644 printf("\t--pcap[=<dev>] : run in pcap mode, no value select interfaces "
645 "from suricata.yaml\n");
646#ifdef HAVE_PCAP_SET_BUFF
647 printf("\t--pcap-buffer-size : size of the pcap buffer value from 0 - %i\n",INT_MAX);
648#endif /* HAVE_SET_PCAP_BUFF */
649#ifdef NFQ
650 printf("\t-q <qid[:qid]> : run in inline nfqueue mode (use colon to "
651 "specify a range of queues)\n");
652#endif /* NFQ */
653#ifdef IPFW
654 printf("\t-d <divert port> : run in inline ipfw divert mode\n");
655#endif /* IPFW */
656#ifdef HAVE_AF_PACKET
657 printf("\t--af-packet[=<dev>] : run in af-packet mode, no value select interfaces from suricata.yaml\n");
658#endif
659#ifdef HAVE_AF_XDP
660 printf("\t--af-xdp[=<dev>] : run in af-xdp mode, no value select "
661 "interfaces from suricata.yaml\n");
662#endif
663#ifdef HAVE_NETMAP
664 printf("\t--netmap[=<dev>] : run in netmap mode, no value select interfaces from suricata.yaml\n");
665#endif
666#ifdef HAVE_PFRING
667 printf("\t--pfring[=<dev>] : run in pfring mode, use interfaces from suricata.yaml\n");
668 printf("\t--pfring-int <dev> : run in pfring mode, use interface <dev>\n");
669 printf("\t--pfring-cluster-id <id> : pfring cluster id \n");
670 printf("\t--pfring-cluster-type <type> : pfring cluster type for PF_RING 4.1.2 and later cluster_round_robin|cluster_flow\n");
671#endif /* HAVE_PFRING */
672#ifdef HAVE_DPDK
673 printf("\t--dpdk : run in dpdk mode, uses interfaces from "
674 "suricata.yaml\n");
675#endif
676#ifdef HAVE_DAG
677 printf("\t--dag <dagX:Y> : process ERF records from DAG interface X, stream Y\n");
678#endif
679#ifdef WINDIVERT
680 printf("\t--windivert <filter> : run in inline WinDivert mode\n");
681 printf("\t--windivert-forward <filter> : run in inline WinDivert mode, as a gateway\n");
682#endif
683#ifdef HAVE_LIBNET11
684 printf("\t--reject-dev <dev> : send reject packets from this interface\n");
685#endif
686
687 printf("\n Capture Files:\n");
688 printf("\t-r <path> : run in pcap file/offline mode\n");
689 printf("\t--pcap-file-continuous : when running in pcap mode with a directory, "
690 "continue checking directory for pcaps until interrupted\n");
691 printf("\t--pcap-file-delete : when running in replay mode (-r with "
692 "directory or file), will delete pcap files that have been processed when done\n");
693 printf("\t--pcap-file-recursive : will descend into subdirectories when running "
694 "in replay mode (-r)\n");
695 printf("\t--pcap-file-buffer-size : set read buffer size (setvbuf)\n");
696 printf("\t--erf-in <path> : process an ERF file\n");
697
698 printf("\n Detection:\n");
699 printf("\t-s <path> : path to signature file loaded in addition to "
700 "suricata.yaml settings (optional)\n");
701 printf("\t-S <path> : path to signature file loaded exclusively "
702 "(optional)\n");
703 printf("\t--disable-detection : disable detection engine\n");
704 printf("\t--engine-analysis : print reports on analysis of different "
705 "sections in the engine and exit.\n"
706 "\t Please have a look at the conf parameter "
707 "engine-analysis on what reports\n"
708 "\t can be printed\n");
709
710 printf("\n Firewall:\n");
711 printf("\t--firewall : enable firewall mode\n");
712 printf("\t--firewall-rules-exclusive=<path> : path to firewall rule file loaded "
713 "exclusively\n");
714
715 printf("\n Info:\n");
716 printf("\t-V : display Suricata version\n");
717 printf("\t--list-keywords[=all|csv|<kword>] : list keywords implemented by the engine\n");
718 printf("\t--list-runmodes : list supported runmodes\n");
719 printf("\t--list-app-layer-protos : list supported app layer protocols\n");
720 printf("\t--list-app-layer-hooks : list supported app layer hooks for use in "
721 "rules\n");
722 printf("\t--dump-config : show the running configuration\n");
723 printf("\t--dump-features : display provided features\n");
724 printf("\t--build-info : display build information\n");
725
726 printf("\n Testing:\n");
727 printf("\t--simulate-ips : force engine into IPS mode. Useful for QA\n");
728#ifdef UNITTESTS
729 printf("\t-u : run the unittests and exit\n");
730 printf("\t-U=REGEX, --unittest-filter=REGEX : filter unittests with a pcre compatible "
731 "regex\n");
732 printf("\t--list-unittests : list unit tests\n");
733 printf("\t--fatal-unittests : enable fatal failure on unittest error\n");
734 printf("\t--unittests-coverage : display unittest coverage report\n");
735#endif /* UNITTESTS */
736 printf("\n");
737 printf("\nTo run " PROG_NAME " with default configuration on "
738 "interface eth0 with signature file \"signatures.rules\", run the "
739 "command as:\n\n%s -c suricata.yaml -s signatures.rules -i eth0 \n\n",
740 progname);
741}
742
743static void PrintBuildInfo(void)
744{
745 const char *bits;
746 const char *endian;
747 char features[2048] = "";
748 const char *tls;
749
750 printf("This is %s version %s\n", PROG_NAME, GetProgramVersion());
751#ifdef DEBUG
752 strlcat(features, "DEBUG ", sizeof(features));
753#endif
754#ifdef DEBUG_VALIDATION
755 strlcat(features, "DEBUG_VALIDATION ", sizeof(features));
756#endif
757#ifdef UNITTESTS
758 strlcat(features, "UNITTESTS ", sizeof(features));
759#endif
760#ifdef NFQ
761 strlcat(features, "NFQ ", sizeof(features));
762#endif
763#ifdef IPFW
764 strlcat(features, "IPFW ", sizeof(features));
765#endif
766#ifdef HAVE_PCAP_SET_BUFF
767 strlcat(features, "PCAP_SET_BUFF ", sizeof(features));
768#endif
769#ifdef HAVE_PFRING
770 strlcat(features, "PF_RING ", sizeof(features));
771#endif
772#ifdef HAVE_NAPATECH
773 strlcat(features, "NAPATECH ", sizeof(features));
774#endif
775#ifdef HAVE_AF_PACKET
776 strlcat(features, "AF_PACKET ", sizeof(features));
777#endif
778#ifdef HAVE_NETMAP
779 strlcat(features, "NETMAP ", sizeof(features));
780#endif
781#ifdef HAVE_PACKET_FANOUT
782 strlcat(features, "HAVE_PACKET_FANOUT ", sizeof(features));
783#endif
784#ifdef HAVE_DAG
785 strlcat(features, "DAG ", sizeof(features));
786#endif
787#ifdef HAVE_LIBCAP_NG
788 strlcat(features, "LIBCAP_NG ", sizeof(features));
789#endif
790#ifdef HAVE_LIBNET11
791 strlcat(features, "LIBNET1.1 ", sizeof(features));
792#endif
793 strlcat(features, "HAVE_HTP_URI_NORMALIZE_HOOK ", sizeof(features));
794#ifdef PCRE2_HAVE_JIT
795 strlcat(features, "PCRE_JIT ", sizeof(features));
796#endif
797 /* For compatibility, just say we have HAVE_NSS. */
798 strlcat(features, "HAVE_NSS ", sizeof(features));
799 /* HTTP2_DECOMPRESSION is not an optional feature in this major version */
800 strlcat(features, "HTTP2_DECOMPRESSION ", sizeof(features));
801 /* Lua is now vendored in and always available. */
802 strlcat(features, "HAVE_LUA ", sizeof(features));
803#ifdef HAVE_JA3
804 strlcat(features, "HAVE_JA3 ", sizeof(features));
805#endif
806#ifdef HAVE_JA4
807 strlcat(features, "HAVE_JA4 ", sizeof(features));
808#endif
809 strlcat(features, "HAVE_LIBJANSSON ", sizeof(features));
810#ifdef PROFILING
811 strlcat(features, "PROFILING ", sizeof(features));
812#endif
813#ifdef PROFILE_LOCKING
814 strlcat(features, "PROFILE_LOCKING ", sizeof(features));
815#endif
816#if defined(TLS_C11) || defined(TLS_GNU)
817 strlcat(features, "TLS ", sizeof(features));
818#endif
819#if defined(TLS_C11)
820 strlcat(features, "TLS_C11 ", sizeof(features));
821#elif defined(TLS_GNU)
822 strlcat(features, "TLS_GNU ", sizeof(features));
823#endif
824#ifdef HAVE_MAGIC
825 strlcat(features, "MAGIC ", sizeof(features));
826#endif
827 strlcat(features, "RUST ", sizeof(features));
828#if defined(SC_ADDRESS_SANITIZER)
829 strlcat(features, "ASAN ", sizeof(features));
830#endif
831#if defined(HAVE_POPCNT64)
832 strlcat(features, "POPCNT64 ", sizeof(features));
833#endif
834 if (strlen(features) == 0) {
835 strlcat(features, "none", sizeof(features));
836 }
837
838 printf("Features: %s\n", features);
839
840 /* SIMD stuff */
841 memset(features, 0x00, sizeof(features));
842#if defined(__SSE4_2__)
843 strlcat(features, "SSE_4_2 ", sizeof(features));
844#endif
845#if defined(__SSE4_1__)
846 strlcat(features, "SSE_4_1 ", sizeof(features));
847#endif
848#if defined(__SSE3__)
849 strlcat(features, "SSE_3 ", sizeof(features));
850#endif
851#if defined(__SSE2__)
852 strlcat(features, "SSE_2 ", sizeof(features));
853#endif
854 if (strlen(features) == 0) {
855 strlcat(features, "none", sizeof(features));
856 }
857 printf("SIMD support: %s\n", features);
858
859 /* atomics stuff */
860 memset(features, 0x00, sizeof(features));
861#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)
862 strlcat(features, "1 ", sizeof(features));
863#endif
864#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
865 strlcat(features, "2 ", sizeof(features));
866#endif
867#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
868 strlcat(features, "4 ", sizeof(features));
869#endif
870#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
871 strlcat(features, "8 ", sizeof(features));
872#endif
873#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
874 strlcat(features, "16 ", sizeof(features));
875#endif
876 if (strlen(features) == 0) {
877 strlcat(features, "none", sizeof(features));
878 } else {
879 strlcat(features, "byte(s)", sizeof(features));
880 }
881 printf("Atomic intrinsics: %s\n", features);
882
883#if __WORDSIZE == 64
884 bits = "64-bits";
885#elif __WORDSIZE == 32
886 bits = "32-bits";
887#else
888 bits = "<unknown>-bits";
889#endif
890
891#if __BYTE_ORDER == __BIG_ENDIAN
892 endian = "Big-endian";
893#elif __BYTE_ORDER == __LITTLE_ENDIAN
894 endian = "Little-endian";
895#else
896 endian = "<unknown>-endian";
897#endif
898
899 printf("%s, %s architecture\n", bits, endian);
900#ifdef __GNUC__
901 printf("GCC version %s, C version %"PRIiMAX"\n", __VERSION__, (intmax_t)__STDC_VERSION__);
902#else
903 printf("C version %"PRIiMAX"\n", (intmax_t)__STDC_VERSION__);
904#endif
905
906#if __SSP__ == 1
907 printf("compiled with -fstack-protector\n");
908#endif
909#if __SSP_ALL__ == 2
910 printf("compiled with -fstack-protector-all\n");
911#endif
912/*
913 * Workaround for special defines of _FORTIFY_SOURCE like
914 * FORTIFY_SOURCE=((defined __OPTIMIZE && OPTIMIZE > 0) ? 2 : 0)
915 * which is used by Gentoo for example and would result in the error
916 * 'defined' undeclared when _FORTIFY_SOURCE used via %d in printf func
917 *
918 */
919#if _FORTIFY_SOURCE == 2
920 printf("compiled with _FORTIFY_SOURCE=2\n");
921#elif _FORTIFY_SOURCE == 1
922 printf("compiled with _FORTIFY_SOURCE=1\n");
923#elif _FORTIFY_SOURCE == 0
924 printf("compiled with _FORTIFY_SOURCE=0\n");
925#endif
926#ifdef CLS
927 printf("L1 cache line size (CLS)=%d\n", CLS);
928#endif
929#if defined(TLS_C11)
930 tls = "_Thread_local";
931#elif defined(TLS_GNU)
932 tls = "__thread";
933#else
934#error "Unsupported thread local"
935#endif
936 printf("thread local storage method: %s\n", tls);
937
938 printf("compiled with %s\n", htp_get_version());
939 printf("\n");
940#include "build-info.h"
941}
942
946
948{
949 /* commanders */
951 /* managers */
955 /* nfq */
959 /* ipfw */
963 /* pcap live */
966 /* pcap file */
969 /* af-packet */
972 /* af-xdp */
975 /* netmap */
978 /* dag file */
981 /* dag live */
984
985 /* flow worker */
987 /* respond-reject */
989
990 /* log api */
993
995 /* nflog */
998
999 /* windivert */
1003
1004 /* Dpdk */
1007
1008 /* Library */
1010}
1011
1013{
1014 SCEnter();
1015
1016 SCInstance *suri = &suricata;
1017
1018 if (suri->conf_filename == NULL)
1020
1021 if (SCConfYamlLoadFile(suri->conf_filename) != 0) {
1022 /* Error already displayed. */
1024 }
1025
1026 if (suri->additional_configs) {
1027 for (int i = 0; suri->additional_configs[i] != NULL; i++) {
1028 SCLogConfig("Loading additional configuration file %s", suri->additional_configs[i]);
1030 }
1031 }
1032
1034}
1035
1036static TmEcode ParseInterfacesList(const int runmode, char *pcap_dev)
1037{
1038 SCEnter();
1039
1040 /* run the selected runmode */
1041 if (runmode == RUNMODE_PCAP_DEV) {
1042 if (strlen(pcap_dev) == 0) {
1043 int ret = LiveBuildDeviceList("pcap");
1044 if (ret == 0) {
1045 SCLogError("No interface found in config for pcap");
1047 }
1048 }
1049 } else if (runmode == RUNMODE_PLUGIN) {
1050 if (strcmp(suricata.capture_plugin_name, "pfring") == 0) {
1051 /* Special handling for pfring. */
1052 if (strlen(pcap_dev)) {
1053 if (SCConfSetFinal("pfring.live-interface", pcap_dev) != 1) {
1054 SCLogError("Failed to set pfring.live-interface");
1056 }
1057 }
1058 }
1059#ifdef HAVE_DPDK
1060 } else if (runmode == RUNMODE_DPDK) {
1061 char iface_selector[] = "dpdk.interfaces";
1062 int ret = LiveBuildDeviceList(iface_selector);
1063 if (ret == 0) {
1064 SCLogError("No interface found in config for %s", iface_selector);
1066 }
1067#endif
1068#ifdef HAVE_AF_PACKET
1069 } else if (runmode == RUNMODE_AFP_DEV) {
1070 /* iface has been set on command line */
1071 if (strlen(pcap_dev)) {
1072 if (SCConfSetFinal("af-packet.live-interface", pcap_dev) != 1) {
1073 SCLogError("Failed to set af-packet.live-interface");
1075 }
1076 } else {
1077 int ret = LiveBuildDeviceList("af-packet");
1078 if (ret == 0) {
1079 SCLogError("No interface found in config for af-packet");
1081 }
1082 }
1083#endif
1084#ifdef HAVE_AF_XDP
1085 } else if (runmode == RUNMODE_AFXDP_DEV) {
1086 /* iface has been set on command line */
1087 if (strlen(pcap_dev)) {
1088 if (SCConfSetFinal("af-xdp.live-interface", pcap_dev) != 1) {
1089 SCLogError("Failed to set af-xdp.live-interface");
1091 }
1092 } else {
1093 int ret = LiveBuildDeviceList("af-xdp");
1094 if (ret == 0) {
1095 SCLogError("No interface found in config for af-xdp");
1097 }
1098 }
1099#endif
1100#ifdef HAVE_NETMAP
1101 } else if (runmode == RUNMODE_NETMAP) {
1102 /* iface has been set on command line */
1103 if (strlen(pcap_dev)) {
1104 if (SCConfSetFinal("netmap.live-interface", pcap_dev) != 1) {
1105 SCLogError("Failed to set netmap.live-interface");
1107 }
1108 } else {
1109 int ret = LiveBuildDeviceList("netmap");
1110 if (ret == 0) {
1111 SCLogError("No interface found in config for netmap");
1113 }
1114 }
1115#endif
1116#ifdef HAVE_NFLOG
1117 } else if (runmode == RUNMODE_NFLOG) {
1118 int ret = LiveBuildDeviceListCustom("nflog", "group");
1119 if (ret == 0) {
1120 SCLogError("No group found in config for nflog");
1122 }
1123#endif
1124 }
1125
1127}
1128
1129static void SCInstanceInit(SCInstance *suri, const char *progname)
1130{
1131 memset(suri, 0x00, sizeof(*suri));
1132
1133 suri->progname = progname;
1134 suri->run_mode = RUNMODE_UNKNOWN;
1135
1136 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1137 suri->sig_file = NULL;
1138 suri->sig_file_exclusive = false;
1139 suri->pid_filename = NULL;
1140 suri->regex_arg = NULL;
1141
1142 suri->keyword_info = NULL;
1143 suri->runmode_custom_mode = NULL;
1144#ifndef OS_WIN32
1145 suri->user_name = NULL;
1146 suri->group_name = NULL;
1147 suri->do_setuid = false;
1148 suri->do_setgid = false;
1149#endif /* OS_WIN32 */
1150 suri->userid = 0;
1151 suri->groupid = 0;
1152 suri->delayed_detect = 0;
1153 suri->daemon = 0;
1154 suri->offline = 0;
1155 suri->verbose = 0;
1156 /* use -1 as unknown */
1157 suri->checksum_validation = -1;
1158#if HAVE_DETECT_DISABLED==1
1160#else
1162#endif
1163}
1164
1165const char *GetDocURL(void)
1166{
1167 const char *prog_ver = GetProgramVersion();
1168 if (strstr(prog_ver, "RELEASE") != NULL) {
1169 return DOC_URL "suricata-" PROG_VER;
1170 }
1171 return DOC_URL "latest";
1172}
1173
1174/** \brief get string with program version
1175 *
1176 * Get the program version as passed to us from AC_INIT
1177 *
1178 * Add 'RELEASE' is no '-dev' in the version. Add the REVISION if passed
1179 * to us.
1180 *
1181 * Possible outputs:
1182 * release: '5.0.1 RELEASE'
1183 * dev with rev: '5.0.1-dev (64a789bbf 2019-10-18)'
1184 * dev w/o rev: '5.0.1-dev'
1185 */
1186const char *GetProgramVersion(void)
1187{
1188 if (strstr(PROG_VER, "-dev") == NULL) {
1189 return PROG_VER " RELEASE";
1190 } else {
1191#ifdef REVISION
1192 return PROG_VER " (" xstr(REVISION) ")";
1193#else
1194 return PROG_VER;
1195#endif
1196 }
1197}
1198
1199static TmEcode PrintVersion(void)
1200{
1201 printf("This is %s version %s\n", PROG_NAME, GetProgramVersion());
1202 return TM_ECODE_OK;
1203}
1204
1205static TmEcode LogVersion(SCInstance *suri)
1206{
1207 const char *mode = suri->system ? "SYSTEM" : "USER";
1208 SCLogNotice("This is %s version %s running in %s mode",
1209 PROG_NAME, GetProgramVersion(), mode);
1210 return TM_ECODE_OK;
1211}
1212
1213static void SCSetStartTime(SCInstance *suri)
1214{
1215 memset(&suri->start_time, 0, sizeof(suri->start_time));
1216 gettimeofday(&suri->start_time, NULL);
1217}
1218
1219static void SCPrintElapsedTime(struct timeval *start_time)
1220{
1221 if (start_time == NULL)
1222 return;
1223 struct timeval end_time;
1224 memset(&end_time, 0, sizeof(end_time));
1225 gettimeofday(&end_time, NULL);
1226 uint64_t milliseconds = ((end_time.tv_sec - start_time->tv_sec) * 1000) +
1227 (((1000000 + end_time.tv_usec - start_time->tv_usec) / 1000) - 1000);
1228 SCLogInfo("time elapsed %.3fs", (float)milliseconds/(float)1000);
1229}
1230
1231static int ParseCommandLineAfpacket(SCInstance *suri, const char *in_arg)
1232{
1233#ifdef HAVE_AF_PACKET
1234 if (suri->run_mode == RUNMODE_UNKNOWN) {
1235 suri->run_mode = RUNMODE_AFP_DEV;
1236 if (in_arg) {
1237 LiveRegisterDeviceName(in_arg);
1238 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1239 strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
1240 }
1241 } else if (suri->run_mode == RUNMODE_AFP_DEV) {
1242 if (in_arg) {
1243 LiveRegisterDeviceName(in_arg);
1244 } else {
1245 SCLogInfo("Multiple af-packet option without interface on each is useless");
1246 }
1247 } else {
1248 SCLogError("more than one run mode "
1249 "has been specified");
1250 PrintUsage(suri->progname);
1251 return TM_ECODE_FAILED;
1252 }
1253 return TM_ECODE_OK;
1254#else
1255 SCLogError("AF_PACKET not enabled. On Linux "
1256 "host, make sure to pass --enable-af-packet to "
1257 "configure when building.");
1258 return TM_ECODE_FAILED;
1259#endif
1260}
1261
1262static int ParseCommandLineAfxdp(SCInstance *suri, const char *in_arg)
1263{
1264#ifdef HAVE_AF_XDP
1265 if (suri->run_mode == RUNMODE_UNKNOWN) {
1267 if (in_arg) {
1268 LiveRegisterDeviceName(in_arg);
1269 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1270 strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
1271 }
1272 } else if (suri->run_mode == RUNMODE_AFXDP_DEV) {
1273 if (in_arg) {
1274 LiveRegisterDeviceName(in_arg);
1275 } else {
1276 SCLogInfo("Multiple af-xdp options without interface on each is useless");
1277 }
1278 } else {
1279 SCLogError("more than one run mode "
1280 "has been specified");
1281 PrintUsage(suri->progname);
1282 return TM_ECODE_FAILED;
1283 }
1284 return TM_ECODE_OK;
1285#else
1286 SCLogError("AF_XDP not enabled. On Linux "
1287 "host, make sure correct libraries are installed,"
1288 " see documentation for information.");
1289 return TM_ECODE_FAILED;
1290#endif
1291}
1292
1293static int ParseCommandLineDpdk(SCInstance *suri, const char *in_arg)
1294{
1295#ifdef HAVE_DPDK
1296 if (suri->run_mode == RUNMODE_UNKNOWN) {
1297 suri->run_mode = RUNMODE_DPDK;
1298 } else if (suri->run_mode == RUNMODE_DPDK) {
1299 SCLogInfo("Multiple dpdk options have no effect on Suricata");
1300 } else {
1301 SCLogError("more than one run mode "
1302 "has been specified");
1303 PrintUsage(suri->progname);
1304 return TM_ECODE_FAILED;
1305 }
1306 return TM_ECODE_OK;
1307#else
1308 SCLogError("DPDK not enabled. On Linux "
1309 "host, make sure to pass --enable-dpdk to "
1310 "configure when building.");
1311 return TM_ECODE_FAILED;
1312#endif
1313}
1314
1315static int ParseCommandLinePcapLive(SCInstance *suri, const char *in_arg)
1316{
1317#if defined(OS_WIN32) && !defined(HAVE_LIBWPCAP)
1318 /* If running on Windows without Npcap, bail early as live capture is not supported. */
1319 FatalError("Live capture not available. To support live capture compile against Npcap.");
1320#endif
1321 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1322
1323 if (in_arg != NULL) {
1324 /* some windows shells require escaping of the \ in \Device. Otherwise
1325 * the backslashes are stripped. We put them back here. */
1326 if (strlen(in_arg) > 9 && strncmp(in_arg, "DeviceNPF", 9) == 0) {
1327 snprintf(suri->pcap_dev, sizeof(suri->pcap_dev), "\\Device\\NPF%s", in_arg+9);
1328 } else {
1329 strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
1330 PcapTranslateIPToDevice(suri->pcap_dev, sizeof(suri->pcap_dev));
1331 }
1332
1333 if (strcmp(suri->pcap_dev, in_arg) != 0) {
1334 SCLogInfo("translated %s to pcap device %s", in_arg, suri->pcap_dev);
1335 } else if (strlen(suri->pcap_dev) > 0 && isdigit((unsigned char)suri->pcap_dev[0])) {
1336 SCLogError("failed to find a pcap device for IP %s", in_arg);
1337 return TM_ECODE_FAILED;
1338 }
1339 }
1340
1341 if (suri->run_mode == RUNMODE_UNKNOWN) {
1342 suri->run_mode = RUNMODE_PCAP_DEV;
1343 if (in_arg) {
1345 }
1346 } else if (suri->run_mode == RUNMODE_PCAP_DEV) {
1348 } else {
1349 SCLogError("more than one run mode "
1350 "has been specified");
1351 PrintUsage(suri->progname);
1352 return TM_ECODE_FAILED;
1353 }
1354 return TM_ECODE_OK;
1355}
1356
1357/**
1358 * Helper function to check if log directory is writable
1359 */
1360static bool IsLogDirectoryWritable(const char* str)
1361{
1362 if (access(str, W_OK) == 0)
1363 return true;
1364 return false;
1365}
1366
1367extern int g_skip_prefilter;
1368
1369TmEcode SCParseCommandLine(int argc, char **argv)
1370{
1371 SCInstance *suri = &suricata;
1372 int opt;
1373
1374 int dump_config = 0;
1375 int dump_features = 0;
1376 int list_app_layer_protocols = 0;
1377 int list_app_layer_hooks = 0;
1378 int list_unittests = 0;
1379 int list_runmodes = 0;
1380 int list_keywords = 0;
1381 int build_info = 0;
1382 int conf_test = 0;
1383 int engine_analysis = 0;
1384 int ret = TM_ECODE_OK;
1385 int is_firewall = 0;
1386
1387#ifdef UNITTESTS
1389 g_ut_modules = 0;
1390 g_ut_covered = 0;
1391#endif
1392
1393 // clang-format off
1394 struct option long_opts[] = {
1395 {"help", 0, 0, 0},
1396 {"dump-config", 0, &dump_config, 1},
1397 {"dump-features", 0, &dump_features, 1},
1398 {"pfring", optional_argument, 0, 0},
1399 {"pfring-int", required_argument, 0, 0},
1400 {"pfring-cluster-id", required_argument, 0, 0},
1401 {"pfring-cluster-type", required_argument, 0, 0},
1402#ifdef HAVE_DPDK
1403 {"dpdk", 0, 0, 0},
1404#endif
1405 {"af-packet", optional_argument, 0, 0},
1406 {"af-xdp", optional_argument, 0, 0},
1407 {"netmap", optional_argument, 0, 0},
1408 {"pcap", optional_argument, 0, 0},
1409 {"pcap-file-continuous", 0, 0, 0},
1410 {"pcap-file-delete", 0, 0, 0},
1411 {"pcap-file-recursive", 0, 0, 0},
1412 {"pcap-file-buffer-size", required_argument, 0, 0},
1413 {"simulate-ips", 0, 0 , 0},
1414 {"no-random", 0, &g_disable_randomness, 1},
1415 {"strict-rule-keywords", optional_argument, 0, 0},
1416
1417 {"capture-plugin", required_argument, 0, 0},
1418 {"capture-plugin-args", required_argument, 0, 0},
1419
1420#ifdef BUILD_UNIX_SOCKET
1421 {"unix-socket", optional_argument, 0, 0},
1422#endif
1423 {"pcap-buffer-size", required_argument, 0, 0},
1424 {"unittest-filter", required_argument, 0, 'U'},
1425 {"list-app-layer-protos", 0, &list_app_layer_protocols, 1},
1426 {"list-app-layer-hooks", 0, &list_app_layer_hooks, 1},
1427 {"list-unittests", 0, &list_unittests, 1},
1428 {"list-runmodes", 0, &list_runmodes, 1},
1429 {"list-keywords", optional_argument, &list_keywords, 1},
1430 {"runmode", required_argument, NULL, 0},
1431 {"engine-analysis", 0, &engine_analysis, 1},
1432#ifdef OS_WIN32
1433 {"service-install", 0, 0, 0},
1434 {"service-remove", 0, 0, 0},
1435 {"service-change-params", 0, 0, 0},
1436#endif /* OS_WIN32 */
1437 {"pidfile", required_argument, 0, 0},
1438 {"init-errors-fatal", 0, 0, 0},
1439 {"disable-detection", 0, 0, 0},
1440 {"disable-hashing", 0, 0, 0},
1441 {"fatal-unittests", 0, 0, 0},
1442 {"unittests-coverage", 0, &coverage_unittests, 1},
1443 {"user", required_argument, 0, 0},
1444 {"group", required_argument, 0, 0},
1445 {"erf-in", required_argument, 0, 0},
1446 {"dag", required_argument, 0, 0},
1447 {"build-info", 0, &build_info, 1},
1448 {"data-dir", required_argument, 0, 0},
1449#ifdef WINDIVERT
1450 {"windivert", required_argument, 0, 0},
1451 {"windivert-forward", required_argument, 0, 0},
1452#endif
1453#ifdef HAVE_LIBNET11
1454 {"reject-dev", required_argument, 0, 0},
1455#endif
1456 {"set", required_argument, 0, 0},
1457#ifdef HAVE_NFLOG
1458 {"nflog", optional_argument, 0, 0},
1459#endif
1460 {"simulate-packet-flow-memcap", required_argument, 0, 0},
1461 {"simulate-applayer-error-at-offset-ts", required_argument, 0, 0},
1462 {"simulate-applayer-error-at-offset-tc", required_argument, 0, 0},
1463 {"simulate-packet-loss", required_argument, 0, 0},
1464 {"simulate-packet-tcp-reassembly-memcap", required_argument, 0, 0},
1465 {"simulate-packet-tcp-ssn-memcap", required_argument, 0, 0},
1466 {"simulate-packet-defrag-memcap", required_argument, 0, 0},
1467 {"simulate-alert-queue-realloc-failure", 0, 0, 0},
1468
1469 {"qa-skip-prefilter", 0, &g_skip_prefilter, 1 },
1470
1471 {"firewall", 0, &is_firewall, 1 },
1472 {"firewall-rules-exclusive", required_argument, 0, 0},
1473
1474 {"include", required_argument, 0, 0},
1475
1476 {NULL, 0, NULL, 0}
1477 };
1478 // clang-format on
1479
1480 /* getopt_long stores the option index here. */
1481 int option_index = 0;
1482
1483 char short_opts[] = "c:TDhi:l:q:d:r:us:S:U:VF:vk:";
1484
1485 while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) {
1486 switch (opt) {
1487 case 0:
1488 if (strcmp((long_opts[option_index]).name, "help") == 0) {
1490 return TM_ECODE_OK;
1491 } else if (strcmp((long_opts[option_index]).name, "pfring") == 0 ||
1492 strcmp((long_opts[option_index]).name, "pfring-int") == 0) {
1493#ifdef HAVE_PFRING
1494 /* TODO: Which plugin? */
1495 suri->run_mode = RUNMODE_PLUGIN;
1496 suri->capture_plugin_name = "pfring";
1497 if (optarg != NULL) {
1498 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1499 strlcpy(suri->pcap_dev, optarg,
1500 ((strlen(optarg) < sizeof(suri->pcap_dev)) ?
1501 (strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
1502 LiveRegisterDeviceName(optarg);
1503 }
1504#else
1505 SCLogError("PF_RING not enabled. Make sure "
1506 "to pass --enable-pfring to configure when building.");
1507 return TM_ECODE_FAILED;
1508#endif /* HAVE_PFRING */
1509 } else if (strcmp((long_opts[option_index]).name, "pfring-cluster-id") == 0) {
1510#ifdef HAVE_PFRING
1511 if (SCConfSetFinal("pfring.cluster-id", optarg) != 1) {
1512 SCLogError("failed to set pfring.cluster-id");
1513 return TM_ECODE_FAILED;
1514 }
1515#else
1516 SCLogError("PF_RING not enabled. Make sure "
1517 "to pass --enable-pfring to configure when building.");
1518 return TM_ECODE_FAILED;
1519#endif /* HAVE_PFRING */
1520 } else if (strcmp((long_opts[option_index]).name, "pfring-cluster-type") == 0) {
1521#ifdef HAVE_PFRING
1522 if (SCConfSetFinal("pfring.cluster-type", optarg) != 1) {
1523 SCLogError("failed to set pfring.cluster-type");
1524 return TM_ECODE_FAILED;
1525 }
1526#else
1527 SCLogError("PF_RING not enabled. Make sure "
1528 "to pass --enable-pfring to configure when building.");
1529 return TM_ECODE_FAILED;
1530#endif /* HAVE_PFRING */
1531 } else if (strcmp((long_opts[option_index]).name, "capture-plugin") == 0) {
1532 suri->run_mode = RUNMODE_PLUGIN;
1533 suri->capture_plugin_name = optarg;
1534 } else if (strcmp((long_opts[option_index]).name, "capture-plugin-args") == 0) {
1535 suri->capture_plugin_args = optarg;
1536 } else if (strcmp((long_opts[option_index]).name, "dpdk") == 0) {
1537 if (ParseCommandLineDpdk(suri, optarg) != TM_ECODE_OK) {
1538 return TM_ECODE_FAILED;
1539 }
1540 } else if (strcmp((long_opts[option_index]).name, "af-packet") == 0) {
1541 if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
1542 return TM_ECODE_FAILED;
1543 }
1544 } else if (strcmp((long_opts[option_index]).name, "af-xdp") == 0) {
1545 if (ParseCommandLineAfxdp(suri, optarg) != TM_ECODE_OK) {
1546 return TM_ECODE_FAILED;
1547 }
1548 } else if (strcmp((long_opts[option_index]).name, "netmap") == 0) {
1549#ifdef HAVE_NETMAP
1550 if (suri->run_mode == RUNMODE_UNKNOWN) {
1551 suri->run_mode = RUNMODE_NETMAP;
1552 if (optarg) {
1553 LiveRegisterDeviceName(optarg);
1554 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1555 strlcpy(suri->pcap_dev, optarg,
1556 ((strlen(optarg) < sizeof(suri->pcap_dev)) ?
1557 (strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
1558 }
1559 } else if (suri->run_mode == RUNMODE_NETMAP) {
1560 if (optarg) {
1561 LiveRegisterDeviceName(optarg);
1562 } else {
1563 SCLogInfo("Multiple netmap option without interface on each is useless");
1564 break;
1565 }
1566 } else {
1567 SCLogError("more than one run mode "
1568 "has been specified");
1569 PrintUsage(argv[0]);
1570 return TM_ECODE_FAILED;
1571 }
1572#else
1573 SCLogError("NETMAP not enabled.");
1574 return TM_ECODE_FAILED;
1575#endif
1576 } else if (strcmp((long_opts[option_index]).name, "nflog") == 0) {
1577#ifdef HAVE_NFLOG
1578 if (suri->run_mode == RUNMODE_UNKNOWN) {
1579 suri->run_mode = RUNMODE_NFLOG;
1580 LiveBuildDeviceListCustom("nflog", "group");
1581 }
1582#else
1583 SCLogError("NFLOG not enabled.");
1584 return TM_ECODE_FAILED;
1585#endif /* HAVE_NFLOG */
1586 } else if (strcmp((long_opts[option_index]).name, "pcap") == 0) {
1587 if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
1588 return TM_ECODE_FAILED;
1589 }
1590 } else if (strcmp((long_opts[option_index]).name, "simulate-ips") == 0) {
1591 SCLogInfo("Setting IPS mode");
1593 } else if (strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) {
1594 if (SCConfSetFinal("engine.init-failure-fatal", "1") != 1) {
1595 SCLogError("failed to set engine init-failure-fatal");
1596 return TM_ECODE_FAILED;
1597 }
1598#ifdef BUILD_UNIX_SOCKET
1599 } else if (strcmp((long_opts[option_index]).name , "unix-socket") == 0) {
1600 if (suri->run_mode == RUNMODE_UNKNOWN) {
1602 if (optarg) {
1603 if (SCConfSetFinal("unix-command.filename", optarg) != 1) {
1604 SCLogError("failed to set unix-command.filename");
1605 return TM_ECODE_FAILED;
1606 }
1607 }
1608 } else {
1609 SCLogError("more than one run mode "
1610 "has been specified");
1611 PrintUsage(argv[0]);
1612 return TM_ECODE_FAILED;
1613 }
1614#endif
1615 }
1616 else if(strcmp((long_opts[option_index]).name, "list-app-layer-protocols") == 0) {
1617 /* listing all supported app layer protocols */
1618 } else if (strcmp((long_opts[option_index]).name, "list-app-layer-hooks") == 0) {
1619 /* listing all supported app layer hooks */
1620 } else if (strcmp((long_opts[option_index]).name, "list-unittests") == 0) {
1621#ifdef UNITTESTS
1623#else
1624 SCLogError("unit tests not enabled. Make sure to pass --enable-unittests to "
1625 "configure when building");
1626 return TM_ECODE_FAILED;
1627#endif /* UNITTESTS */
1628 } else if (strcmp((long_opts[option_index]).name, "list-runmodes") == 0) {
1630 return TM_ECODE_OK;
1631 } else if (strcmp((long_opts[option_index]).name, "list-keywords") == 0) {
1632 if (optarg) {
1633 if (strcmp("short", optarg) != 0) {
1634 suri->keyword_info = optarg;
1635 }
1636 }
1637 } else if (strcmp((long_opts[option_index]).name, "runmode") == 0) {
1638 suri->runmode_custom_mode = optarg;
1639 } else if (strcmp((long_opts[option_index]).name, "engine-analysis") == 0) {
1640 // do nothing for now
1641 }
1642#ifdef OS_WIN32
1643 else if (strcmp((long_opts[option_index]).name, "service-install") == 0) {
1644 suri->run_mode = RUNMODE_INSTALL_SERVICE;
1645 return TM_ECODE_OK;
1646 } else if (strcmp((long_opts[option_index]).name, "service-remove") == 0) {
1647 suri->run_mode = RUNMODE_REMOVE_SERVICE;
1648 return TM_ECODE_OK;
1649 } else if (strcmp((long_opts[option_index]).name, "service-change-params") == 0) {
1650 suri->run_mode = RUNMODE_CHANGE_SERVICE_PARAMS;
1651 return TM_ECODE_OK;
1652 }
1653#endif /* OS_WIN32 */
1654 else if (strcmp((long_opts[option_index]).name, "pidfile") == 0) {
1655 suri->pid_filename = SCStrdup(optarg);
1656 if (suri->pid_filename == NULL) {
1657 SCLogError("strdup failed: %s", strerror(errno));
1658 return TM_ECODE_FAILED;
1659 }
1660 } else if (strcmp((long_opts[option_index]).name, "disable-detection") == 0) {
1662 } else if (strcmp((long_opts[option_index]).name, "disable-hashing") == 0) {
1663 g_disable_hashing = true;
1664 // for rust
1665 SCDisableHashing();
1666 } else if (strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) {
1667#ifdef UNITTESTS
1668 unittests_fatal = 1;
1669#else
1670 SCLogError("unit tests not enabled. Make sure to pass --enable-unittests to "
1671 "configure when building");
1672 return TM_ECODE_FAILED;
1673#endif /* UNITTESTS */
1674 } else if (strcmp((long_opts[option_index]).name, "user") == 0) {
1675#ifndef HAVE_LIBCAP_NG
1676 SCLogError("libcap-ng is required to"
1677 " drop privileges, but it was not compiled into Suricata.");
1678 return TM_ECODE_FAILED;
1679#else
1680 suri->user_name = optarg;
1681 suri->do_setuid = true;
1682#endif /* HAVE_LIBCAP_NG */
1683 } else if (strcmp((long_opts[option_index]).name, "group") == 0) {
1684#ifndef HAVE_LIBCAP_NG
1685 SCLogError("libcap-ng is required to"
1686 " drop privileges, but it was not compiled into Suricata.");
1687 return TM_ECODE_FAILED;
1688#else
1689 suri->group_name = optarg;
1690 suri->do_setgid = true;
1691#endif /* HAVE_LIBCAP_NG */
1692 } else if (strcmp((long_opts[option_index]).name, "erf-in") == 0) {
1693 suri->run_mode = RUNMODE_ERF_FILE;
1694 if (SCConfSetFinal("erf-file.file", optarg) != 1) {
1695 SCLogError("failed to set erf-file.file");
1696 return TM_ECODE_FAILED;
1697 }
1698 } else if (strcmp((long_opts[option_index]).name, "dag") == 0) {
1699#ifdef HAVE_DAG
1700 if (suri->run_mode == RUNMODE_UNKNOWN) {
1701 suri->run_mode = RUNMODE_DAG;
1702 }
1703 else if (suri->run_mode != RUNMODE_DAG) {
1704 SCLogError("more than one run mode has been specified");
1705 PrintUsage(argv[0]);
1706 return TM_ECODE_FAILED;
1707 }
1708 LiveRegisterDeviceName(optarg);
1709#else
1710 SCLogError("libdag and a DAG card are required"
1711 " to receive packets using --dag.");
1712 return TM_ECODE_FAILED;
1713#endif /* HAVE_DAG */
1714 } else if (strcmp((long_opts[option_index]).name, "napatech") == 0) {
1715#ifdef HAVE_NAPATECH
1716 suri->run_mode = RUNMODE_PLUGIN;
1717#else
1718 SCLogError("libntapi and a Napatech adapter are required"
1719 " to capture packets using --napatech.");
1720 return TM_ECODE_FAILED;
1721#endif /* HAVE_NAPATECH */
1722 } else if (strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) {
1723#ifdef HAVE_PCAP_SET_BUFF
1724 if (SCConfSetFinal("pcap.buffer-size", optarg) != 1) {
1725 SCLogError("failed to set pcap-buffer-size");
1726 return TM_ECODE_FAILED;
1727 }
1728#else
1729 SCLogError("The version of libpcap you have"
1730 " doesn't support setting buffer size.");
1731#endif /* HAVE_PCAP_SET_BUFF */
1732 } else if (strcmp((long_opts[option_index]).name, "build-info") == 0) {
1734 return TM_ECODE_OK;
1735 } else if (strcmp((long_opts[option_index]).name, "windivert-forward") == 0) {
1736#ifdef WINDIVERT
1737 if (suri->run_mode == RUNMODE_UNKNOWN) {
1739 if (WinDivertRegisterQueue(true, optarg) == -1) {
1740 exit(EXIT_FAILURE);
1741 }
1742 } else if (suri->run_mode == RUNMODE_WINDIVERT) {
1743 if (WinDivertRegisterQueue(true, optarg) == -1) {
1744 exit(EXIT_FAILURE);
1745 }
1746 } else {
1747 SCLogError("more than one run mode "
1748 "has been specified");
1749 PrintUsage(argv[0]);
1750 exit(EXIT_FAILURE);
1751 }
1752 }
1753 else if(strcmp((long_opts[option_index]).name, "windivert") == 0) {
1754 if (suri->run_mode == RUNMODE_UNKNOWN) {
1756 if (WinDivertRegisterQueue(false, optarg) == -1) {
1757 exit(EXIT_FAILURE);
1758 }
1759 } else if (suri->run_mode == RUNMODE_WINDIVERT) {
1760 if (WinDivertRegisterQueue(false, optarg) == -1) {
1761 exit(EXIT_FAILURE);
1762 }
1763 } else {
1764 SCLogError("more than one run mode "
1765 "has been specified");
1766 PrintUsage(argv[0]);
1767 exit(EXIT_FAILURE);
1768 }
1769#else
1770 SCLogError("WinDivert not enabled. Make sure to pass --enable-windivert to "
1771 "configure when building.");
1772 return TM_ECODE_FAILED;
1773#endif /* WINDIVERT */
1774 } else if(strcmp((long_opts[option_index]).name, "reject-dev") == 0) {
1775#ifdef HAVE_LIBNET11
1776 BUG_ON(optarg == NULL); /* for static analysis */
1777 extern char *g_reject_dev;
1778 extern uint16_t g_reject_dev_mtu;
1779 g_reject_dev = optarg;
1780 int mtu = GetIfaceMTU(g_reject_dev);
1781 if (mtu > 0) {
1782 g_reject_dev_mtu = (uint16_t)mtu;
1783 }
1784#else
1785 SCLogError("Libnet 1.1 support not enabled. Compile Suricata with libnet support.");
1786 return TM_ECODE_FAILED;
1787#endif
1788 }
1789 else if (strcmp((long_opts[option_index]).name, "set") == 0) {
1790 if (optarg != NULL) {
1791 /* Quick validation. */
1792 char *val = strchr(optarg, '=');
1793 if (val == NULL) {
1794 FatalError("Invalid argument for --set, must be key=val.");
1795 }
1796 if (!SCConfSetFromString(optarg, 1)) {
1797 FatalError("failed to set configuration value %s", optarg);
1798 }
1799 }
1800 }
1801 else if (strcmp((long_opts[option_index]).name, "pcap-file-continuous") == 0) {
1802 if (SCConfSetFinal("pcap-file.continuous", "true") != 1) {
1803 SCLogError("Failed to set pcap-file.continuous");
1804 return TM_ECODE_FAILED;
1805 }
1806 }
1807 else if (strcmp((long_opts[option_index]).name, "pcap-file-delete") == 0) {
1808 if (SCConfSetFinal("pcap-file.delete-when-done", "true") != 1) {
1809 SCLogError("Failed to set pcap-file.delete-when-done");
1810 return TM_ECODE_FAILED;
1811 }
1812 }
1813 else if (strcmp((long_opts[option_index]).name, "pcap-file-recursive") == 0) {
1814 if (SCConfSetFinal("pcap-file.recursive", "true") != 1) {
1815 SCLogError("failed to set pcap-file.recursive");
1816 return TM_ECODE_FAILED;
1817 }
1818 } else if (strcmp((long_opts[option_index]).name, "pcap-file-buffer-size") == 0) {
1819 if (SCConfSetFinal("pcap-file.buffer-size", optarg) != 1) {
1820 SCLogError("failed to set pcap-file.buffer-size");
1821 return TM_ECODE_FAILED;
1822 }
1823 } else if (strcmp((long_opts[option_index]).name, "data-dir") == 0) {
1824 if (optarg == NULL) {
1825 SCLogError("no option argument (optarg) for -d");
1826 return TM_ECODE_FAILED;
1827 }
1828
1829 if (ConfigSetDataDirectory(optarg) != TM_ECODE_OK) {
1830 SCLogError("Failed to set data directory.");
1831 return TM_ECODE_FAILED;
1832 }
1833 if (ConfigCheckDataDirectory(optarg) != TM_ECODE_OK) {
1834 SCLogError("The data directory \"%s\""
1835 " supplied at the command-line (-d %s) doesn't "
1836 "exist. Shutting down the engine.",
1837 optarg, optarg);
1838 return TM_ECODE_FAILED;
1839 }
1840 suri->set_datadir = true;
1841 } else if (strcmp((long_opts[option_index]).name, "strict-rule-keywords") == 0) {
1842 if (optarg == NULL) {
1843 suri->strict_rule_parsing_string = SCStrdup("all");
1844 } else {
1845 suri->strict_rule_parsing_string = SCStrdup(optarg);
1846 }
1847 if (suri->strict_rule_parsing_string == NULL) {
1848 FatalError("failed to duplicate 'strict' string");
1849 }
1850 } else if (strcmp((long_opts[option_index]).name, "include") == 0) {
1851 if (suri->additional_configs == NULL) {
1852 suri->additional_configs = SCCalloc(2, sizeof(char *));
1853 if (suri->additional_configs == NULL) {
1854 FatalError(
1855 "Failed to allocate memory for additional configuration files: %s",
1856 strerror(errno));
1857 }
1858 suri->additional_configs[0] = optarg;
1859 } else {
1860 for (int i = 0;; i++) {
1861 if (suri->additional_configs[i] == NULL) {
1862 const char **additional_configs =
1863 SCRealloc(suri->additional_configs, (i + 2) * sizeof(char *));
1864 if (additional_configs == NULL) {
1865 FatalError("Failed to allocate memory for additional configuration "
1866 "files: %s",
1867 strerror(errno));
1868 } else {
1869 suri->additional_configs = additional_configs;
1870 }
1871 suri->additional_configs[i] = optarg;
1872 suri->additional_configs[i + 1] = NULL;
1873 break;
1874 }
1875 }
1876 }
1877 } else if (strcmp((long_opts[option_index]).name, "firewall-rules-exclusive") == 0) {
1878 if (suri->firewall_rule_file != NULL) {
1879 SCLogError("can't have multiple --firewall-rules-exclusive options");
1880 return TM_ECODE_FAILED;
1881 }
1882 suri->firewall_rule_file = optarg;
1883 suri->firewall_rule_file_exclusive = true;
1884 suri->is_firewall = true;
1885 } else {
1887 (long_opts[option_index]).name, optarg);
1888 if (r < 0)
1889 return TM_ECODE_FAILED;
1890 }
1891 break;
1892 case 'c':
1893 suri->conf_filename = optarg;
1894 break;
1895 case 'T':
1896 conf_test = 1;
1897 if (SCConfSetFinal("engine.init-failure-fatal", "1") != 1) {
1898 SCLogError("failed to set engine init-failure-fatal");
1899 return TM_ECODE_FAILED;
1900 }
1901 break;
1902#ifndef OS_WIN32
1903 case 'D':
1904 suri->daemon = 1;
1905 break;
1906#endif /* OS_WIN32 */
1907 case 'h':
1909 return TM_ECODE_OK;
1910 case 'i':
1911 if (optarg == NULL) {
1912 SCLogError("no option argument (optarg) for -i");
1913 return TM_ECODE_FAILED;
1914 }
1915#ifdef HAVE_AF_PACKET
1916 if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
1917 return TM_ECODE_FAILED;
1918 }
1919#else /* not afpacket */
1920 /* warn user if netmap is available */
1921#if defined HAVE_NETMAP
1922 int i = 0;
1923#ifdef HAVE_NETMAP
1924 i++;
1925#endif
1926 SCLogWarning("faster capture "
1927 "option%s %s available:"
1928#ifdef HAVE_NETMAP
1929 " NETMAP (--netmap=%s)"
1930#endif
1931 ". Use --pcap=%s to suppress this warning",
1932 i == 1 ? "" : "s", i == 1 ? "is" : "are"
1933#ifdef HAVE_NETMAP
1934 ,
1935 optarg
1936#endif
1937 ,
1938 optarg);
1939#endif /* have faster methods */
1940 if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
1941 return TM_ECODE_FAILED;
1942 }
1943#endif
1944 break;
1945 case 'l':
1946 if (optarg == NULL) {
1947 SCLogError("no option argument (optarg) for -l");
1948 return TM_ECODE_FAILED;
1949 }
1950
1951 if (ConfigSetLogDirectory(optarg) != TM_ECODE_OK) {
1952 SCLogError("Failed to set log directory.");
1953 return TM_ECODE_FAILED;
1954 }
1956 SCLogError("The logging directory \"%s\""
1957 " supplied at the command-line (-l %s) doesn't "
1958 "exist. Shutting down the engine.",
1959 optarg, optarg);
1960 return TM_ECODE_FAILED;
1961 }
1962 if (!IsLogDirectoryWritable(optarg)) {
1963 SCLogError("The logging directory \"%s\""
1964 " supplied at the command-line (-l %s) is not "
1965 "writable. Shutting down the engine.",
1966 optarg, optarg);
1967 return TM_ECODE_FAILED;
1968 }
1969 suri->set_logdir = true;
1970
1971 break;
1972 case 'q':
1973#ifdef NFQ
1974 if (suri->run_mode == RUNMODE_UNKNOWN) {
1975 suri->run_mode = RUNMODE_NFQ;
1977 if (NFQParseAndRegisterQueues(optarg) == -1)
1978 return TM_ECODE_FAILED;
1979 } else if (suri->run_mode == RUNMODE_NFQ) {
1980 if (NFQParseAndRegisterQueues(optarg) == -1)
1981 return TM_ECODE_FAILED;
1982 } else {
1983 SCLogError("more than one run mode "
1984 "has been specified");
1985 PrintUsage(argv[0]);
1986 return TM_ECODE_FAILED;
1987 }
1988#else
1989 SCLogError("NFQUEUE not enabled. Make sure to pass --enable-nfqueue to configure when "
1990 "building.");
1991 return TM_ECODE_FAILED;
1992#endif /* NFQ */
1993 break;
1994 case 'd':
1995#ifdef IPFW
1996 if (suri->run_mode == RUNMODE_UNKNOWN) {
1997 suri->run_mode = RUNMODE_IPFW;
1999 if (IPFWRegisterQueue(optarg) == -1)
2000 return TM_ECODE_FAILED;
2001 } else if (suri->run_mode == RUNMODE_IPFW) {
2002 if (IPFWRegisterQueue(optarg) == -1)
2003 return TM_ECODE_FAILED;
2004 } else {
2005 SCLogError("more than one run mode "
2006 "has been specified");
2007 PrintUsage(argv[0]);
2008 return TM_ECODE_FAILED;
2009 }
2010#else
2011 SCLogError("IPFW not enabled. Make sure to pass --enable-ipfw to configure when "
2012 "building.");
2013 return TM_ECODE_FAILED;
2014#endif /* IPFW */
2015 break;
2016 case 'r':
2017 BUG_ON(optarg == NULL); /* for static analysis */
2018 if (suri->run_mode == RUNMODE_UNKNOWN) {
2020 } else {
2021 SCLogError("more than one run mode "
2022 "has been specified");
2023 PrintUsage(argv[0]);
2024 return TM_ECODE_FAILED;
2025 }
2026 SCStat buf;
2027 if (SCStatFn(optarg, &buf) != 0) {
2028 SCLogError("pcap file '%s': %s", optarg, strerror(errno));
2029 return TM_ECODE_FAILED;
2030 }
2031 if (SCConfSetFinal("pcap-file.file", optarg) != 1) {
2032 SCLogError("ERROR: Failed to set pcap-file.file\n");
2033 return TM_ECODE_FAILED;
2034 }
2035
2036 break;
2037 case 's':
2038 if (suri->sig_file != NULL) {
2039 SCLogError("can't have multiple -s options or mix -s and -S.");
2040 return TM_ECODE_FAILED;
2041 }
2042 suri->sig_file = optarg;
2043 break;
2044 case 'S':
2045 if (suri->sig_file != NULL) {
2046 SCLogError("can't have multiple -S options or mix -s and -S.");
2047 return TM_ECODE_FAILED;
2048 }
2049 suri->sig_file = optarg;
2050 suri->sig_file_exclusive = true;
2051 break;
2052 case 'u':
2053#ifdef UNITTESTS
2054 if (suri->run_mode == RUNMODE_UNKNOWN) {
2055 suri->run_mode = RUNMODE_UNITTEST;
2056 } else {
2057 SCLogError("more than one run mode has"
2058 " been specified");
2059 PrintUsage(argv[0]);
2060 return TM_ECODE_FAILED;
2061 }
2062#else
2063 SCLogError("unit tests not enabled. Make sure to pass --enable-unittests to configure "
2064 "when building.");
2065 return TM_ECODE_FAILED;
2066#endif /* UNITTESTS */
2067 break;
2068 case 'U':
2069#ifdef UNITTESTS
2070 suri->regex_arg = optarg;
2071
2072 if(strlen(suri->regex_arg) == 0)
2073 suri->regex_arg = NULL;
2074#endif
2075 break;
2076 case 'V':
2078 return TM_ECODE_OK;
2079 case 'F':
2080 if (optarg == NULL) {
2081 SCLogError("no option argument (optarg) for -F");
2082 return TM_ECODE_FAILED;
2083 }
2084
2085 SetBpfStringFromFile(optarg);
2086 break;
2087 case 'v':
2088 suri->verbose++;
2089 break;
2090 case 'k':
2091 if (optarg == NULL) {
2092 SCLogError("no option argument (optarg) for -k");
2093 return TM_ECODE_FAILED;
2094 }
2095 if (!strcmp("all", optarg))
2096 suri->checksum_validation = 1;
2097 else if (!strcmp("none", optarg))
2098 suri->checksum_validation = 0;
2099 else {
2100 SCLogError("option '%s' invalid for -k", optarg);
2101 return TM_ECODE_FAILED;
2102 }
2103 break;
2104 default:
2105 PrintUsage(argv[0]);
2106 return TM_ECODE_FAILED;
2107 }
2108 }
2109
2110 if (is_firewall) {
2111 suri->is_firewall = true;
2112 }
2113
2114 if (suri->disabled_detect && (suri->sig_file != NULL || suri->firewall_rule_file != NULL)) {
2115 SCLogError("can't use -s/-S or --firewall-rules-exclusive when detection is disabled");
2116 return TM_ECODE_FAILED;
2117 }
2118
2119 /* save the runmode from the command-line (if any) */
2120 suri->aux_run_mode = suri->run_mode;
2121
2122 if (list_app_layer_protocols)
2124 if (list_app_layer_hooks)
2126 if (list_keywords)
2128 if (list_unittests)
2130 if (dump_config)
2132 if (dump_features)
2134 if (conf_test)
2136 if (engine_analysis)
2138
2139 suri->offline = IsRunModeOffline(suri->run_mode);
2140 g_system = suri->system = IsRunModeSystem(suri->run_mode);
2141
2142 ret = SetBpfString(optind, argv);
2143 if (ret != TM_ECODE_OK)
2144 return ret;
2145
2146 return TM_ECODE_OK;
2147}
2148
2149#ifdef OS_WIN32
2150int WindowsInitService(int argc, char **argv)
2151{
2152 if (SCRunningAsService()) {
2153 char path[MAX_PATH];
2154 char *p = NULL;
2155 strlcpy(path, argv[0], MAX_PATH);
2156 if ((p = strrchr(path, '\\'))) {
2157 *p = '\0';
2158 }
2159 if (!SetCurrentDirectory(path)) {
2160 SCLogError("Can't set current directory to: %s", path);
2161 return -1;
2162 }
2163 SCLogInfo("Current directory is set to: %s", path);
2164 SCServiceInit(argc, argv);
2165 }
2166
2167 /* Windows socket subsystem initialization */
2168 WSADATA wsaData;
2169 if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) {
2170 SCLogError("Can't initialize Windows sockets: %d", WSAGetLastError());
2171 return -1;
2172 }
2173
2174 return 0;
2175}
2176#endif /* OS_WIN32 */
2177
2178static int MayDaemonize(SCInstance *suri)
2179{
2180 if (suri->daemon == 1 && suri->pid_filename == NULL) {
2181 const char *pid_filename;
2182
2183 if (SCConfGet("pid-file", &pid_filename) == 1) {
2184 SCLogInfo("Use pid file %s from config file.", pid_filename);
2185 } else {
2186 pid_filename = DEFAULT_PID_FILENAME;
2187 }
2188 /* The pid file name may be in config memory, but is needed later. */
2189 suri->pid_filename = SCStrdup(pid_filename);
2190 if (suri->pid_filename == NULL) {
2191 SCLogError("strdup failed: %s", strerror(errno));
2192 return TM_ECODE_FAILED;
2193 }
2194 }
2195
2196 if (suri->pid_filename != NULL && SCPidfileTestRunning(suri->pid_filename) != 0) {
2197 SCFree(suri->pid_filename);
2198 suri->pid_filename = NULL;
2199 return TM_ECODE_FAILED;
2200 }
2201
2202 if (suri->daemon == 1) {
2203 Daemonize();
2204 }
2205
2206 if (suri->pid_filename != NULL) {
2207 if (SCPidfileCreate(suri->pid_filename) != 0) {
2208 SCFree(suri->pid_filename);
2209 suri->pid_filename = NULL;
2210 SCLogError("Unable to create PID file, concurrent run of"
2211 " Suricata can occur.");
2212 SCLogError("PID file creation WILL be mandatory for daemon mode"
2213 " in future version");
2214 }
2215 }
2216
2217 return TM_ECODE_OK;
2218}
2219
2220/* Initialize the user and group Suricata is to run as. */
2221static int InitRunAs(SCInstance *suri)
2222{
2223#ifndef OS_WIN32
2224 /* Try to get user/group to run suricata as if
2225 command line as not decide of that */
2226 if (!suri->do_setuid && !suri->do_setgid) {
2227 const char *id;
2228 if (SCConfGet("run-as.user", &id) == 1) {
2229 suri->do_setuid = true;
2230 suri->user_name = id;
2231 }
2232 if (SCConfGet("run-as.group", &id) == 1) {
2233 suri->do_setgid = true;
2234 suri->group_name = id;
2235 }
2236 }
2237 /* Get the suricata user ID to given user ID */
2238 if (suri->do_setuid) {
2239 SCGetUserID(suri->user_name, suri->group_name, &suri->userid, &suri->groupid);
2240 sc_set_caps = true;
2241 /* Get the suricata group ID to given group ID */
2242 } else if (suri->do_setgid) {
2243 SCGetGroupID(suri->group_name, &suri->groupid);
2244 sc_set_caps = true;
2245 }
2246#endif
2247 return TM_ECODE_OK;
2248}
2249
2250static int InitSignalHandler(SCInstance *suri)
2251{
2252 /* registering signals we use */
2253#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2254 UtilSignalHandlerSetup(SIGINT, SignalHandlerSigint);
2255 UtilSignalHandlerSetup(SIGTERM, SignalHandlerSigterm);
2256#if HAVE_LIBUNWIND
2257 int enabled;
2258 if (SCConfGetBool("logging.stacktrace-on-signal", &enabled) == 0) {
2259 enabled = 1;
2260 }
2261
2262 if (enabled) {
2263 SCLogInfo("Preparing unexpected signal handling");
2264 struct sigaction stacktrace_action;
2265 memset(&stacktrace_action, 0, sizeof(stacktrace_action));
2266 stacktrace_action.sa_sigaction = SignalHandlerUnexpected;
2267 stacktrace_action.sa_flags = SA_SIGINFO;
2268 sigaction(SIGSEGV, &stacktrace_action, NULL);
2269 sigaction(SIGABRT, &stacktrace_action, NULL);
2270 }
2271#endif /* HAVE_LIBUNWIND */
2272#endif
2273#ifndef OS_WIN32
2274 UtilSignalHandlerSetup(SIGHUP, SignalHandlerSigHup);
2275 UtilSignalHandlerSetup(SIGPIPE, SIG_IGN);
2276 UtilSignalHandlerSetup(SIGSYS, SIG_IGN);
2277#endif /* OS_WIN32 */
2278
2279 return TM_ECODE_OK;
2280}
2281
2282/* initialization code for both the main modes and for
2283 * unix socket mode.
2284 *
2285 * Will be run once per pcap in unix-socket mode */
2286void PreRunInit(const int runmode)
2287{
2288 if (runmode == RUNMODE_UNIX_SOCKET)
2289 return;
2290
2291 StatsInit();
2292#ifdef PROFILE_RULES
2293 SCProfilingRulesGlobalInit();
2294#endif
2295#ifdef PROFILING
2299#endif /* PROFILING */
2300#ifdef PROFILE_RULES
2302#endif
2303 DefragInit();
2311}
2312
2313/* tasks we need to run before packets start flowing,
2314 * but after we dropped privs */
2315void PreRunPostPrivsDropInit(const int runmode)
2316{
2317 if (runmode == RUNMODE_UNIX_SOCKET) {
2318 return;
2319 }
2320
2323 DatasetsInit();
2325}
2326
2327/** \brief clean up / shutdown code for packet modes
2328 *
2329 * Shuts down packet modes, so regular packet runmodes and the
2330 * per pcap mode in the unix socket. */
2331void PostRunDeinit(const int runmode, struct timeval *start_time)
2332{
2333 if (runmode == RUNMODE_UNIX_SOCKET)
2334 return;
2335
2337
2338 /* needed by FlowWorkToDoCleanup */
2340
2341 /* handle graceful shutdown of the flow engine, it's helper
2342 * threads and the packet threads */
2344 /* disable capture */
2346 /* tell relevant packet threads to enter flow timeout loop */
2349 /* run cleanup on the flow hash */
2351 /* gracefully shut down all packet threads */
2353 SCPrintElapsedTime(start_time);
2355
2356 /* kill the stats threads */
2359
2360 /* kill packet threads -- already in 'disabled' state */
2363
2365
2366 /* mgt and ppt threads killed, we can run non thread-safe
2367 * shutdown functions */
2371 FlowShutdown();
2373 HostCleanup();
2375 DefragDestroy();
2377#ifdef HAVE_HWLOC
2379#endif /* HAVE_HWLOC */
2380
2382#ifdef PROFILING
2386#endif
2387}
2388
2389int SCStartInternalRunMode(int argc, char **argv)
2390{
2391 SCInstance *suri = &suricata;
2392 /* Treat internal running mode */
2393 switch (suri->run_mode) {
2395 return ListKeywords(suri->keyword_info);
2397 if (suri->conf_filename != NULL) {
2399 } else {
2401 }
2403 if (suri->conf_filename != NULL) {
2404 return ListAppLayerHooks(suri->conf_filename);
2405 } else {
2407 }
2409 PrintVersion();
2410 return TM_ECODE_DONE;
2412 PrintBuildInfo();
2413 return TM_ECODE_DONE;
2415 PrintUsage(argv[0]);
2416 return TM_ECODE_DONE;
2419 return TM_ECODE_DONE;
2421 RunUnittests(1, suri->regex_arg);
2422 case RUNMODE_UNITTEST:
2423 RunUnittests(0, suri->regex_arg);
2424#ifdef OS_WIN32
2425 case RUNMODE_INSTALL_SERVICE:
2426 if (SCServiceInstall(argc, argv)) {
2427 return TM_ECODE_FAILED;
2428 }
2429 SCLogInfo("Suricata service has been successfully installed.");
2430 return TM_ECODE_DONE;
2431 case RUNMODE_REMOVE_SERVICE:
2432 if (SCServiceRemove()) {
2433 return TM_ECODE_FAILED;
2434 }
2435 SCLogInfo("Suricata service has been successfully removed.");
2436 return TM_ECODE_DONE;
2437 case RUNMODE_CHANGE_SERVICE_PARAMS:
2438 if (SCServiceChangeParams(argc, argv)) {
2439 return TM_ECODE_FAILED;
2440 }
2441 SCLogInfo("Suricata service startup parameters has been successfully changed.");
2442 return TM_ECODE_DONE;
2443#endif /* OS_WIN32 */
2444 default:
2445 /* simply continue for other running mode */
2446 break;
2447 }
2448 return TM_ECODE_OK;
2449}
2450
2452{
2453 SCInstance *suri = &suricata;
2454 switch (suri->run_mode) {
2455 case RUNMODE_UNKNOWN:
2456 PrintUsage(suri->progname);
2457 return TM_ECODE_FAILED;
2458 default:
2459 break;
2460 }
2461
2462 if (!CheckValidDaemonModes(suri->daemon, suri->run_mode)) {
2463 return TM_ECODE_FAILED;
2464 }
2465
2466 return TM_ECODE_OK;
2467}
2468
2469static void SetupDelayedDetect(SCInstance *suri)
2470{
2471 /* In offline mode delayed init of detect is a bad idea */
2472 if (suri->offline) {
2473 suri->delayed_detect = 0;
2474 } else {
2475 if (SCConfGetBool("detect.delayed-detect", &suri->delayed_detect) != 1) {
2476 SCConfNode *denode = NULL;
2477 SCConfNode *decnf = SCConfGetNode("detect-engine");
2478 if (decnf != NULL) {
2479 TAILQ_FOREACH(denode, &decnf->head, next) {
2480 if (strcmp(denode->val, "delayed-detect") == 0) {
2482 denode, "delayed-detect", &suri->delayed_detect);
2483 }
2484 }
2485 }
2486 }
2487 }
2488
2489 SCLogConfig("Delayed detect %s", suri->delayed_detect ? "enabled" : "disabled");
2490 if (suri->delayed_detect) {
2491 SCLogInfo("Packets will start being processed before signatures are active.");
2492 }
2493
2494}
2495
2496static int LoadSignatures(DetectEngineCtx *de_ctx, SCInstance *suri)
2497{
2499
2500 if (SigLoadSignatures(de_ctx, suri->sig_file, suri->sig_file_exclusive) < 0) {
2501 SCLogError("Loading signatures failed.");
2502 if (de_ctx->failure_fatal)
2503 return TM_ECODE_FAILED;
2504 }
2505
2506 return TM_ECODE_OK;
2507}
2508
2509static int ConfigGetCaptureValue(SCInstance *suri)
2510{
2511 /* Pull the max pending packets from the config, if not found fall
2512 * back on a sane default. */
2513 intmax_t tmp_max_pending_packets;
2514 if (SCConfGetInt("max-pending-packets", &tmp_max_pending_packets) != 1)
2515 tmp_max_pending_packets = DEFAULT_MAX_PENDING_PACKETS;
2516 if (tmp_max_pending_packets < 1 || tmp_max_pending_packets > 2147483648) {
2517 SCLogError("Maximum max-pending-packets setting is 2147483648 and must be greater than 0. "
2518 "Please check %s for errors",
2519 suri->conf_filename);
2520 return TM_ECODE_FAILED;
2521 } else {
2522 max_pending_packets = (uint32_t)tmp_max_pending_packets;
2523 }
2524
2525 SCLogDebug("Max pending packets set to %" PRIu32, max_pending_packets);
2526
2527 /* Pull the default packet size from the config, if not found fall
2528 * back on a sane default. */
2529 const char *temp_default_packet_size;
2530 if ((SCConfGet("default-packet-size", &temp_default_packet_size)) != 1) {
2531 int lthread;
2532 int nlive;
2533 int strip_trailing_plus = 0;
2534 switch (suri->run_mode) {
2535 case RUNMODE_AFP_DEV:
2536 /* For AF_PACKET we delay setting the
2537 * default-packet-size until we know more about the
2538 * configuration. */
2539 break;
2540#ifdef WINDIVERT
2541 case RUNMODE_WINDIVERT: {
2542 /* by default, WinDivert collects from all devices */
2543 const int mtu = GetGlobalMTUWin32();
2544
2545 if (mtu > 0) {
2546 /* SLL_HEADER_LEN is the longest header + 8 for VLAN */
2548 break;
2549 }
2551 break;
2552 }
2553#endif /* WINDIVERT */
2554 case RUNMODE_NETMAP:
2555 /* in netmap igb0+ has a special meaning, however the
2556 * interface really is igb0 */
2557 strip_trailing_plus = 1;
2558 /* fall through */
2559 case RUNMODE_PLUGIN:
2560 case RUNMODE_PCAP_DEV:
2561 case RUNMODE_AFXDP_DEV:
2562 nlive = LiveGetDeviceCount();
2563 for (lthread = 0; lthread < nlive; lthread++) {
2564 const char *live_dev = LiveGetDeviceName(lthread);
2565 char dev[128]; /* need to be able to support GUID names on Windows */
2566 (void)strlcpy(dev, live_dev, sizeof(dev));
2567
2568 if (strip_trailing_plus) {
2569 size_t len = strlen(dev);
2570 if (len &&
2571 (dev[len-1] == '+' ||
2572 dev[len-1] == '^' ||
2573 dev[len-1] == '*'))
2574 {
2575 dev[len-1] = '\0';
2576 }
2577 }
2578 LiveDevice *ld = LiveGetDevice(dev);
2579 unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(ld);
2580 if (iface_max_packet_size > default_packet_size)
2581 default_packet_size = iface_max_packet_size;
2582 }
2584 break;
2585 /* fall through */
2586 default:
2588 }
2589 } else {
2590 if (ParseSizeStringU32(temp_default_packet_size, &default_packet_size) < 0) {
2591 SCLogError("Error parsing max-pending-packets "
2592 "from conf file - %s. Killing engine",
2593 temp_default_packet_size);
2594 return TM_ECODE_FAILED;
2595 }
2596 }
2597
2598 SCLogDebug("Default packet size set to %"PRIu32, default_packet_size);
2599
2600 return TM_ECODE_OK;
2601}
2602
2603static void PostRunStartedDetectSetup(const SCInstance *suri)
2604{
2605#ifndef OS_WIN32
2606 /* registering signal handlers we use. We setup usr2 here, so that one
2607 * can't call it during the first sig load phase or while threads are still
2608 * starting up. */
2609 if (DetectEngineEnabled() && suri->delayed_detect == 0) {
2610 UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
2611 UtilSignalUnblock(SIGUSR2);
2612 }
2613#endif
2614 if (suri->delayed_detect) {
2615 /* force 'reload', this will load the rules and swap engines */
2616 DetectEngineReload(suri);
2617 SCLogNotice("Signature(s) loaded, Detect thread(s) activated.");
2618#ifndef OS_WIN32
2619 UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
2620 UtilSignalUnblock(SIGUSR2);
2621#endif
2622 }
2623}
2624
2626{
2627 DetectEngineCtx *de_ctx = NULL;
2628 if (!suri->disabled_detect) {
2629 SetupDelayedDetect(suri);
2630 int mt_enabled = 0;
2631 (void)SCConfGetBool("multi-detect.enabled", &mt_enabled);
2632 int default_tenant = 0;
2633 if (mt_enabled)
2634 (void)SCConfGetBool("multi-detect.default", &default_tenant);
2636 FatalError("initializing multi-detect "
2637 "detection engine contexts failed.");
2638 }
2639 if (suri->delayed_detect && suri->run_mode != RUNMODE_CONF_TEST) {
2641 } else if (mt_enabled && !default_tenant && suri->run_mode != RUNMODE_CONF_TEST) {
2643 } else {
2645 }
2646 if (de_ctx == NULL) {
2647 FatalError("initializing detection engine failed.");
2648 }
2649
2651 if (LoadSignatures(de_ctx, suri) != TM_ECODE_OK)
2652 exit(EXIT_FAILURE);
2653 }
2654
2655 gettimeofday(&de_ctx->last_reload, NULL);
2658 }
2659}
2660
2661static void PostConfLoadedSetupHostMode(void)
2662{
2663 const char *hostmode = NULL;
2664
2665 if (SCConfGet("host-mode", &hostmode) == 1) {
2666 if (!strcmp(hostmode, "router")) {
2668 } else if (!strcmp(hostmode, "sniffer-only")) {
2670 } else {
2671 if (strcmp(hostmode, "auto") != 0) {
2672 WarnInvalidConfEntry("host-mode", "%s", "auto");
2673 }
2674 if (EngineModeIsIPS()) {
2676 } else {
2678 }
2679 }
2680 } else {
2681 if (EngineModeIsIPS()) {
2683 SCLogInfo("No 'host-mode': suricata is in IPS mode, using "
2684 "default setting 'router'");
2685 } else {
2687 SCLogInfo("No 'host-mode': suricata is in IDS mode, using "
2688 "default setting 'sniffer-only'");
2689 }
2690 }
2691}
2692
2693static void SetupUserMode(SCInstance *suri)
2694{
2695 /* apply 'user mode' config updates here */
2696 if (!suri->system) {
2697 if (!suri->set_logdir) {
2698 /* override log dir to current work dir" */
2699 if (ConfigSetLogDirectory((char *)".") != TM_ECODE_OK) {
2700 FatalError("could not set USER mode logdir");
2701 }
2702 }
2703 if (!suri->set_datadir) {
2704 /* override data dir to current work dir" */
2705 if (ConfigSetDataDirectory((char *)".") != TM_ECODE_OK) {
2706 FatalError("could not set USER mode datadir");
2707 }
2708 }
2709 }
2710}
2711
2712/**
2713 * This function is meant to contain code that needs
2714 * to be run once the configuration has been loaded.
2715 */
2717{
2718 int cnf_firewall_enabled = 0;
2719 if (SCConfGetBool("firewall.enabled", &cnf_firewall_enabled) == 1) {
2720 if (cnf_firewall_enabled == 1) {
2721 suri->is_firewall = true;
2722 } else {
2723 if (suri->is_firewall) {
2724 FatalError("firewall mode enabled through commandline, but disabled in config");
2725 }
2726 }
2727 }
2728 if (suri->is_firewall) {
2729 SCLogWarning("firewall mode is EXPERIMENTAL and subject to change");
2731 }
2732
2733 /* load the pattern matchers */
2734 MpmTableSetup();
2735 SpmTableSetup();
2736
2737 int disable_offloading;
2738 if (SCConfGetBool("capture.disable-offloading", &disable_offloading) == 0)
2739 disable_offloading = 1;
2740 if (disable_offloading) {
2742 } else {
2744 }
2745
2746 if (suri->checksum_validation == -1) {
2747 const char *cv = NULL;
2748 if (SCConfGet("capture.checksum-validation", &cv) == 1) {
2749 if (strcmp(cv, "none") == 0) {
2750 suri->checksum_validation = 0;
2751 } else if (strcmp(cv, "all") == 0) {
2752 suri->checksum_validation = 1;
2753 }
2754 }
2755 }
2756 switch (suri->checksum_validation) {
2757 case 0:
2758 SCConfSet("stream.checksum-validation", "0");
2759 break;
2760 case 1:
2761 SCConfSet("stream.checksum-validation", "1");
2762 break;
2763 }
2764
2765 if (suri->runmode_custom_mode) {
2766 SCConfSet("runmode", suri->runmode_custom_mode);
2767 }
2768
2769 StorageInit();
2770#ifdef HAVE_PACKET_EBPF
2771 if (suri->run_mode == RUNMODE_AFP_DEV) {
2772 EBPFRegisterExtension();
2774 }
2775#endif
2777
2780
2781 SigTableInit();
2782
2783#ifdef HAVE_PLUGINS
2785#endif
2786
2787 LiveDeviceFinalize(); // must be after EBPF extension registration
2788
2791 FatalError("IPS mode setup failed");
2792 }
2793
2794 if (EngineModeIsUnknown()) { // if still uninitialized, set the default
2795 SCLogInfo("Setting engine mode to IDS mode by default");
2797 }
2798
2800
2801 SCConfNode *eps = SCConfGetNode("stats.exception-policy");
2802 if (eps != NULL) {
2803 if (SCConfNodeChildValueIsTrue(eps, "per-app-proto-errors")) {
2805 }
2806 }
2807
2808 /* Must occur prior to output mod registration
2809 and app layer setup. */
2811
2812 AppLayerSetup();
2813
2814 /* Suricata will use this umask if provided. By default it will use the
2815 umask passed on from the shell. */
2816 const char *custom_umask;
2817 if (SCConfGet("umask", &custom_umask) == 1) {
2818 uint16_t mask;
2819 if (StringParseUint16(&mask, 8, (uint16_t)strlen(custom_umask), custom_umask) > 0) {
2820 umask((mode_t)mask);
2821 }
2822 }
2823
2824 if (ConfigGetCaptureValue(suri) != TM_ECODE_OK) {
2826 }
2827
2828#ifdef NFQ
2829 if (suri->run_mode == RUNMODE_NFQ)
2830 NFQInitConfig(false);
2831#endif
2832
2833 /* Load the Host-OS lookup. */
2835
2836 if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) {
2837 SCLogInfo("== Carrying out Engine Analysis ==");
2838 const char *temp = NULL;
2839 if (SCConfGet("engine-analysis", &temp) == 0) {
2840 SCLogInfo("no engine-analysis parameter(s) defined in conf file. "
2841 "Please define/enable them in the conf to use this "
2842 "feature.");
2844 }
2845 }
2846
2847 /* hardcoded initialization code */
2848 SigTableSetup(); /* load the rule keywords */
2850 TmqhSetup();
2851
2852 TagInitCtx();
2854 ThresholdInit();
2857
2858 if (DetectAddressTestConfVars() < 0) {
2859 SCLogError(
2860 "basic address vars test failed. Please check %s for errors", suri->conf_filename);
2862 }
2863 if (DetectPortTestConfVars() < 0) {
2864 SCLogError("basic port vars test failed. Please check %s for errors", suri->conf_filename);
2866 }
2867
2870
2872
2874
2875 if (MayDaemonize(suri) != TM_ECODE_OK)
2877
2878 if (suri->install_signal_handlers) {
2879 if (InitSignalHandler(suri) != TM_ECODE_OK)
2881 }
2882
2883 /* Check for the existence of the default logging directory which we pick
2884 * from suricata.yaml. If not found, shut the engine down */
2886
2888 SCLogError("The logging directory \"%s\" "
2889 "supplied by %s (default-log-dir) doesn't exist. "
2890 "Shutting down the engine",
2891 suri->log_dir, suri->conf_filename);
2893 }
2894 if (!IsLogDirectoryWritable(suri->log_dir)) {
2895 SCLogError("The logging directory \"%s\" "
2896 "supplied by %s (default-log-dir) is not writable. "
2897 "Shutting down the engine",
2898 suri->log_dir, suri->conf_filename);
2900 }
2901
2902 if (suri->disabled_detect) {
2903 SCLogConfig("detection engine disabled");
2904 /* disable raw reassembly */
2905 (void)SCConfSetFinal("stream.reassembly.raw", "false");
2906 }
2907
2909
2911
2913
2914 /* hostmode depends on engine mode being set */
2915 PostConfLoadedSetupHostMode();
2916
2917 PreRunInit(suri->run_mode);
2918
2920}
2921
2923{
2924 SCInstance *suri = &suricata;
2925 while(1) {
2926 if (sigterm_count || sigint_count) {
2928 }
2929
2931 SCLogNotice("Signal Received. Stopping engine.");
2932 break;
2933 }
2934
2936
2937 if (sighup_count > 0) {
2939 sighup_count--;
2940 }
2941
2942 if (sigusr2_count > 0) {
2943 if (!(DetectEngineReloadIsStart())) {
2945 DetectEngineReload(suri);
2947 sigusr2_count--;
2948 }
2949
2950 } else if (DetectEngineReloadIsStart()) {
2951 DetectEngineReload(suri);
2953 }
2954
2955 usleep(10* 1000);
2956 }
2957}
2958
2959/**
2960 * \brief Global initialization common to all runmodes.
2961 *
2962 * This can be used by fuzz targets.
2963 */
2964
2965int InitGlobal(void)
2966{
2967 SCRustInit(&suricata_context);
2968
2969 SC_ATOMIC_INIT(engine_stage);
2970
2971 /* initialize the logging subsys */
2972 SCLogInitLogModule(NULL);
2973
2974 SCSetThreadName("Suricata-Main");
2975
2976 /* Ignore SIGUSR2 as early as possible. We redeclare interest
2977 * once we're done launching threads. The goal is to either die
2978 * completely or handle any and all SIGUSR2s correctly.
2979 */
2980#ifndef OS_WIN32
2981 UtilSignalHandlerSetup(SIGUSR2, SIG_IGN);
2982 if (UtilSignalBlock(SIGUSR2)) {
2983 SCLogError("SIGUSR2 initialization error");
2984 return EXIT_FAILURE;
2985 }
2986#endif
2987
2988 ParseSizeInit();
2990
2991 /* Initialize the configuration module. */
2992 SCConfInit();
2994
2996
2997 // zero all module storage
2998 memset(tmm_modules, 0, TMM_SIZE * sizeof(TmModule));
2999
3000 return 0;
3001}
3002
3003void SuricataPreInit(const char *progname)
3004{
3005 SCInstanceInit(&suricata, progname);
3006
3007 if (InitGlobal() != 0) {
3008 exit(EXIT_FAILURE);
3009 }
3010}
3011
3013{
3014 /* Initializations for global vars, queues, etc (memsets, mutex init..) */
3016
3018 SCConfDump();
3019 exit(EXIT_SUCCESS);
3020 }
3021
3022 int tracking = 1;
3023 if (SCConfGetBool("vlan.use-for-tracking", &tracking) == 1 && !tracking) {
3024 /* Ignore vlan_ids when comparing flows. */
3025 g_vlan_mask = 0x0000;
3026 }
3027 SCLogDebug("vlan tracking is %s", tracking == 1 ? "enabled" : "disabled");
3028 if (SCConfGetBool("livedev.use-for-tracking", &tracking) == 1 && !tracking) {
3029 /* Ignore livedev id when comparing flows. */
3030 g_livedev_mask = 0x0000;
3031 }
3032 if (SCConfGetBool("decoder.recursion-level.use-for-tracking", &tracking) == 1 && !tracking) {
3033 /* Ignore recursion level when comparing flows. */
3034 g_recurlvl_mask = 0x00;
3035 }
3036 SetupUserMode(&suricata);
3037 InitRunAs(&suricata);
3038
3039 /* Since our config is now loaded we can finish configurating the
3040 * logging module. */
3042
3043 LogVersion(&suricata);
3046
3048 SCLogInfo("Running suricata under test mode");
3049
3050 if (ParseInterfacesList(suricata.aux_run_mode, suricata.pcap_dev) != TM_ECODE_OK) {
3051 exit(EXIT_FAILURE);
3052 }
3053
3055 exit(EXIT_FAILURE);
3056 }
3057
3059
3060 /* Re-enable coredumps after privileges are dropped. */
3062
3065 }
3066
3068
3070
3072
3075 goto out;
3076 } else if (suricata.run_mode == RUNMODE_CONF_TEST){
3077 SCLogNotice("Configuration provided was successfully loaded. Exiting.");
3078 goto out;
3079 } else if (suricata.run_mode == RUNMODE_DUMP_FEATURES) {
3080 FeatureDump();
3081 goto out;
3082 }
3083
3086
3087 SCSetStartTime(&suricata);
3090 }
3093 return;
3094
3095out:
3097 exit(EXIT_SUCCESS);
3098}
3099
3101{
3102 /* Update the engine stage/status flag */
3103 SC_ATOMIC_SET(engine_stage, SURICATA_DEINIT);
3104
3107 /* kill remaining threads */
3109}
3110
3112{
3113 /* Wait till all the threads have been initialized */
3116 FatalError("Engine initialization failed, "
3117 "aborting...");
3118 }
3119
3120 int limit_nproc = 0;
3121 if (SCConfGetBool("security.limit-noproc", &limit_nproc) == 0) {
3122 limit_nproc = 0;
3123 }
3124
3125#if defined(SC_ADDRESS_SANITIZER)
3126 if (limit_nproc) {
3128 "\"security.limit-noproc\" (setrlimit()) not set when using address sanitizer");
3129 limit_nproc = 0;
3130 }
3131#endif
3132
3133 if (limit_nproc) {
3134#if defined(HAVE_SYS_RESOURCE_H)
3135#ifdef linux
3136 if (geteuid() == 0) {
3137 SCLogWarning("setrlimit has no effect when running as root.");
3138 }
3139#endif
3140 struct rlimit r = { 0, 0 };
3141 if (setrlimit(RLIMIT_NPROC, &r) != 0) {
3142 SCLogWarning("setrlimit failed to prevent process creation.");
3143 }
3144#else
3145 SCLogWarning("setrlimit unavailable.");
3146#endif
3147 }
3148
3149 SC_ATOMIC_SET(engine_stage, SURICATA_RUNTIME);
3151
3152 /* Un-pause all the paused threads */
3154
3155 /* Must ensure all threads are fully operational before continuing with init process */
3158 exit(EXIT_FAILURE);
3159 }
3160
3161 /* Print notice and send OS specific notification of threads in running state */
3162 OnNotifyRunning();
3163
3164 PostRunStartedDetectSetup(&suricata);
3165 if (suricata.run_mode == RUNMODE_DPDK) { // only DPDK uses hpages at the moment
3169 SystemHugepageSnapshotDestroy(postrun_snap);
3170 }
3171 SCPledge();
3172}
uint8_t len
void HttpRangeContainersDestroy(void)
void HttpRangeContainersInit(void)
struct HtpBodyChunk_ * next
void AppLayerParserPostStreamSetup(void)
int AppLayerSetup(void)
Setup the app layer.
Definition app-layer.c:1078
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition app-layer.c:1159
int AppLayerDeSetup(void)
De initializes the app layer.
Definition app-layer.c:1095
int SCConfYamlLoadFile(const char *filename)
Load configuration from a YAML file.
int SCConfYamlHandleInclude(SCConfNode *parent, const char *filename)
Include a file in the configuration.
void SCConfInit(void)
Initialize the configuration system.
Definition conf.c:120
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
Definition conf.c:181
int SCConfNodeChildValueIsTrue(const SCConfNode *node, const char *key)
Test if a configuration node has a true value.
Definition conf.c:868
void SCConfDeInit(void)
De-initializes the configuration system.
Definition conf.c:703
void SCConfDump(void)
Dump configuration to stdout.
Definition conf.c:761
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition conf.c:414
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition conf.c:318
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition conf.c:497
int SCConfGetChildValueBool(const SCConfNode *base, const char *name, int *val)
Definition conf.c:515
int SCConfSet(const char *name, const char *val)
Set a configuration value.
Definition conf.c:239
SCConfNode * SCConfGetRootNode(void)
Get the root configuration node.
Definition conf.c:222
int SCConfSetFromString(const char *input, int final)
Set a configuration parameter from a string.
Definition conf.c:264
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition conf.c:350
void StatsInit(void)
Initializes the perf counter api. Things are hard coded currently. More work to be done when we imple...
Definition counters.c:876
void StatsSetupPostConfigPostOutput(void)
Definition counters.c:891
void StatsReleaseResources(void)
Releases the resources allotted by the Stats API.
Definition counters.c:1267
void StatsSetupPostConfigPreOutput(void)
Definition counters.c:886
void DatasetsSave(void)
Definition datasets.c:852
int DatasetsInit(void)
Definition datasets.c:622
void DatasetsDestroy(void)
Definition datasets.c:774
#define SLL_HEADER_LEN
Definition decode-sll.h:27
#define DEFAULT_PACKET_SIZE
Definition decode.h:699
void DefragInit(void)
Definition defrag.c:1109
void DefragDestroy(void)
Definition defrag.c:1129
int DetectAddressTestConfVars(void)
void PacketAlertTagInit(void)
int SigLoadSignatures(DetectEngineCtx *de_ctx, char *sig_file, bool sig_file_exclusive)
Load signatures.
int engine_analysis
int DetectPortTestConfVars(void)
void SigTableSetup(void)
void SigTableCleanup(void)
void SigTableInit(void)
DetectEngineCtx * DetectEngineCtxInit(void)
void TagDestroyCtx(void)
Destroy tag context hash tables.
void TagInitCtx(void)
int DetectEngineReload(const SCInstance *suri)
Reload the detection engine.
int DetectEngineMoveToFreeList(DetectEngineCtx *de_ctx)
void DetectEngineBumpVersion(void)
DetectEngineCtx * DetectEngineCtxInitStubForMT(void)
DetectEngineCtx * DetectEngineCtxInitStubForDD(void)
int DetectEngineReloadIsStart(void)
void DetectEngineClearMaster(void)
void DetectEngineDeReference(DetectEngineCtx **de_ctx)
void DetectEngineReloadSetIdle(void)
int DetectEngineReloadStart(void)
int DetectEngineAddToMaster(DetectEngineCtx *de_ctx)
int DetectEngineEnabled(void)
Check if detection is enabled.
DetectEngineCtx * DetectEngineGetCurrent(void)
int DetectEngineMultiTenantSetup(const bool unix_socket)
setup multi-detect / multi-tenancy
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
uint32_t id
void DetectParseFreeRegexes(void)
void SigTableApplyStrictCommandLineOption(const char *str)
@ DETECT_ENGINE_TYPE_NORMAL
Definition detect.h:902
void FeatureDump(void)
Definition feature.c:144
void FeatureTrackingRegister(void)
Definition feature.c:152
void FeatureTrackingRelease(void)
Definition feature.c:136
void TmModuleBypassedFlowManagerRegister(void)
void TmModuleFlowRecyclerRegister(void)
void FlowDisableFlowManagerThread(void)
Used to disable flow manager thread(s).
void TmModuleFlowManagerRegister(void)
void FlowDisableFlowRecyclerThread(void)
Used to disable flow recycler thread(s).
void FlowWorkToDoCleanup(void)
Clean up all the flows that have unprocessed segments and have some work to do in the detection engin...
void RegisterFlowBypassInfo(void)
Definition flow-util.c:240
void TmModuleFlowWorkerRegister(void)
void FlowInitConfig(bool quiet)
initialize the configuration
Definition flow.c:547
void FlowShutdown(void)
shutdown the flow engine
Definition flow.c:691
#define FLOW_QUIET
Definition flow.h:43
DetectEngineCtx * de_ctx
int unittests_fatal
void TmModuleReceiveAFPRegister(void)
Registration Function for RecieveAFP.
uint32_t max_pending_packets
Definition suricata.c:183
void TmModuleDecodeAFPRegister(void)
Registration Function for DecodeAFP.
void AFPPeersListClean(void)
Clean the global peers list.
void TmModuleReceiveAFXDPRegister(void)
void TmModuleDecodeAFXDPRegister(void)
Registration Function for DecodeAFXDP.
uint32_t default_packet_size
Definition decode.c:77
void DecodeUnregisterCounters(void)
Definition decode.c:602
void DecodeGlobalConfig(void)
Definition decode.c:1050
void TmModuleDecodeDPDKRegister(void)
Registration Function for DecodeDPDK.
Definition source-dpdk.c:65
void TmModuleReceiveDPDKRegister(void)
Definition source-dpdk.c:51
void HTPAtExitPrintStats(void)
Print the stats of the HTTP requests.
void HTPFreeConfig(void)
Clears the HTTP server configuration memory used by HTP library.
void AppLayerHtpNeedFileInspection(void)
Sets a flag that informs the HTP app layer that some module in the engine needs the http request file...
void AppLayerHtpPrintStats(void)
void TmModuleDecodeNetmapRegister(void)
Registration Function for DecodeNetmap.
void TmModuleReceiveNetmapRegister(void)
void ThresholdInit(void)
void ThresholdDestroy(void)
void HostBitInitCtx(void)
Definition host-bit.c:49
void HostCleanup(void)
Cleanup the host engine.
Definition host.c:332
void HostShutdown(void)
shutdown the flow engine
Definition host.c:296
void HostInitConfig(bool quiet)
initialize the configuration
Definition host.c:168
#define HOST_VERBOSE
Definition host.h:92
void IPPairBitInitCtx(void)
Definition ippair-bit.c:49
void IPPairInitConfig(bool quiet)
initialize the configuration
Definition ippair.c:162
void IPPairShutdown(void)
shutdown the flow engine
Definition ippair.c:290
void OutputFilestoreRegisterGlobalCounters(void)
void TmModuleStatsLoggerRegister(void)
void OutputTxShutdown(void)
Definition output-tx.c:661
void OutputNotifyFileRotation(void)
Notifies all registered file rotation notification flags.
Definition output.c:735
void OutputDeregisterAll(void)
Deregister all modules. Useful for a memory clean exit.
Definition output.c:658
void TmModuleLoggerRegister(void)
Definition output.c:925
void SCOnLoggingReady(void)
Invokes all registered logging ready callbacks.
Definition output.c:778
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:252
void TmModuleRespondRejectRegister(void)
void TmqhSetup(void)
void RunUnittests(int list_unittests, const char *regex_arg)
bool IsRunModeOffline(enum SCRunModes run_mode_to_check)
Definition runmodes.c:561
void RunModeDispatch(int runmode, const char *custom_mode, const char *capture_plugin_name, const char *capture_plugin_args)
Definition runmodes.c:409
void RunModeShutDown(void)
Definition runmodes.c:579
int RunModeEngineIsIPS(int capture_mode, const char *runmode, const char *capture_plugin_name)
Definition runmodes.c:379
void RunModeInitializeThreadSettings(void)
Definition runmodes.c:954
void RunModeRegisterRunModes(void)
Register all runmodes in the engine.
Definition runmodes.c:231
void RunModeListRunmodes(void)
Lists all registered runmodes.
Definition runmodes.c:257
void RunModeInitializeOutputs(void)
Definition runmodes.c:769
bool IsRunModeSystem(enum SCRunModes run_mode_to_check)
Definition runmodes.c:548
@ RUNMODE_NFLOG
Definition runmodes.h:32
@ RUNMODE_UNITTEST
Definition runmodes.h:41
@ RUNMODE_DAG
Definition runmodes.h:35
@ RUNMODE_CONF_TEST
Definition runmodes.h:54
@ RUNMODE_NFQ
Definition runmodes.h:31
@ RUNMODE_PRINT_USAGE
Definition runmodes.h:52
@ RUNMODE_AFP_DEV
Definition runmodes.h:36
@ RUNMODE_DUMP_CONFIG
Definition runmodes.h:53
@ RUNMODE_PRINT_VERSION
Definition runmodes.h:50
@ RUNMODE_LIST_APP_LAYER_HOOKS
Definition runmodes.h:48
@ RUNMODE_NETMAP
Definition runmodes.h:38
@ RUNMODE_ENGINE_ANALYSIS
Definition runmodes.h:56
@ RUNMODE_DPDK
Definition runmodes.h:39
@ RUNMODE_LIST_UNITTEST
Definition runmodes.h:55
@ RUNMODE_IPFW
Definition runmodes.h:33
@ RUNMODE_UNKNOWN
Definition runmodes.h:28
@ RUNMODE_WINDIVERT
Definition runmodes.h:43
@ RUNMODE_PRINT_BUILDINFO
Definition runmodes.h:51
@ RUNMODE_PLUGIN
Definition runmodes.h:44
@ RUNMODE_LIST_RUNMODES
Definition runmodes.h:49
@ RUNMODE_LIST_KEYWORDS
Definition runmodes.h:46
@ RUNMODE_ERF_FILE
Definition runmodes.h:34
@ RUNMODE_PCAP_FILE
Definition runmodes.h:30
@ RUNMODE_AFXDP_DEV
Definition runmodes.h:37
@ RUNMODE_PCAP_DEV
Definition runmodes.h:29
@ RUNMODE_DUMP_FEATURES
Definition runmodes.h:62
@ RUNMODE_LIST_APP_LAYERS
Definition runmodes.h:47
@ RUNMODE_UNIX_SOCKET
Definition runmodes.h:42
enum SCRunModes SCRunMode
const SuricataContext suricata_context
void TmModuleReceiveErfDagRegister(void)
Register the ERF file receiver (reader) module.
void TmModuleDecodeErfDagRegister(void)
Register the ERF file decoder module.
void TmModuleDecodeErfFileRegister(void)
Register the ERF file decoder module.
void TmModuleReceiveErfFileRegister(void)
Register the ERF file receiver (reader) module.
int IPFWRegisterQueue(char *queue)
Add an IPFW divert.
void TmModuleReceiveIPFWRegister(void)
Registration Function for RecieveIPFW.
void TmModuleDecodeIPFWRegister(void)
Registration Function for DecodeIPFW.
void TmModuleVerdictIPFWRegister(void)
Registration Function for VerdictIPFW.
void TmModuleDecodeLibRegister(void)
register a "Decode" module for suricata as a library.
Definition source-lib.c:107
void TmModuleDecodeNFLOGRegister(void)
void TmModuleReceiveNFLOGRegister(void)
void TmModuleReceiveNFQRegister(void)
Definition source-nfq.c:170
void TmModuleVerdictNFQRegister(void)
Definition source-nfq.c:185
void TmModuleDecodeNFQRegister(void)
Definition source-nfq.c:194
void NFQContextsClean(void)
Clean global contexts. Must be called on exit.
void NFQInitConfig(bool quiet)
To initialize the NFQ global configuration data.
Definition source-nfq.c:208
int NFQParseAndRegisterQueues(const char *queues)
Parses and adds Netfilter queue(s).
Definition source-nfq.c:881
void TmModuleReceivePcapFileRegister(void)
void TmModuleDecodePcapFileRegister(void)
void PcapTranslateIPToDevice(char *pcap_dev, size_t len)
void TmModuleReceivePcapRegister(void)
Registration Function for ReceivePcap.
void TmModuleDecodePcapRegister(void)
Registration Function for DecodePcap.
void TmModuleDecodeWinDivertRegister(void)
void TmModuleVerdictWinDivertRegister(void)
void TmModuleReceiveWinDivertRegister(void)
void StreamTcpFreeConfig(bool quiet)
Definition stream-tcp.c:859
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition stream-tcp.c:488
#define STREAM_VERBOSE
Definition stream-tcp.h:35
main detection engine ctx
Definition detect.h:932
const char * firewall_rule_file_exclusive
Definition detect.h:1144
enum DetectEngineType type
Definition detect.h:1053
bool failure_fatal
Definition detect.h:933
struct timeval last_reload
Definition detect.h:1099
char * val
Definition conf.h:39
bool do_setuid
Definition suricata.h:152
struct timeval start_time
Definition suricata.h:173
char * runmode_custom_mode
Definition suricata.h:148
char * sig_file
Definition suricata.h:138
const char * group_name
Definition suricata.h:151
int checksum_validation
Definition suricata.h:170
bool is_firewall
Definition suricata.h:145
const char * capture_plugin_args
Definition suricata.h:182
char * strict_rule_parsing_string
Definition suricata.h:179
char * firewall_rule_file
Definition suricata.h:142
bool sig_file_exclusive
Definition suricata.h:139
enum SCRunModes run_mode
Definition suricata.h:134
const char * capture_plugin_name
Definition suricata.h:181
const char * progname
Definition suricata.h:176
uint32_t userid
Definition suricata.h:155
char * regex_arg
Definition suricata.h:141
bool set_logdir
Definition suricata.h:159
bool do_setgid
Definition suricata.h:153
bool system
Definition suricata.h:158
const char * user_name
Definition suricata.h:150
bool firewall_rule_file_exclusive
Definition suricata.h:143
const char ** additional_configs
Definition suricata.h:178
const char * conf_filename
Definition suricata.h:177
enum SCRunModes aux_run_mode
Definition suricata.h:135
bool unix_socket_enabled
Definition suricata.h:161
bool set_datadir
Definition suricata.h:160
char pcap_dev[128]
Definition suricata.h:137
const char * log_dir
Definition suricata.h:175
uint32_t groupid
Definition suricata.h:156
char * keyword_info
Definition suricata.h:147
char * pid_filename
Definition suricata.h:140
int disabled_detect
Definition suricata.h:166
bool install_signal_handlers
Definition suricata.h:163
int delayed_detect
Definition suricata.h:165
#define BUG_ON(x)
size_t strlcat(char *, const char *src, size_t siz)
#define REVISION
#define str(s)
#define CLS
size_t strlcpy(char *dst, const char *src, size_t siz)
#define xstr(s)
void EngineDone(void)
Used to indicate that the current task is done.
Definition suricata.c:481
void SuricataInit(void)
Definition suricata.c:3012
int coverage_unittests
Definition suricata.c:943
uint16_t g_livedev_mask
Definition suricata.c:206
void PostRunDeinit(const int runmode, struct timeval *start_time)
clean up / shutdown code for packet modes
Definition suricata.c:2331
int InitGlobal(void)
Global initialization common to all runmodes.
Definition suricata.c:2965
void PostConfLoadedDetectSetup(SCInstance *suri)
Definition suricata.c:2625
volatile sig_atomic_t sigusr2_count
Definition suricata.c:159
int g_ut_covered
Definition suricata.c:945
void SCEnableDefaultSignalHandlers(void)
Enable default signal handlers.
Definition suricata.c:289
void EngineModeSetFirewall(void)
Definition suricata.c:254
void PreRunInit(const int runmode)
Definition suricata.c:2286
void PreRunPostPrivsDropInit(const int runmode)
Definition suricata.c:2315
bool g_disable_hashing
Definition suricata.c:214
void SuricataShutdown(void)
Definition suricata.c:3100
TmEcode SCLoadYamlConfig(void)
Definition suricata.c:1012
bool EngineModeIsFirewall(void)
Definition suricata.c:235
uint8_t g_recurlvl_mask
Definition suricata.c:210
int EngineModeIsIPS(void)
Definition suricata.c:242
SCRunMode SCRunmodeGet(void)
Get the current run mode.
Definition suricata.c:279
int SCFinalizeRunMode(void)
Definition suricata.c:2451
volatile uint8_t suricata_ctl_flags
Definition suricata.c:172
int EngineModeIsUnknown(void)
Definition suricata.c:230
void EngineModeSetIDS(void)
Definition suricata.c:264
void EngineModeSetIPS(void)
Definition suricata.c:259
int SCStartInternalRunMode(int argc, char **argv)
Definition suricata.c:2389
uint16_t g_vlan_mask
Definition suricata.c:202
#define DEFAULT_MAX_PENDING_PACKETS
Definition suricata.c:169
int g_skip_prefilter
int SuriHasSigFile(void)
Definition suricata.c:225
int g_disable_randomness
Definition suricata.c:195
uint8_t host_mode
Definition suricata.c:180
void GlobalsDestroy(void)
Definition suricata.c:390
void EngineStop(void)
make sure threads can stop the engine by calling this function. Purpose: pcap file mode needs to be a...
Definition suricata.c:470
SCInstance suricata
Definition suricata.c:223
void SCRunmodeSet(SCRunMode run_mode)
Set the current run mode.
Definition suricata.c:284
TmEcode SCParseCommandLine(int argc, char **argv)
Definition suricata.c:1369
void SuricataMainLoop(void)
Definition suricata.c:2922
void RegisterAllModules(void)
Definition suricata.c:947
volatile sig_atomic_t sighup_count
Definition suricata.c:157
void SuricataPreInit(const char *progname)
Definition suricata.c:3003
SystemHugepageSnapshot * prerun_snap
Definition suricata.c:217
const char * GetDocURL(void)
Definition suricata.c:1165
void SuricataPostInit(void)
Definition suricata.c:3111
bool g_system
Definition suricata.c:191
bool g_stats_eps_per_app_proto_errors
Definition suricata.c:220
int g_ut_modules
Definition suricata.c:944
void GlobalsInitPreConfig(void)
Definition suricata.c:382
const char * GetProgramVersion(void)
get string with program version
Definition suricata.c:1186
bool sc_set_caps
Definition suricata.c:189
int EngineModeIsIDS(void)
Definition suricata.c:248
int RunmodeIsUnittests(void)
Definition suricata.c:270
volatile sig_atomic_t sigterm_count
Definition suricata.c:158
volatile sig_atomic_t sigint_count
Definition suricata.c:156
int g_detect_disabled
Definition suricata.c:186
int PostConfLoadedSetup(SCInstance *suri)
Definition suricata.c:2716
#define DOC_URL
Definition suricata.h:90
#define PROG_VER
Definition suricata.h:76
#define SURICATA_STOP
Definition suricata.h:94
EngineMode
Definition suricata.h:106
@ ENGINE_MODE_IDS
Definition suricata.h:108
@ ENGINE_MODE_FIREWALL
Definition suricata.h:111
@ ENGINE_MODE_UNKNOWN
Definition suricata.h:107
@ ENGINE_MODE_IPS
Definition suricata.h:110
#define DEFAULT_CONF_FILE
Definition suricata.h:84
#define PROG_NAME
Definition suricata.h:75
@ SURI_HOST_IS_SNIFFER_ONLY
Definition suricata.h:125
@ SURI_HOST_IS_ROUTER
Definition suricata.h:126
#define DEFAULT_PID_FILENAME
Definition suricata.h:88
#define SURICATA_DONE
Definition suricata.h:96
@ SURICATA_DEINIT
Definition suricata.h:102
@ SURICATA_RUNTIME
Definition suricata.h:101
#define SCSetThreadName(n)
Definition threads.h:304
#define THV_RUNNING_DONE
Definition threadvars.h:46
#define THV_FLOW_LOOP
Definition threadvars.h:48
#define THV_REQ_FLOW_LOOP
Definition threadvars.h:47
#define THV_KILL
Definition threadvars.h:40
void TmModuleRunDeInit(void)
Definition tm-modules.c:119
void TmModuleRunInit(void)
Definition tm-modules.c:104
TmModule tmm_modules[TMM_SIZE]
Definition tm-modules.c:29
void TmModuleDebugList(void)
Definition tm-modules.c:31
#define TM_FLAG_FLOWWORKER_TM
Definition tm-modules.h:34
#define TM_FLAG_PACKET_ALL
Definition tm-modules.h:40
#define TM_FLAG_RECEIVE_TM
Definition tm-modules.h:32
void TmqhCleanup(void)
Clean up registration time allocs.
void TmqResetQueues(void)
Definition tm-queues.c:80
@ TVT_MGMT
@ TVT_PPT
@ TMM_SIZE
@ TM_ECODE_FAILED
@ TM_ECODE_OK
@ TM_ECODE_DONE
void TmThreadKillThreads(void)
void TmThreadClearThreadsFamily(int family)
TmEcode TmThreadWaitOnThreadInit(void)
Used to check if all threads have finished their initialization. On finding an un-initialized thread,...
void TmThreadsUnsealThreads(void)
const char * name
void TmThreadDisableReceiveThreads(void)
Disable all threads having the specified TMs.
void TmThreadKillThreadsFamily(int family)
void TmThreadContinueThreads(void)
Unpauses all threads present in tv_root.
void TmThreadCheckThreadState(void)
Used to check the thread for certain conditions of failure.
void TmThreadDisablePacketThreads(const uint16_t set, const uint16_t check, const uint8_t module_flags)
Disable all packet threads.
TmEcode TmThreadWaitOnThreadRunning(void)
Waits for all threads to be in a running state.
void PacketPoolDestroy(void)
void PacketPoolInit(void)
void PacketPoolPostRunmodes(void)
Set the max_pending_return_packets value.
void UnixManagerThreadSpawnNonRunmode(const bool unix_socket_enabled)
void TmModuleUnixManagerRegister(void)
void UnixSocketKillSocketThread(void)
void TopologyDestroy(void)
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define SC_ATOMIC_DECLARE(type, name)
wrapper for declaring atomic variables.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:337
TmEcode ConfigSetDataDirectory(char *name)
Definition util-conf.c:66
TmEcode ConfigCheckDataDirectory(const char *data_dir)
Definition util-conf.c:99
const char * SCConfigGetLogDirectory(void)
Definition util-conf.c:38
TmEcode ConfigSetLogDirectory(const char *name)
Definition util-conf.c:33
TmEcode ConfigCheckLogDirectoryExists(const char *log_dir)
Definition util-conf.c:56
int ConfUnixSocketIsEnable(void)
Definition util-conf.c:136
void CoredumpEnable(void)
Enable coredumps on systems where coredumps can and need to be enabled.
int32_t CoredumpLoadConfig(void)
Configures the core dump size.
void UtilCpuPrintSummary(void)
Print a summary of CPUs detected (configured and online)
Definition util-cpu.c:140
int CheckValidDaemonModes(int daemon, int mode)
Check for a valid combination daemon/mode.
void Daemonize(void)
Daemonize the process.
void SCLogDeInitLogModule(void)
De-Initializes the logging module.
void SCLogLoadConfig(int daemon, int verbose, uint32_t userid, uint32_t groupid)
void SCLogInitLogModule(SCLogInitData *sc_lid)
Initializes the logging module.
#define SCEnter(...)
Definition util-debug.h:277
#define FatalError(...)
Definition util-debug.h:510
#define SC_LOG_MAX_LOG_MSG_LEN
Definition util-debug.h:85
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition util-debug.h:243
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition util-debug.h:225
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCLogConfig(...)
Definition util-debug.h:229
void LiveDeviceFinalize(void)
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
int LiveGetDeviceCount(void)
Get the number of registered devices.
int LiveBuildDeviceList(const char *runmode)
void LiveSetOffloadDisable(void)
Definition util-device.c:77
void LiveDevRegisterExtension(void)
int LiveBuildDeviceListCustom(const char *runmode, const char *itemname)
void LiveSetOffloadWarn(void)
Definition util-device.c:82
int LiveRegisterDeviceName(const char *dev)
Add a device for monitoring.
int LiveDeviceListClean(void)
const char * LiveGetDeviceName(int number)
Get a pointer to the device name at idx.
void DPDKCleanupEAL(void)
Definition util-dpdk.c:30
int ExceptionSimulationCommandLineParser(const char *name, const char *arg)
void SetMasterExceptionPolicy(void)
void FlowRateRegisterFlowStorage(void)
void SCHInfoLoadFromConfig(void)
Load the host os policy information from the configuration.
void SystemHugepageEvaluateHugepages(SystemHugepageSnapshot *pre_s, SystemHugepageSnapshot *post_s)
The function compares two hugepage snapshots and prints out recommendations for hugepage configuratio...
void SystemHugepageSnapshotDestroy(SystemHugepageSnapshot *s)
SystemHugepageSnapshot * SystemHugepageSnapshotCreate(void)
The function creates a snapshot of the system's hugepage usage per NUMA node and per hugepage size....
int GetIfaceMaxPacketSize(LiveDevice *ld)
output max packet size for a link
Definition util-ioctl.c:121
int GetIfaceMTU(const char *dev)
output the link MTU
Definition util-ioctl.c:82
void LandlockSandboxing(SCInstance *suri)
void MacSetRegisterFlowStorage(void)
Definition util-macset.c:62
#define SCFree(p)
Definition util-mem.h:61
#define SCRealloc(ptr, sz)
Definition util-mem.h:50
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define SCStrdup(s)
Definition util-mem.h:56
int ParseSizeStringU32(const char *size, uint32_t *res)
Definition util-misc.c:173
void ParseSizeDeinit(void)
Definition util-misc.c:54
void ParseSizeInit(void)
Definition util-misc.c:35
#define WarnInvalidConfEntry(param_name, format, value)
Generic API that can be used by all to log an invalid conf entry.
Definition util-misc.h:35
void MpmHSGlobalCleanup(void)
void MpmTableSetup(void)
Definition util-mpm.c:224
#define unlikely(expr)
#define SCStatFn(pathname, statbuf)
Definition util-path.h:35
struct stat SCStat
Definition util-path.h:33
#define SCFstatFn(fd, statbuf)
Definition util-path.h:34
int SCPidfileTestRunning(const char *pid_filename)
Check the Suricata pid file (used at the startup)
int SCPidfileCreate(const char *pidfile)
Write a pid file (used at the startup) This commonly needed by the init scripts.
void SCPidfileRemove(const char *pid_filename)
Remove the pid file (used at the startup)
void SCPluginsLoad(const char *capture_plugin_name, const char *capture_plugin_args)
void SCGetGroupID(const char *group_name, uint32_t *gid)
Function to get the group ID from the specified group name.
Definition util-privs.c:210
void SCGetUserID(const char *user_name, const char *group_name, uint32_t *uid, uint32_t *gid)
Function to get the user and group ID from the specified user name.
Definition util-privs.c:143
#define SCPledge(...)
Definition util-privs.h:99
#define SCDropMainThreadCaps(...)
Definition util-privs.h:90
void SCProfilingKeywordsGlobalInit(void)
void SCProfilingPrefilterGlobalInit(void)
void SCProfilingSghsGlobalInit(void)
void SCProfilingDestroy(void)
Free resources used by profiling.
void SCProfilingInit(void)
Initialize profiling.
int profiling_packets_enabled
void SCProfilingDump(void)
void SCProtoNameInit(void)
void SCProtoNameRelease(void)
int ListAppLayerProtocols(const char *conf_filename)
int ListAppLayerHooks(const char *conf_filename)
int ListKeywords(const char *keyword_info)
int UtilSignalUnblock(int signum)
Definition util-signal.c:46
void UtilSignalHandlerSetup(int sig, void(*handler)(int))
Definition util-signal.c:60
int UtilSignalBlock(int signum)
Definition util-signal.c:29
void SpmTableSetup(void)
Definition util-spm.c:122
int StorageFinalize(void)
void StorageInit(void)
int SystemDNotifyReady(void)
void SCThresholdConfGlobalInit(void)
void TimeInit(void)
Definition util-time.c:79
void TimeDeinit(void)
Definition util-time.c:87
#define DEBUG_VALIDATE_BUG_ON(exp)
void VarNameStoreDestroy(void)
void VarNameStoreInit(void)
#define geteuid()
Definition win32-misc.h:41