1 /* Copyright (C) 2007-2020 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
34 #ifdef HAVE_NSS
35 #include <prinit.h>
36 #include <nss.h>
37 #endif
38
39 #include "suricata.h"
40 #include "decode.h"
41 #include "feature.h"
42 #include "detect.h"
43 #include "packet-queue.h"
44 #include "threads.h"
45 #include "threadvars.h"
46 #include "flow-worker.h"
47
48 #include "util-atomic.h"
49 #include "util-spm.h"
50 #include "util-cpu.h"
51 #include "util-action.h"
52 #include "util-pidfile.h"
53 #include "util-ioctl.h"
54 #include "util-device.h"
55 #include "util-misc.h"
56 #include "util-running-modes.h"
57
58 #include "detect-engine.h"
59 #include "detect-parse.h"
60 #include "detect-fast-pattern.h"
61 #include "detect-engine-tag.h"
62 #include "detect-engine-threshold.h"
63 #include "detect-engine-address.h"
64 #include "detect-engine-port.h"
65 #include "detect-engine-mpm.h"
66
67 #include "tm-queuehandlers.h"
68 #include "tm-queues.h"
69 #include "tm-threads.h"
70
71 #include "tmqh-flow.h"
72
73 #include "conf.h"
74 #include "conf-yaml-loader.h"
75
76 #include "datasets.h"
77
78 #include "stream-tcp.h"
79
80 #include "source-nfq.h"
81 #include "source-nfq-prototypes.h"
82
83 #include "source-nflog.h"
84
85 #include "source-ipfw.h"
86
87 #include "source-pcap.h"
88 #include "source-pcap-file.h"
89
90 #include "source-pfring.h"
91
92 #include "source-erf-file.h"
93 #include "source-erf-dag.h"
94 #include "source-napatech.h"
95
96 #include "source-af-packet.h"
97 #include "source-netmap.h"
98
99 #include "source-windivert.h"
100 #include "source-windivert-prototypes.h"
101
102 #include "respond-reject.h"
103
104 #include "flow.h"
105 #include "flow-timeout.h"
106 #include "flow-manager.h"
107 #include "flow-bypass.h"
108 #include "flow-var.h"
109 #include "flow-bit.h"
110 #include "pkt-var.h"
111 #include "host-bit.h"
112
113 #include "ippair.h"
114 #include "ippair-bit.h"
115
116 #include "host.h"
117 #include "unix-manager.h"
118
119 #include "app-layer.h"
120 #include "app-layer-parser.h"
121 #include "app-layer-htp.h"
122 #include "app-layer-ssl.h"
123 #include "app-layer-ssh.h"
124 #include "app-layer-ftp.h"
125 #include "app-layer-smtp.h"
126 #include "app-layer-modbus.h"
127 #include "app-layer-enip.h"
128 #include "app-layer-dnp3.h"
129 #include "app-layer-smb.h"
130 #include "app-layer-dcerpc.h"
131
132 #include "output-filestore.h"
133
134 #include "util-ebpf.h"
135 #include "util-radix-tree.h"
136 #include "util-host-os-info.h"
137 #include "util-cidr.h"
138 #include "util-unittest.h"
139 #include "util-unittest-helper.h"
140 #include "util-time.h"
141 #include "util-rule-vars.h"
142 #include "util-classification-config.h"
143 #include "util-threshold-config.h"
144 #include "util-reference-config.h"
145 #include "util-profiling.h"
146 #include "util-magic.h"
147 #include "util-signal.h"
148
149 #include "util-coredump-config.h"
150
151 #include "util-decode-mime.h"
152
153 #include "defrag.h"
154
155 #include "runmodes.h"
156 #include "runmode-unittests.h"
157
158 #include "util-debug.h"
159 #include "util-error.h"
160 #include "util-daemon.h"
161 #include "util-byte.h"
162 #include "reputation.h"
163
164 #include "output.h"
165
166 #include "util-privs.h"
167
168 #include "tmqh-packetpool.h"
169
170 #include "util-proto-name.h"
171 #include "util-mpm-hs.h"
172 #include "util-storage.h"
173 #include "host-storage.h"
174
175 #include "util-lua.h"
176
177 #include "util-plugin.h"
178
179 #include "rust.h"
180
181 /*
182 * we put this here, because we only use it here in main.
183 */
184 volatile sig_atomic_t sigint_count = 0;
185 volatile sig_atomic_t sighup_count = 0;
186 volatile sig_atomic_t sigterm_count = 0;
187 volatile sig_atomic_t sigusr2_count = 0;
188
189 /*
190 * Flag to indicate if the engine is at the initialization
191 * or already processing packets. 3 stages: SURICATA_INIT,
192 * SURICATA_RUNTIME and SURICATA_FINALIZE
193 */
194 SC_ATOMIC_DECLARE(unsigned int, engine_stage);
195
196 /* Max packets processed simultaniously per thread. */
197 #define DEFAULT_MAX_PENDING_PACKETS 1024
198
199 /** suricata engine control flags */
200 volatile uint8_t suricata_ctl_flags = 0;
201
202 /** Run mode selected */
203 int run_mode = RUNMODE_UNKNOWN;
204
205 /** Engine mode: inline (ENGINE_MODE_IPS) or just
206 * detection mode (ENGINE_MODE_IDS by default) */
207 static enum EngineMode g_engine_mode = ENGINE_MODE_IDS;
208
209 /** Host mode: set if box is sniffing only
210 * or is a router */
211 uint8_t host_mode = SURI_HOST_IS_SNIFFER_ONLY;
212
213 /** Maximum packets to simultaneously process. */
214 intmax_t max_pending_packets;
215
216 /** global indicating if detection is enabled */
217 int g_detect_disabled = 0;
218
219 /** set caps or not */
220 int sc_set_caps = FALSE;
221
222 /** highest mtu of the interfaces we monitor */
223 int g_default_mtu = 0;
224
225 bool g_system = false;
226
227 /** disable randomness to get reproducible results accross runs */
228 #ifndef AFLFUZZ_NO_RANDOM
229 int g_disable_randomness = 0;
230 #else
231 int g_disable_randomness = 1;
232 #endif
233
234 /** determine (without branching) if we include the vlan_ids when hashing or
235 * comparing flows */
236 uint16_t g_vlan_mask = 0xffff;
237
238 /** Suricata instance */
239 SCInstance suricata;
240
SuriHasSigFile(void)241 int SuriHasSigFile(void)
242 {
243 return (suricata.sig_file != NULL);
244 }
245
EngineModeIsIPS(void)246 int EngineModeIsIPS(void)
247 {
248 return (g_engine_mode == ENGINE_MODE_IPS);
249 }
250
EngineModeIsIDS(void)251 int EngineModeIsIDS(void)
252 {
253 return (g_engine_mode == ENGINE_MODE_IDS);
254 }
255
EngineModeSetIPS(void)256 void EngineModeSetIPS(void)
257 {
258 g_engine_mode = ENGINE_MODE_IPS;
259 }
260
EngineModeSetIDS(void)261 void EngineModeSetIDS(void)
262 {
263 g_engine_mode = ENGINE_MODE_IDS;
264 }
265
RunmodeIsUnittests(void)266 int RunmodeIsUnittests(void)
267 {
268 if (run_mode == RUNMODE_UNITTEST)
269 return 1;
270
271 return 0;
272 }
273
RunmodeGetCurrent(void)274 int RunmodeGetCurrent(void)
275 {
276 return run_mode;
277 }
278
279 /** signal handlers
280 *
281 * WARNING: don't use the SCLog* API in the handlers. The API is complex
282 * with memory allocation possibly happening, calls to syslog, json message
283 * construction, etc.
284 */
285
286 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
SignalHandlerSigint(int sig)287 static void SignalHandlerSigint(/*@unused@*/ int sig)
288 {
289 sigint_count = 1;
290 }
SignalHandlerSigterm(int sig)291 static void SignalHandlerSigterm(/*@unused@*/ int sig)
292 {
293 sigterm_count = 1;
294 }
295 #endif
296
297 #ifndef OS_WIN32
298 /**
299 * SIGUSR2 handler. Just set sigusr2_count. The main loop will act on
300 * it.
301 */
SignalHandlerSigusr2(int sig)302 static void SignalHandlerSigusr2(int sig)
303 {
304 if (sigusr2_count < 2)
305 sigusr2_count++;
306 }
307
308 /**
309 * SIGHUP handler. Just set sighup_count. The main loop will act on
310 * it.
311 */
SignalHandlerSigHup(int sig)312 static void SignalHandlerSigHup(/*@unused@*/ int sig)
313 {
314 sighup_count = 1;
315 }
316 #endif
317
GlobalsInitPreConfig(void)318 void GlobalsInitPreConfig(void)
319 {
320 TimeInit();
321 SupportFastPatternForSigMatchTypes();
322 SCThresholdConfGlobalInit();
323 }
324
GlobalsDestroy(SCInstance * suri)325 static void GlobalsDestroy(SCInstance *suri)
326 {
327 HostShutdown();
328 HTPFreeConfig();
329 HTPAtExitPrintStats();
330
331 AppLayerHtpPrintStats();
332
333 /* TODO this can do into it's own func */
334 DetectEngineCtx *de_ctx = DetectEngineGetCurrent();
335 if (de_ctx) {
336 DetectEngineMoveToFreeList(de_ctx);
337 DetectEngineDeReference(&de_ctx);
338 }
339 DetectEnginePruneFreeList();
340
341 AppLayerDeSetup();
342 DatasetsSave();
343 DatasetsDestroy();
344 TagDestroyCtx();
345
346 LiveDeviceListClean();
347 OutputDeregisterAll();
348 FeatureTrackingRelease();
349 TimeDeinit();
350 SCProtoNameDeInit();
351 if (!suri->disabled_detect) {
352 SCReferenceConfDeinit();
353 SCClassConfDeinit();
354 }
355 TmqhCleanup();
356 TmModuleRunDeInit();
357 ParseSizeDeinit();
358 #ifdef HAVE_NSS
359 if (NSS_IsInitialized()) {
360 NSS_Shutdown();
361 PR_Cleanup();
362 }
363 #endif
364
365 #ifdef HAVE_AF_PACKET
366 AFPPeersListClean();
367 #endif
368
369 #ifdef NFQ
370 NFQContextsClean();
371 #endif
372
373 #ifdef BUILD_HYPERSCAN
374 MpmHSGlobalCleanup();
375 #endif
376
377 ConfDeInit();
378 #ifdef HAVE_LUAJIT
379 LuajitFreeStatesPool();
380 #endif
381 SCLogDeInitLogModule();
382 DetectParseFreeRegexes();
383 SCThresholdConfGlobalFree();
384
385 SCPidfileRemove(suri->pid_filename);
386 SCFree(suri->pid_filename);
387 suri->pid_filename = NULL;
388 }
389
390 /** \brief make sure threads can stop the engine by calling this
391 * function. Purpose: pcap file mode needs to be able to tell the
392 * engine the file eof is reached. */
EngineStop(void)393 void EngineStop(void)
394 {
395 suricata_ctl_flags |= SURICATA_STOP;
396 }
397
398 /**
399 * \brief Used to indicate that the current task is done.
400 *
401 * This is mainly used by pcap-file to tell it has finished
402 * to treat a pcap files when running in unix-socket mode.
403 */
EngineDone(void)404 void EngineDone(void)
405 {
406 suricata_ctl_flags |= SURICATA_DONE;
407 }
408
SetBpfString(int argc,char * argv[])409 static int SetBpfString(int argc, char *argv[])
410 {
411 char *bpf_filter = NULL;
412 uint32_t bpf_len = 0;
413 int tmpindex = 0;
414
415 /* attempt to parse remaining args as bpf filter */
416 tmpindex = argc;
417 while(argv[tmpindex] != NULL) {
418 bpf_len+=strlen(argv[tmpindex]) + 1;
419 tmpindex++;
420 }
421
422 if (bpf_len == 0)
423 return TM_ECODE_OK;
424
425 if (EngineModeIsIPS()) {
426 SCLogError(SC_ERR_NOT_SUPPORTED,
427 "BPF filter not available in IPS mode."
428 " Use firewall filtering if possible.");
429 return TM_ECODE_FAILED;
430 }
431
432 bpf_filter = SCMalloc(bpf_len);
433 if (unlikely(bpf_filter == NULL))
434 return TM_ECODE_OK;
435 memset(bpf_filter, 0x00, bpf_len);
436
437 tmpindex = optind;
438 while(argv[tmpindex] != NULL) {
439 strlcat(bpf_filter, argv[tmpindex],bpf_len);
440 if(argv[tmpindex + 1] != NULL) {
441 strlcat(bpf_filter," ", bpf_len);
442 }
443 tmpindex++;
444 }
445
446 if(strlen(bpf_filter) > 0) {
447 if (ConfSetFinal("bpf-filter", bpf_filter) != 1) {
448 SCLogError(SC_ERR_FATAL, "Failed to set bpf filter.");
449 SCFree(bpf_filter);
450 return TM_ECODE_FAILED;
451 }
452 }
453 SCFree(bpf_filter);
454
455 return TM_ECODE_OK;
456 }
457
SetBpfStringFromFile(char * filename)458 static void SetBpfStringFromFile(char *filename)
459 {
460 char *bpf_filter = NULL;
461 char *bpf_comment_tmp = NULL;
462 char *bpf_comment_start = NULL;
463 uint32_t bpf_len = 0;
464 #ifdef OS_WIN32
465 struct _stat st;
466 #else
467 struct stat st;
468 #endif /* OS_WIN32 */
469 FILE *fp = NULL;
470 size_t nm = 0;
471
472 if (EngineModeIsIPS()) {
473 FatalError(SC_ERR_FATAL,
474 "BPF filter not available in IPS mode."
475 " Use firewall filtering if possible.");
476 }
477
478 #ifdef OS_WIN32
479 if(_stat(filename, &st) != 0) {
480 #else
481 if(stat(filename, &st) != 0) {
482 #endif /* OS_WIN32 */
483 SCLogError(SC_ERR_FOPEN, "Failed to stat file %s", filename);
484 exit(EXIT_FAILURE);
485 }
486 bpf_len = st.st_size + 1;
487
488 // coverity[toctou : FALSE]
489 fp = fopen(filename,"r");
490 if (fp == NULL) {
491 SCLogError(SC_ERR_FOPEN, "Failed to open file %s", filename);
492 exit(EXIT_FAILURE);
493 }
494
495 bpf_filter = SCMalloc(bpf_len * sizeof(char));
496 if (unlikely(bpf_filter == NULL)) {
497 SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate buffer for bpf filter in file %s", filename);
498 exit(EXIT_FAILURE);
499 }
500 memset(bpf_filter, 0x00, bpf_len);
501
502 nm = fread(bpf_filter, 1, bpf_len - 1, fp);
503 if ((ferror(fp) != 0) || (nm != (bpf_len - 1))) {
504 SCLogError(SC_ERR_BPF, "Failed to read complete BPF file %s", filename);
505 SCFree(bpf_filter);
506 fclose(fp);
507 exit(EXIT_FAILURE);
508 }
509 fclose(fp);
510 bpf_filter[nm] = '\0';
511
512 if(strlen(bpf_filter) > 0) {
513 /*replace comments with space*/
514 bpf_comment_start = bpf_filter;
515 while((bpf_comment_tmp = strchr(bpf_comment_start, '#')) != NULL) {
516 while((*bpf_comment_tmp !='\0') &&
517 (*bpf_comment_tmp != '\r') && (*bpf_comment_tmp != '\n'))
518 {
519 *bpf_comment_tmp++ = ' ';
520 }
521 bpf_comment_start = bpf_comment_tmp;
522 }
523 /*remove remaining '\r' and '\n' */
524 while((bpf_comment_tmp = strchr(bpf_filter, '\r')) != NULL) {
525 *bpf_comment_tmp = ' ';
526 }
527 while((bpf_comment_tmp = strchr(bpf_filter, '\n')) != NULL) {
528 *bpf_comment_tmp = ' ';
529 }
530 /* cut trailing spaces */
531 while (strlen(bpf_filter) > 0 &&
532 bpf_filter[strlen(bpf_filter)-1] == ' ')
533 {
534 bpf_filter[strlen(bpf_filter)-1] = '\0';
535 }
536 if (strlen(bpf_filter) > 0) {
537 if(ConfSetFinal("bpf-filter", bpf_filter) != 1) {
538 SCLogError(SC_ERR_FOPEN, "ERROR: Failed to set bpf filter!");
539 SCFree(bpf_filter);
540 exit(EXIT_FAILURE);
541 }
542 }
543 }
544 SCFree(bpf_filter);
545 }
546
547 static void PrintUsage(const char *progname)
548 {
549 #ifdef REVISION
550 printf("%s %s (%s)\n", PROG_NAME, PROG_VER, xstr(REVISION));
551 #else
552 printf("%s %s\n", PROG_NAME, PROG_VER);
553 #endif
554 printf("USAGE: %s [OPTIONS] [BPF FILTER]\n\n", progname);
555 printf("\t-c <path> : path to configuration file\n");
556 printf("\t-T : test configuration file (use with -c)\n");
557 printf("\t-i <dev or ip> : run in pcap live mode\n");
558 printf("\t-F <bpf filter file> : bpf filter file\n");
559 printf("\t-r <path> : run in pcap file/offline mode\n");
560 #ifdef NFQ
561 printf("\t-q <qid[:qid]> : run in inline nfqueue mode (use colon to specify a range of queues)\n");
562 #endif /* NFQ */
563 #ifdef IPFW
564 printf("\t-d <divert port> : run in inline ipfw divert mode\n");
565 #endif /* IPFW */
566 printf("\t-s <path> : path to signature file loaded in addition to suricata.yaml settings (optional)\n");
567 printf("\t-S <path> : path to signature file loaded exclusively (optional)\n");
568 printf("\t-l <dir> : default log directory\n");
569 #ifndef OS_WIN32
570 printf("\t-D : run as daemon\n");
571 #else
572 printf("\t--service-install : install as service\n");
573 printf("\t--service-remove : remove service\n");
574 printf("\t--service-change-params : change service startup parameters\n");
575 #endif /* OS_WIN32 */
576 printf("\t-k [all|none] : force checksum check (all) or disabled it (none)\n");
577 printf("\t-V : display Suricata version\n");
578 printf("\t-v : be more verbose (use multiple times to increase verbosity)\n");
579 #ifdef UNITTESTS
580 printf("\t-u : run the unittests and exit\n");
581 printf("\t-U, --unittest-filter=REGEX : filter unittests with a regex\n");
582 printf("\t--list-unittests : list unit tests\n");
583 printf("\t--fatal-unittests : enable fatal failure on unittest error\n");
584 printf("\t--unittests-coverage : display unittest coverage report\n");
585 #endif /* UNITTESTS */
586 printf("\t--list-app-layer-protos : list supported app layer protocols\n");
587 printf("\t--list-keywords[=all|csv|<kword>] : list keywords implemented by the engine\n");
588 printf("\t--list-runmodes : list supported runmodes\n");
589 printf("\t--runmode <runmode_id> : specific runmode modification the engine should run. The argument\n"
590 "\t supplied should be the id for the runmode obtained by running\n"
591 "\t --list-runmodes\n");
592 printf("\t--engine-analysis : print reports on analysis of different sections in the engine and exit.\n"
593 "\t Please have a look at the conf parameter engine-analysis on what reports\n"
594 "\t can be printed\n");
595 printf("\t--pidfile <file> : write pid to this file\n");
596 printf("\t--init-errors-fatal : enable fatal failure on signature init error\n");
597 printf("\t--disable-detection : disable detection engine\n");
598 printf("\t--dump-config : show the running configuration\n");
599 printf("\t--dump-features : display provided features\n");
600 printf("\t--build-info : display build information\n");
601 printf("\t--pcap[=<dev>] : run in pcap mode, no value select interfaces from suricata.yaml\n");
602 printf("\t--pcap-file-continuous : when running in pcap mode with a directory, continue checking directory for pcaps until interrupted\n");
603 printf("\t--pcap-file-delete : when running in replay mode (-r with directory or file), will delete pcap files that have been processed when done\n");
604 printf("\t--pcap-file-recursive : will descend into subdirectories when running in replay mode (-r)\n");
605 #ifdef HAVE_PCAP_SET_BUFF
606 printf("\t--pcap-buffer-size : size of the pcap buffer value from 0 - %i\n",INT_MAX);
607 #endif /* HAVE_SET_PCAP_BUFF */
608 #ifdef HAVE_AF_PACKET
609 printf("\t--af-packet[=<dev>] : run in af-packet mode, no value select interfaces from suricata.yaml\n");
610 #endif
611 #ifdef HAVE_NETMAP
612 printf("\t--netmap[=<dev>] : run in netmap mode, no value select interfaces from suricata.yaml\n");
613 #endif
614 #ifdef HAVE_PFRING
615 printf("\t--pfring[=<dev>] : run in pfring mode, use interfaces from suricata.yaml\n");
616 printf("\t--pfring-int <dev> : run in pfring mode, use interface <dev>\n");
617 printf("\t--pfring-cluster-id <id> : pfring cluster id \n");
618 printf("\t--pfring-cluster-type <type> : pfring cluster type for PF_RING 4.1.2 and later cluster_round_robin|cluster_flow\n");
619 #endif /* HAVE_PFRING */
620 printf("\t--simulate-ips : force engine into IPS mode. Useful for QA\n");
621 #ifdef HAVE_LIBCAP_NG
622 printf("\t--user <user> : run suricata as this user after init\n");
623 printf("\t--group <group> : run suricata as this group after init\n");
624 #endif /* HAVE_LIBCAP_NG */
625 printf("\t--erf-in <path> : process an ERF file\n");
626 #ifdef HAVE_DAG
627 printf("\t--dag <dagX:Y> : process ERF records from DAG interface X, stream Y\n");
628 #endif
629 #ifdef HAVE_NAPATECH
630 printf("\t--napatech : run Napatech Streams using the API\n");
631 #endif
632 #ifdef BUILD_UNIX_SOCKET
633 printf("\t--unix-socket[=<file>] : use unix socket to control suricata work\n");
634 #endif
635 #ifdef WINDIVERT
636 printf("\t--windivert <filter> : run in inline WinDivert mode\n");
637 printf("\t--windivert-forward <filter> : run in inline WinDivert mode, as a gateway\n");
638 #endif
639 #ifdef HAVE_LIBNET11
640 printf("\t--reject-dev <dev> : send reject packets from this interface\n");
641 #endif
642 printf("\t--set name=value : set a configuration value\n");
643 printf("\n");
644 printf("\nTo run the engine with default configuration on "
645 "interface eth0 with signature file \"signatures.rules\", run the "
646 "command as:\n\n%s -c suricata.yaml -s signatures.rules -i eth0 \n\n",
647 progname);
648 }
649
650 static void PrintBuildInfo(void)
651 {
652 const char *bits = "<unknown>-bits";
653 const char *endian = "<unknown>-endian";
654 char features[2048] = "";
655 const char *tls;
656
657 printf("This is %s version %s\n", PROG_NAME, GetProgramVersion());
658
659 #ifdef DEBUG
660 strlcat(features, "DEBUG ", sizeof(features));
661 #endif
662 #ifdef DEBUG_VALIDATION
663 strlcat(features, "DEBUG_VALIDATION ", sizeof(features));
664 #endif
665 #ifdef UNITTESTS
666 strlcat(features, "UNITTESTS ", sizeof(features));
667 #endif
668 #ifdef NFQ
669 strlcat(features, "NFQ ", sizeof(features));
670 #endif
671 #ifdef IPFW
672 strlcat(features, "IPFW ", sizeof(features));
673 #endif
674 #ifdef HAVE_PCAP_SET_BUFF
675 strlcat(features, "PCAP_SET_BUFF ", sizeof(features));
676 #endif
677 #ifdef HAVE_PFRING
678 strlcat(features, "PF_RING ", sizeof(features));
679 #endif
680 #ifdef HAVE_AF_PACKET
681 strlcat(features, "AF_PACKET ", sizeof(features));
682 #endif
683 #ifdef HAVE_NETMAP
684 strlcat(features, "NETMAP ", sizeof(features));
685 #endif
686 #ifdef HAVE_PACKET_FANOUT
687 strlcat(features, "HAVE_PACKET_FANOUT ", sizeof(features));
688 #endif
689 #ifdef HAVE_DAG
690 strlcat(features, "DAG ", sizeof(features));
691 #endif
692 #ifdef HAVE_LIBCAP_NG
693 strlcat(features, "LIBCAP_NG ", sizeof(features));
694 #endif
695 #ifdef HAVE_LIBNET11
696 strlcat(features, "LIBNET1.1 ", sizeof(features));
697 #endif
698 #ifdef HAVE_HTP_URI_NORMALIZE_HOOK
699 strlcat(features, "HAVE_HTP_URI_NORMALIZE_HOOK ", sizeof(features));
700 #endif
701 #ifdef PCRE_HAVE_JIT
702 strlcat(features, "PCRE_JIT ", sizeof(features));
703 #endif
704 #ifdef HAVE_NSS
705 strlcat(features, "HAVE_NSS ", sizeof(features));
706 #endif
707 #ifdef HTTP2_DECOMPRESSION
708 strlcat(features, "HTTP2_DECOMPRESSION ", sizeof(features));
709 #endif
710 #ifdef HAVE_LUA
711 strlcat(features, "HAVE_LUA ", sizeof(features));
712 #endif
713 #ifdef HAVE_LUAJIT
714 strlcat(features, "HAVE_LUAJIT ", sizeof(features));
715 #endif
716 strlcat(features, "HAVE_LIBJANSSON ", sizeof(features));
717 #ifdef PROFILING
718 strlcat(features, "PROFILING ", sizeof(features));
719 #endif
720 #ifdef PROFILE_LOCKING
721 strlcat(features, "PROFILE_LOCKING ", sizeof(features));
722 #endif
723 #if defined(TLS_C11) || defined(TLS_GNU)
724 strlcat(features, "TLS ", sizeof(features));
725 #endif
726 #if defined(TLS_C11)
727 strlcat(features, "TLS_C11 ", sizeof(features));
728 #elif defined(TLS_GNU)
729 strlcat(features, "TLS_GNU ", sizeof(features));
730 #endif
731 #ifdef HAVE_MAGIC
732 strlcat(features, "MAGIC ", sizeof(features));
733 #endif
734 strlcat(features, "RUST ", sizeof(features));
735 if (strlen(features) == 0) {
736 strlcat(features, "none", sizeof(features));
737 }
738
739 printf("Features: %s\n", features);
740
741 /* SIMD stuff */
742 memset(features, 0x00, sizeof(features));
743 #if defined(__SSE4_2__)
744 strlcat(features, "SSE_4_2 ", sizeof(features));
745 #endif
746 #if defined(__SSE4_1__)
747 strlcat(features, "SSE_4_1 ", sizeof(features));
748 #endif
749 #if defined(__SSE3__)
750 strlcat(features, "SSE_3 ", sizeof(features));
751 #endif
752 if (strlen(features) == 0) {
753 strlcat(features, "none", sizeof(features));
754 }
755 printf("SIMD support: %s\n", features);
756
757 /* atomics stuff */
758 memset(features, 0x00, sizeof(features));
759 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)
760 strlcat(features, "1 ", sizeof(features));
761 #endif
762 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
763 strlcat(features, "2 ", sizeof(features));
764 #endif
765 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
766 strlcat(features, "4 ", sizeof(features));
767 #endif
768 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
769 strlcat(features, "8 ", sizeof(features));
770 #endif
771 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
772 strlcat(features, "16 ", sizeof(features));
773 #endif
774 if (strlen(features) == 0) {
775 strlcat(features, "none", sizeof(features));
776 } else {
777 strlcat(features, "byte(s)", sizeof(features));
778 }
779 printf("Atomic intrinsics: %s\n", features);
780
781 #if __WORDSIZE == 64
782 bits = "64-bits";
783 #elif __WORDSIZE == 32
784 bits = "32-bits";
785 #endif
786
787 #if __BYTE_ORDER == __BIG_ENDIAN
788 endian = "Big-endian";
789 #elif __BYTE_ORDER == __LITTLE_ENDIAN
790 endian = "Little-endian";
791 #endif
792
793 printf("%s, %s architecture\n", bits, endian);
794 #ifdef __GNUC__
795 printf("GCC version %s, C version %"PRIiMAX"\n", __VERSION__, (intmax_t)__STDC_VERSION__);
796 #else
797 printf("C version %"PRIiMAX"\n", (intmax_t)__STDC_VERSION__);
798 #endif
799
800 #if __SSP__ == 1
801 printf("compiled with -fstack-protector\n");
802 #endif
803 #if __SSP_ALL__ == 2
804 printf("compiled with -fstack-protector-all\n");
805 #endif
806 /*
807 * Workaround for special defines of _FORTIFY_SOURCE like
808 * FORTIFY_SOURCE=((defined __OPTIMIZE && OPTIMIZE > 0) ? 2 : 0)
809 * which is used by Gentoo for example and would result in the error
810 * 'defined' undeclared when _FORTIFY_SOURCE used via %d in printf func
811 *
812 */
813 #if _FORTIFY_SOURCE == 2
814 printf("compiled with _FORTIFY_SOURCE=2\n");
815 #elif _FORTIFY_SOURCE == 1
816 printf("compiled with _FORTIFY_SOURCE=1\n");
817 #elif _FORTIFY_SOURCE == 0
818 printf("compiled with _FORTIFY_SOURCE=0\n");
819 #endif
820 #ifdef CLS
821 printf("L1 cache line size (CLS)=%d\n", CLS);
822 #endif
823 #if defined(TLS_C11)
824 tls = "_Thread_local";
825 #elif defined(TLS_GNU)
826 tls = "__thread";
827 #else
828 #error "Unsupported thread local"
829 #endif
830 printf("thread local storage method: %s\n", tls);
831
832 printf("compiled with %s, linked against %s\n",
833 HTP_VERSION_STRING_FULL, htp_get_version());
834 printf("\n");
835 #include "build-info.h"
836 }
837
838 int coverage_unittests;
839 int g_ut_modules;
840 int g_ut_covered;
841
842 void RegisterAllModules(void)
843 {
844 // zero all module storage
845 memset(tmm_modules, 0, TMM_SIZE * sizeof(TmModule));
846
847 /* commanders */
848 TmModuleUnixManagerRegister();
849 /* managers */
850 TmModuleFlowManagerRegister();
851 TmModuleFlowRecyclerRegister();
852 TmModuleBypassedFlowManagerRegister();
853 /* nfq */
854 TmModuleReceiveNFQRegister();
855 TmModuleVerdictNFQRegister();
856 TmModuleDecodeNFQRegister();
857 /* ipfw */
858 TmModuleReceiveIPFWRegister();
859 TmModuleVerdictIPFWRegister();
860 TmModuleDecodeIPFWRegister();
861 /* pcap live */
862 TmModuleReceivePcapRegister();
863 TmModuleDecodePcapRegister();
864 /* pcap file */
865 TmModuleReceivePcapFileRegister();
866 TmModuleDecodePcapFileRegister();
867 /* af-packet */
868 TmModuleReceiveAFPRegister();
869 TmModuleDecodeAFPRegister();
870 /* netmap */
871 TmModuleReceiveNetmapRegister();
872 TmModuleDecodeNetmapRegister();
873 /* pfring */
874 TmModuleReceivePfringRegister();
875 TmModuleDecodePfringRegister();
876 /* dag file */
877 TmModuleReceiveErfFileRegister();
878 TmModuleDecodeErfFileRegister();
879 /* dag live */
880 TmModuleReceiveErfDagRegister();
881 TmModuleDecodeErfDagRegister();
882 /* napatech */
883 TmModuleNapatechStreamRegister();
884 TmModuleNapatechDecodeRegister();
885
886 /* flow worker */
887 TmModuleFlowWorkerRegister();
888 /* respond-reject */
889 TmModuleRespondRejectRegister();
890
891 /* log api */
892 TmModuleLoggerRegister();
893 TmModuleStatsLoggerRegister();
894
895 TmModuleDebugList();
896 /* nflog */
897 TmModuleReceiveNFLOGRegister();
898 TmModuleDecodeNFLOGRegister();
899
900 /* windivert */
901 TmModuleReceiveWinDivertRegister();
902 TmModuleVerdictWinDivertRegister();
903 TmModuleDecodeWinDivertRegister();
904 }
905
906 static TmEcode LoadYamlConfig(SCInstance *suri)
907 {
908 SCEnter();
909
910 if (suri->conf_filename == NULL)
911 suri->conf_filename = DEFAULT_CONF_FILE;
912
913 if (ConfYamlLoadFile(suri->conf_filename) != 0) {
914 /* Error already displayed. */
915 SCReturnInt(TM_ECODE_FAILED);
916 }
917
918 SCReturnInt(TM_ECODE_OK);
919 }
920
921 static TmEcode ParseInterfacesList(const int runmode, char *pcap_dev)
922 {
923 SCEnter();
924
925 /* run the selected runmode */
926 if (runmode == RUNMODE_PCAP_DEV) {
927 if (strlen(pcap_dev) == 0) {
928 int ret = LiveBuildDeviceList("pcap");
929 if (ret == 0) {
930 SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for pcap");
931 SCReturnInt(TM_ECODE_FAILED);
932 }
933 }
934 } else if (runmode == RUNMODE_PFRING) {
935 /* FIXME add backward compat support */
936 /* iface has been set on command line */
937 if (strlen(pcap_dev)) {
938 if (ConfSetFinal("pfring.live-interface", pcap_dev) != 1) {
939 SCLogError(SC_ERR_INITIALIZATION, "Failed to set pfring.live-interface");
940 SCReturnInt(TM_ECODE_FAILED);
941 }
942 } else {
943 /* not an error condition if we have a 1.0 config */
944 LiveBuildDeviceList("pfring");
945 }
946 #ifdef HAVE_AF_PACKET
947 } else if (runmode == RUNMODE_AFP_DEV) {
948 /* iface has been set on command line */
949 if (strlen(pcap_dev)) {
950 if (ConfSetFinal("af-packet.live-interface", pcap_dev) != 1) {
951 SCLogError(SC_ERR_INITIALIZATION, "Failed to set af-packet.live-interface");
952 SCReturnInt(TM_ECODE_FAILED);
953 }
954 } else {
955 int ret = LiveBuildDeviceList("af-packet");
956 if (ret == 0) {
957 SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for af-packet");
958 SCReturnInt(TM_ECODE_FAILED);
959 }
960 }
961 #endif
962 #ifdef HAVE_NETMAP
963 } else if (runmode == RUNMODE_NETMAP) {
964 /* iface has been set on command line */
965 if (strlen(pcap_dev)) {
966 if (ConfSetFinal("netmap.live-interface", pcap_dev) != 1) {
967 SCLogError(SC_ERR_INITIALIZATION, "Failed to set netmap.live-interface");
968 SCReturnInt(TM_ECODE_FAILED);
969 }
970 } else {
971 int ret = LiveBuildDeviceList("netmap");
972 if (ret == 0) {
973 SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for netmap");
974 SCReturnInt(TM_ECODE_FAILED);
975 }
976 }
977 #endif
978 #ifdef HAVE_NFLOG
979 } else if (runmode == RUNMODE_NFLOG) {
980 int ret = LiveBuildDeviceListCustom("nflog", "group");
981 if (ret == 0) {
982 SCLogError(SC_ERR_INITIALIZATION, "No group found in config for nflog");
983 SCReturnInt(TM_ECODE_FAILED);
984 }
985 #endif
986 }
987
988 SCReturnInt(TM_ECODE_OK);
989 }
990
991 static void SCInstanceInit(SCInstance *suri, const char *progname)
992 {
993 memset(suri, 0x00, sizeof(*suri));
994
995 suri->progname = progname;
996 suri->run_mode = RUNMODE_UNKNOWN;
997
998 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
999 suri->sig_file = NULL;
1000 suri->sig_file_exclusive = FALSE;
1001 suri->pid_filename = NULL;
1002 suri->regex_arg = NULL;
1003
1004 suri->keyword_info = NULL;
1005 suri->runmode_custom_mode = NULL;
1006 #ifndef OS_WIN32
1007 suri->user_name = NULL;
1008 suri->group_name = NULL;
1009 suri->do_setuid = FALSE;
1010 suri->do_setgid = FALSE;
1011 suri->userid = 0;
1012 suri->groupid = 0;
1013 #endif /* OS_WIN32 */
1014 suri->delayed_detect = 0;
1015 suri->daemon = 0;
1016 suri->offline = 0;
1017 suri->verbose = 0;
1018 /* use -1 as unknown */
1019 suri->checksum_validation = -1;
1020 #if HAVE_DETECT_DISABLED==1
1021 g_detect_disabled = suri->disabled_detect = 1;
1022 #else
1023 g_detect_disabled = suri->disabled_detect = 0;
1024 #endif
1025 }
1026
1027 const char *GetDocURL(void)
1028 {
1029 const char *prog_ver = GetProgramVersion();
1030 if (strstr(prog_ver, "RELEASE") != NULL) {
1031 return DOC_URL "suricata-" PROG_VER;
1032 }
1033 return DOC_URL "latest";
1034 }
1035
1036 /** \brief get string with program version
1037 *
1038 * Get the program version as passed to us from AC_INIT
1039 *
1040 * Add 'RELEASE' is no '-dev' in the version. Add the REVISION if passed
1041 * to us.
1042 *
1043 * Possible outputs:
1044 * release: '5.0.1 RELEASE'
1045 * dev with rev: '5.0.1-dev (64a789bbf 2019-10-18)'
1046 * dev w/o rev: '5.0.1-dev'
1047 */
1048 const char *GetProgramVersion(void)
1049 {
1050 if (strstr(PROG_VER, "-dev") == NULL) {
1051 return PROG_VER " RELEASE";
1052 } else {
1053 #ifdef REVISION
1054 return PROG_VER " (" xstr(REVISION) ")";
1055 #else
1056 return PROG_VER;
1057 #endif
1058 }
1059 }
1060
1061 static TmEcode PrintVersion(void)
1062 {
1063 printf("This is %s version %s\n", PROG_NAME, GetProgramVersion());
1064 return TM_ECODE_OK;
1065 }
1066
1067 static TmEcode LogVersion(SCInstance *suri)
1068 {
1069 const char *mode = suri->system ? "SYSTEM" : "USER";
1070 SCLogNotice("This is %s version %s running in %s mode",
1071 PROG_NAME, GetProgramVersion(), mode);
1072 return TM_ECODE_OK;
1073 }
1074
1075 static void SCSetStartTime(SCInstance *suri)
1076 {
1077 memset(&suri->start_time, 0, sizeof(suri->start_time));
1078 gettimeofday(&suri->start_time, NULL);
1079 }
1080
1081 static void SCPrintElapsedTime(struct timeval *start_time)
1082 {
1083 if (start_time == NULL)
1084 return;
1085 struct timeval end_time;
1086 memset(&end_time, 0, sizeof(end_time));
1087 gettimeofday(&end_time, NULL);
1088 uint64_t milliseconds = ((end_time.tv_sec - start_time->tv_sec) * 1000) +
1089 (((1000000 + end_time.tv_usec - start_time->tv_usec) / 1000) - 1000);
1090 SCLogInfo("time elapsed %.3fs", (float)milliseconds/(float)1000);
1091 }
1092
1093 static int ParseCommandLineAfpacket(SCInstance *suri, const char *in_arg)
1094 {
1095 #ifdef HAVE_AF_PACKET
1096 if (suri->run_mode == RUNMODE_UNKNOWN) {
1097 suri->run_mode = RUNMODE_AFP_DEV;
1098 if (in_arg) {
1099 LiveRegisterDeviceName(in_arg);
1100 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1101 strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
1102 }
1103 } else if (suri->run_mode == RUNMODE_AFP_DEV) {
1104 if (in_arg) {
1105 LiveRegisterDeviceName(in_arg);
1106 } else {
1107 SCLogInfo("Multiple af-packet option without interface on each is useless");
1108 }
1109 } else {
1110 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1111 "has been specified");
1112 PrintUsage(suri->progname);
1113 return TM_ECODE_FAILED;
1114 }
1115 return TM_ECODE_OK;
1116 #else
1117 SCLogError(SC_ERR_NO_AF_PACKET,"AF_PACKET not enabled. On Linux "
1118 "host, make sure to pass --enable-af-packet to "
1119 "configure when building.");
1120 return TM_ECODE_FAILED;
1121 #endif
1122 }
1123
1124 static int ParseCommandLinePcapLive(SCInstance *suri, const char *in_arg)
1125 {
1126 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1127
1128 if (in_arg != NULL) {
1129 /* some windows shells require escaping of the \ in \Device. Otherwise
1130 * the backslashes are stripped. We put them back here. */
1131 if (strlen(in_arg) > 9 && strncmp(in_arg, "DeviceNPF", 9) == 0) {
1132 snprintf(suri->pcap_dev, sizeof(suri->pcap_dev), "\\Device\\NPF%s", in_arg+9);
1133 } else {
1134 strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
1135 PcapTranslateIPToDevice(suri->pcap_dev, sizeof(suri->pcap_dev));
1136 }
1137
1138 if (strcmp(suri->pcap_dev, in_arg) != 0) {
1139 SCLogInfo("translated %s to pcap device %s", in_arg, suri->pcap_dev);
1140 } else if (strlen(suri->pcap_dev) > 0 && isdigit((unsigned char)suri->pcap_dev[0])) {
1141 SCLogError(SC_ERR_PCAP_TRANSLATE, "failed to find a pcap device for IP %s", in_arg);
1142 return TM_ECODE_FAILED;
1143 }
1144 }
1145
1146 if (suri->run_mode == RUNMODE_UNKNOWN) {
1147 suri->run_mode = RUNMODE_PCAP_DEV;
1148 if (in_arg) {
1149 LiveRegisterDeviceName(suri->pcap_dev);
1150 }
1151 } else if (suri->run_mode == RUNMODE_PCAP_DEV) {
1152 LiveRegisterDeviceName(suri->pcap_dev);
1153 } else {
1154 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1155 "has been specified");
1156 PrintUsage(suri->progname);
1157 return TM_ECODE_FAILED;
1158 }
1159 return TM_ECODE_OK;
1160 }
1161
1162 /**
1163 * Helper function to check if log directory is writable
1164 */
1165 static bool IsLogDirectoryWritable(const char* str)
1166 {
1167 if (access(str, W_OK) == 0)
1168 return true;
1169 return false;
1170 }
1171
1172 static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
1173 {
1174 int opt;
1175
1176 int dump_config = 0;
1177 int dump_features = 0;
1178 int list_app_layer_protocols = 0;
1179 int list_unittests = 0;
1180 int list_runmodes = 0;
1181 int list_keywords = 0;
1182 int build_info = 0;
1183 int conf_test = 0;
1184 int engine_analysis = 0;
1185 int ret = TM_ECODE_OK;
1186
1187 #ifdef UNITTESTS
1188 coverage_unittests = 0;
1189 g_ut_modules = 0;
1190 g_ut_covered = 0;
1191 #endif
1192
1193 struct option long_opts[] = {
1194 {"dump-config", 0, &dump_config, 1},
1195 {"dump-features", 0, &dump_features, 1},
1196 {"pfring", optional_argument, 0, 0},
1197 {"pfring-int", required_argument, 0, 0},
1198 {"pfring-cluster-id", required_argument, 0, 0},
1199 {"pfring-cluster-type", required_argument, 0, 0},
1200 {"af-packet", optional_argument, 0, 0},
1201 {"netmap", optional_argument, 0, 0},
1202 {"pcap", optional_argument, 0, 0},
1203 {"pcap-file-continuous", 0, 0, 0},
1204 {"pcap-file-delete", 0, 0, 0},
1205 {"pcap-file-recursive", 0, 0, 0},
1206 {"simulate-ips", 0, 0 , 0},
1207 {"no-random", 0, &g_disable_randomness, 1},
1208 {"strict-rule-keywords", optional_argument, 0, 0},
1209
1210 {"capture-plugin", required_argument, 0, 0},
1211 {"capture-plugin-args", required_argument, 0, 0},
1212
1213 #ifdef BUILD_UNIX_SOCKET
1214 {"unix-socket", optional_argument, 0, 0},
1215 #endif
1216 {"pcap-buffer-size", required_argument, 0, 0},
1217 {"unittest-filter", required_argument, 0, 'U'},
1218 {"list-app-layer-protos", 0, &list_app_layer_protocols, 1},
1219 {"list-unittests", 0, &list_unittests, 1},
1220 {"list-runmodes", 0, &list_runmodes, 1},
1221 {"list-keywords", optional_argument, &list_keywords, 1},
1222 {"runmode", required_argument, NULL, 0},
1223 {"engine-analysis", 0, &engine_analysis, 1},
1224 #ifdef OS_WIN32
1225 {"service-install", 0, 0, 0},
1226 {"service-remove", 0, 0, 0},
1227 {"service-change-params", 0, 0, 0},
1228 #endif /* OS_WIN32 */
1229 {"pidfile", required_argument, 0, 0},
1230 {"init-errors-fatal", 0, 0, 0},
1231 {"disable-detection", 0, 0, 0},
1232 {"fatal-unittests", 0, 0, 0},
1233 {"unittests-coverage", 0, &coverage_unittests, 1},
1234 {"user", required_argument, 0, 0},
1235 {"group", required_argument, 0, 0},
1236 {"erf-in", required_argument, 0, 0},
1237 {"dag", required_argument, 0, 0},
1238 {"napatech", 0, 0, 0},
1239 {"build-info", 0, &build_info, 1},
1240 {"data-dir", required_argument, 0, 0},
1241 #ifdef WINDIVERT
1242 {"windivert", required_argument, 0, 0},
1243 {"windivert-forward", required_argument, 0, 0},
1244 #endif
1245 #ifdef HAVE_LIBNET11
1246 {"reject-dev", required_argument, 0, 0},
1247 #endif
1248 {"set", required_argument, 0, 0},
1249 #ifdef HAVE_NFLOG
1250 {"nflog", optional_argument, 0, 0},
1251 #endif
1252 {NULL, 0, NULL, 0}
1253 };
1254
1255 /* getopt_long stores the option index here. */
1256 int option_index = 0;
1257
1258 char short_opts[] = "c:TDhi:l:q:d:r:us:S:U:VF:vk:";
1259
1260 while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) {
1261 switch (opt) {
1262 case 0:
1263 if (strcmp((long_opts[option_index]).name , "pfring") == 0 ||
1264 strcmp((long_opts[option_index]).name , "pfring-int") == 0) {
1265 #ifdef HAVE_PFRING
1266 suri->run_mode = RUNMODE_PFRING;
1267 if (optarg != NULL) {
1268 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1269 strlcpy(suri->pcap_dev, optarg,
1270 ((strlen(optarg) < sizeof(suri->pcap_dev)) ?
1271 (strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
1272 LiveRegisterDeviceName(optarg);
1273 }
1274 #else
1275 SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
1276 "to pass --enable-pfring to configure when building.");
1277 return TM_ECODE_FAILED;
1278 #endif /* HAVE_PFRING */
1279 }
1280 else if(strcmp((long_opts[option_index]).name , "pfring-cluster-id") == 0){
1281 #ifdef HAVE_PFRING
1282 if (ConfSetFinal("pfring.cluster-id", optarg) != 1) {
1283 fprintf(stderr, "ERROR: Failed to set pfring.cluster-id.\n");
1284 return TM_ECODE_FAILED;
1285 }
1286 #else
1287 SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
1288 "to pass --enable-pfring to configure when building.");
1289 return TM_ECODE_FAILED;
1290 #endif /* HAVE_PFRING */
1291 }
1292 else if(strcmp((long_opts[option_index]).name , "pfring-cluster-type") == 0){
1293 #ifdef HAVE_PFRING
1294 if (ConfSetFinal("pfring.cluster-type", optarg) != 1) {
1295 fprintf(stderr, "ERROR: Failed to set pfring.cluster-type.\n");
1296 return TM_ECODE_FAILED;
1297 }
1298 #else
1299 SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
1300 "to pass --enable-pfring to configure when building.");
1301 return TM_ECODE_FAILED;
1302 #endif /* HAVE_PFRING */
1303 }
1304 else if (strcmp((long_opts[option_index]).name , "capture-plugin") == 0){
1305 suri->run_mode = RUNMODE_PLUGIN;
1306 suri->capture_plugin_name = optarg;
1307 }
1308 else if (strcmp((long_opts[option_index]).name , "capture-plugin-args") == 0){
1309 suri->capture_plugin_args = optarg;
1310 }
1311 else if (strcmp((long_opts[option_index]).name , "af-packet") == 0)
1312 {
1313 if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
1314 return TM_ECODE_FAILED;
1315 }
1316 } else if (strcmp((long_opts[option_index]).name , "netmap") == 0){
1317 #ifdef HAVE_NETMAP
1318 if (suri->run_mode == RUNMODE_UNKNOWN) {
1319 suri->run_mode = RUNMODE_NETMAP;
1320 if (optarg) {
1321 LiveRegisterDeviceName(optarg);
1322 memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1323 strlcpy(suri->pcap_dev, optarg,
1324 ((strlen(optarg) < sizeof(suri->pcap_dev)) ?
1325 (strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
1326 }
1327 } else if (suri->run_mode == RUNMODE_NETMAP) {
1328 if (optarg) {
1329 LiveRegisterDeviceName(optarg);
1330 } else {
1331 SCLogInfo("Multiple netmap option without interface on each is useless");
1332 break;
1333 }
1334 } else {
1335 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1336 "has been specified");
1337 PrintUsage(argv[0]);
1338 return TM_ECODE_FAILED;
1339 }
1340 #else
1341 SCLogError(SC_ERR_NO_NETMAP, "NETMAP not enabled.");
1342 return TM_ECODE_FAILED;
1343 #endif
1344 } else if (strcmp((long_opts[option_index]).name, "nflog") == 0) {
1345 #ifdef HAVE_NFLOG
1346 if (suri->run_mode == RUNMODE_UNKNOWN) {
1347 suri->run_mode = RUNMODE_NFLOG;
1348 LiveBuildDeviceListCustom("nflog", "group");
1349 }
1350 #else
1351 SCLogError(SC_ERR_NFLOG_NOSUPPORT, "NFLOG not enabled.");
1352 return TM_ECODE_FAILED;
1353 #endif /* HAVE_NFLOG */
1354 } else if (strcmp((long_opts[option_index]).name , "pcap") == 0) {
1355 if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
1356 return TM_ECODE_FAILED;
1357 }
1358 } else if(strcmp((long_opts[option_index]).name, "simulate-ips") == 0) {
1359 SCLogInfo("Setting IPS mode");
1360 EngineModeSetIPS();
1361 } else if(strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) {
1362 if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) {
1363 fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n");
1364 return TM_ECODE_FAILED;
1365 }
1366 #ifdef BUILD_UNIX_SOCKET
1367 } else if (strcmp((long_opts[option_index]).name , "unix-socket") == 0) {
1368 if (suri->run_mode == RUNMODE_UNKNOWN) {
1369 suri->run_mode = RUNMODE_UNIX_SOCKET;
1370 if (optarg) {
1371 if (ConfSetFinal("unix-command.filename", optarg) != 1) {
1372 fprintf(stderr, "ERROR: Failed to set unix-command.filename.\n");
1373 return TM_ECODE_FAILED;
1374 }
1375
1376 }
1377 } else {
1378 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1379 "has been specified");
1380 PrintUsage(argv[0]);
1381 return TM_ECODE_FAILED;
1382 }
1383 #endif
1384 }
1385 else if(strcmp((long_opts[option_index]).name, "list-app-layer-protocols") == 0) {
1386 /* listing all supported app layer protocols */
1387 }
1388 else if(strcmp((long_opts[option_index]).name, "list-unittests") == 0) {
1389 #ifdef UNITTESTS
1390 suri->run_mode = RUNMODE_LIST_UNITTEST;
1391 #else
1392 fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
1393 return TM_ECODE_FAILED;
1394 #endif /* UNITTESTS */
1395 } else if (strcmp((long_opts[option_index]).name, "list-runmodes") == 0) {
1396 suri->run_mode = RUNMODE_LIST_RUNMODES;
1397 return TM_ECODE_OK;
1398 } else if (strcmp((long_opts[option_index]).name, "list-keywords") == 0) {
1399 if (optarg) {
1400 if (strcmp("short",optarg)) {
1401 suri->keyword_info = optarg;
1402 }
1403 }
1404 } else if (strcmp((long_opts[option_index]).name, "runmode") == 0) {
1405 suri->runmode_custom_mode = optarg;
1406 } else if(strcmp((long_opts[option_index]).name, "engine-analysis") == 0) {
1407 // do nothing for now
1408 }
1409 #ifdef OS_WIN32
1410 else if(strcmp((long_opts[option_index]).name, "service-install") == 0) {
1411 suri->run_mode = RUNMODE_INSTALL_SERVICE;
1412 return TM_ECODE_OK;
1413 }
1414 else if(strcmp((long_opts[option_index]).name, "service-remove") == 0) {
1415 suri->run_mode = RUNMODE_REMOVE_SERVICE;
1416 return TM_ECODE_OK;
1417 }
1418 else if(strcmp((long_opts[option_index]).name, "service-change-params") == 0) {
1419 suri->run_mode = RUNMODE_CHANGE_SERVICE_PARAMS;
1420 return TM_ECODE_OK;
1421 }
1422 #endif /* OS_WIN32 */
1423 else if(strcmp((long_opts[option_index]).name, "pidfile") == 0) {
1424 suri->pid_filename = SCStrdup(optarg);
1425 if (suri->pid_filename == NULL) {
1426 SCLogError(SC_ERR_MEM_ALLOC, "strdup failed: %s",
1427 strerror(errno));
1428 return TM_ECODE_FAILED;
1429 }
1430 }
1431 else if(strcmp((long_opts[option_index]).name, "disable-detection") == 0) {
1432 g_detect_disabled = suri->disabled_detect = 1;
1433 }
1434 else if(strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) {
1435 #ifdef UNITTESTS
1436 unittests_fatal = 1;
1437 #else
1438 fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
1439 return TM_ECODE_FAILED;
1440 #endif /* UNITTESTS */
1441 }
1442 else if(strcmp((long_opts[option_index]).name, "user") == 0) {
1443 #ifndef HAVE_LIBCAP_NG
1444 SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to"
1445 " drop privileges, but it was not compiled into Suricata.");
1446 return TM_ECODE_FAILED;
1447 #else
1448 suri->user_name = optarg;
1449 suri->do_setuid = TRUE;
1450 #endif /* HAVE_LIBCAP_NG */
1451 }
1452 else if(strcmp((long_opts[option_index]).name, "group") == 0) {
1453 #ifndef HAVE_LIBCAP_NG
1454 SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to"
1455 " drop privileges, but it was not compiled into Suricata.");
1456 return TM_ECODE_FAILED;
1457 #else
1458 suri->group_name = optarg;
1459 suri->do_setgid = TRUE;
1460 #endif /* HAVE_LIBCAP_NG */
1461 }
1462 else if (strcmp((long_opts[option_index]).name, "erf-in") == 0) {
1463 suri->run_mode = RUNMODE_ERF_FILE;
1464 if (ConfSetFinal("erf-file.file", optarg) != 1) {
1465 fprintf(stderr, "ERROR: Failed to set erf-file.file\n");
1466 return TM_ECODE_FAILED;
1467 }
1468 }
1469 else if (strcmp((long_opts[option_index]).name, "dag") == 0) {
1470 #ifdef HAVE_DAG
1471 if (suri->run_mode == RUNMODE_UNKNOWN) {
1472 suri->run_mode = RUNMODE_DAG;
1473 }
1474 else if (suri->run_mode != RUNMODE_DAG) {
1475 SCLogError(SC_ERR_MULTIPLE_RUN_MODE,
1476 "more than one run mode has been specified");
1477 PrintUsage(argv[0]);
1478 return TM_ECODE_FAILED;
1479 }
1480 LiveRegisterDeviceName(optarg);
1481 #else
1482 SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required"
1483 " to receive packets using --dag.");
1484 return TM_ECODE_FAILED;
1485 #endif /* HAVE_DAG */
1486 } else if (strcmp((long_opts[option_index]).name, "napatech") == 0) {
1487 #ifdef HAVE_NAPATECH
1488 suri->run_mode = RUNMODE_NAPATECH;
1489 #else
1490 SCLogError(SC_ERR_NAPATECH_REQUIRED, "libntapi and a Napatech adapter are required"
1491 " to capture packets using --napatech.");
1492 return TM_ECODE_FAILED;
1493 #endif /* HAVE_NAPATECH */
1494 } else if (strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) {
1495 #ifdef HAVE_PCAP_SET_BUFF
1496 if (ConfSetFinal("pcap.buffer-size", optarg) != 1) {
1497 fprintf(stderr, "ERROR: Failed to set pcap-buffer-size.\n");
1498 return TM_ECODE_FAILED;
1499 }
1500 #else
1501 SCLogError(SC_ERR_NO_PCAP_SET_BUFFER_SIZE, "The version of libpcap you have"
1502 " doesn't support setting buffer size.");
1503 #endif /* HAVE_PCAP_SET_BUFF */
1504 } else if (strcmp((long_opts[option_index]).name, "build-info") == 0) {
1505 suri->run_mode = RUNMODE_PRINT_BUILDINFO;
1506 return TM_ECODE_OK;
1507 } else if (strcmp((long_opts[option_index]).name, "windivert-forward") == 0) {
1508 #ifdef WINDIVERT
1509 if (suri->run_mode == RUNMODE_UNKNOWN) {
1510 suri->run_mode = RUNMODE_WINDIVERT;
1511 if (WinDivertRegisterQueue(true, optarg) == -1) {
1512 exit(EXIT_FAILURE);
1513 }
1514 } else if (suri->run_mode == RUNMODE_WINDIVERT) {
1515 if (WinDivertRegisterQueue(true, optarg) == -1) {
1516 exit(EXIT_FAILURE);
1517 }
1518 } else {
1519 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1520 "has been specified");
1521 PrintUsage(argv[0]);
1522 exit(EXIT_FAILURE);
1523 }
1524 }
1525 else if(strcmp((long_opts[option_index]).name, "windivert") == 0) {
1526 if (suri->run_mode == RUNMODE_UNKNOWN) {
1527 suri->run_mode = RUNMODE_WINDIVERT;
1528 if (WinDivertRegisterQueue(false, optarg) == -1) {
1529 exit(EXIT_FAILURE);
1530 }
1531 } else if (suri->run_mode == RUNMODE_WINDIVERT) {
1532 if (WinDivertRegisterQueue(false, optarg) == -1) {
1533 exit(EXIT_FAILURE);
1534 }
1535 } else {
1536 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1537 "has been specified");
1538 PrintUsage(argv[0]);
1539 exit(EXIT_FAILURE);
1540 }
1541 #else
1542 SCLogError(SC_ERR_WINDIVERT_NOSUPPORT,"WinDivert not enabled. Make sure to pass --enable-windivert to configure when building.");
1543 return TM_ECODE_FAILED;
1544 #endif /* WINDIVERT */
1545 } else if(strcmp((long_opts[option_index]).name, "reject-dev") == 0) {
1546 #ifdef HAVE_LIBNET11
1547 BUG_ON(optarg == NULL); /* for static analysis */
1548 extern char *g_reject_dev;
1549 extern uint16_t g_reject_dev_mtu;
1550 g_reject_dev = optarg;
1551 int mtu = GetIfaceMTU(g_reject_dev);
1552 if (mtu > 0) {
1553 g_reject_dev_mtu = (uint16_t)mtu;
1554 }
1555 #else
1556 SCLogError(SC_ERR_LIBNET_NOT_ENABLED,
1557 "Libnet 1.1 support not enabled. Compile Suricata with libnet support.");
1558 return TM_ECODE_FAILED;
1559 #endif
1560 }
1561 else if (strcmp((long_opts[option_index]).name, "set") == 0) {
1562 if (optarg != NULL) {
1563 /* Quick validation. */
1564 char *val = strchr(optarg, '=');
1565 if (val == NULL) {
1566 FatalError(SC_ERR_FATAL,
1567 "Invalid argument for --set, must be key=val.");
1568 }
1569 if (!ConfSetFromString(optarg, 1)) {
1570 fprintf(stderr, "Failed to set configuration value %s.",
1571 optarg);
1572 exit(EXIT_FAILURE);
1573 }
1574 }
1575 }
1576 else if (strcmp((long_opts[option_index]).name, "pcap-file-continuous") == 0) {
1577 if (ConfSetFinal("pcap-file.continuous", "true") != 1) {
1578 SCLogError(SC_ERR_CMD_LINE, "Failed to set pcap-file.continuous");
1579 return TM_ECODE_FAILED;
1580 }
1581 }
1582 else if (strcmp((long_opts[option_index]).name, "pcap-file-delete") == 0) {
1583 if (ConfSetFinal("pcap-file.delete-when-done", "true") != 1) {
1584 SCLogError(SC_ERR_CMD_LINE, "Failed to set pcap-file.delete-when-done");
1585 return TM_ECODE_FAILED;
1586 }
1587 }
1588 else if (strcmp((long_opts[option_index]).name, "pcap-file-recursive") == 0) {
1589 if (ConfSetFinal("pcap-file.recursive", "true") != 1) {
1590 SCLogError(SC_ERR_CMD_LINE, "ERROR: Failed to set pcap-file.recursive");
1591 return TM_ECODE_FAILED;
1592 }
1593 }
1594 else if (strcmp((long_opts[option_index]).name, "data-dir") == 0) {
1595 if (optarg == NULL) {
1596 SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -d");
1597 return TM_ECODE_FAILED;
1598 }
1599
1600 if (ConfigSetDataDirectory(optarg) != TM_ECODE_OK) {
1601 SCLogError(SC_ERR_FATAL, "Failed to set data directory.");
1602 return TM_ECODE_FAILED;
1603 }
1604 if (ConfigCheckDataDirectory(optarg) != TM_ECODE_OK) {
1605 SCLogError(SC_ERR_LOGDIR_CMDLINE, "The data directory \"%s\""
1606 " supplied at the commandline (-d %s) doesn't "
1607 "exist. Shutting down the engine.", optarg, optarg);
1608 return TM_ECODE_FAILED;
1609 }
1610 suri->set_datadir = true;
1611 } else if (strcmp((long_opts[option_index]).name , "strict-rule-keywords") == 0){
1612 if (optarg == NULL) {
1613 suri->strict_rule_parsing_string = SCStrdup("all");
1614 } else {
1615 suri->strict_rule_parsing_string = SCStrdup(optarg);
1616 }
1617 if (suri->strict_rule_parsing_string == NULL) {
1618 FatalError(SC_ERR_MEM_ALLOC, "failed to duplicate 'strict' string");
1619 }
1620 }
1621 break;
1622 case 'c':
1623 suri->conf_filename = optarg;
1624 break;
1625 case 'T':
1626 SCLogInfo("Running suricata under test mode");
1627 conf_test = 1;
1628 if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) {
1629 fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n");
1630 return TM_ECODE_FAILED;
1631 }
1632 break;
1633 #ifndef OS_WIN32
1634 case 'D':
1635 suri->daemon = 1;
1636 break;
1637 #endif /* OS_WIN32 */
1638 case 'h':
1639 suri->run_mode = RUNMODE_PRINT_USAGE;
1640 return TM_ECODE_OK;
1641 case 'i':
1642 if (optarg == NULL) {
1643 SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -i");
1644 return TM_ECODE_FAILED;
1645 }
1646 #ifdef HAVE_AF_PACKET
1647 if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
1648 return TM_ECODE_FAILED;
1649 }
1650 #else /* not afpacket */
1651 /* warn user if netmap or pf-ring are available */
1652 #if defined HAVE_PFRING || HAVE_NETMAP
1653 int i = 0;
1654 #ifdef HAVE_PFRING
1655 i++;
1656 #endif
1657 #ifdef HAVE_NETMAP
1658 i++;
1659 #endif
1660 SCLogWarning(SC_WARN_FASTER_CAPTURE_AVAILABLE, "faster capture "
1661 "option%s %s available:"
1662 #ifdef HAVE_PFRING
1663 " PF_RING (--pfring-int=%s)"
1664 #endif
1665 #ifdef HAVE_NETMAP
1666 " NETMAP (--netmap=%s)"
1667 #endif
1668 ". Use --pcap=%s to suppress this warning",
1669 i == 1 ? "" : "s", i == 1 ? "is" : "are"
1670 #ifdef HAVE_PFRING
1671 , optarg
1672 #endif
1673 #ifdef HAVE_NETMAP
1674 , optarg
1675 #endif
1676 , optarg
1677 );
1678 #endif /* have faster methods */
1679 if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
1680 return TM_ECODE_FAILED;
1681 }
1682 #endif
1683 break;
1684 case 'l':
1685 if (optarg == NULL) {
1686 SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -l");
1687 return TM_ECODE_FAILED;
1688 }
1689
1690 if (ConfigSetLogDirectory(optarg) != TM_ECODE_OK) {
1691 SCLogError(SC_ERR_FATAL, "Failed to set log directory.");
1692 return TM_ECODE_FAILED;
1693 }
1694 if (ConfigCheckLogDirectoryExists(optarg) != TM_ECODE_OK) {
1695 SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\""
1696 " supplied at the commandline (-l %s) doesn't "
1697 "exist. Shutting down the engine.", optarg, optarg);
1698 return TM_ECODE_FAILED;
1699 }
1700 if (!IsLogDirectoryWritable(optarg)) {
1701 SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\""
1702 " supplied at the commandline (-l %s) is not "
1703 "writable. Shutting down the engine.", optarg, optarg);
1704 return TM_ECODE_FAILED;
1705 }
1706 suri->set_logdir = true;
1707
1708 break;
1709 case 'q':
1710 #ifdef NFQ
1711 if (suri->run_mode == RUNMODE_UNKNOWN) {
1712 suri->run_mode = RUNMODE_NFQ;
1713 EngineModeSetIPS();
1714 if (NFQParseAndRegisterQueues(optarg) == -1)
1715 return TM_ECODE_FAILED;
1716 } else if (suri->run_mode == RUNMODE_NFQ) {
1717 if (NFQParseAndRegisterQueues(optarg) == -1)
1718 return TM_ECODE_FAILED;
1719 } else {
1720 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1721 "has been specified");
1722 PrintUsage(argv[0]);
1723 return TM_ECODE_FAILED;
1724 }
1725 #else
1726 SCLogError(SC_ERR_NFQ_NOSUPPORT,"NFQUEUE not enabled. Make sure to pass --enable-nfqueue to configure when building.");
1727 return TM_ECODE_FAILED;
1728 #endif /* NFQ */
1729 break;
1730 case 'd':
1731 #ifdef IPFW
1732 if (suri->run_mode == RUNMODE_UNKNOWN) {
1733 suri->run_mode = RUNMODE_IPFW;
1734 EngineModeSetIPS();
1735 if (IPFWRegisterQueue(optarg) == -1)
1736 return TM_ECODE_FAILED;
1737 } else if (suri->run_mode == RUNMODE_IPFW) {
1738 if (IPFWRegisterQueue(optarg) == -1)
1739 return TM_ECODE_FAILED;
1740 } else {
1741 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1742 "has been specified");
1743 PrintUsage(argv[0]);
1744 return TM_ECODE_FAILED;
1745 }
1746 #else
1747 SCLogError(SC_ERR_IPFW_NOSUPPORT,"IPFW not enabled. Make sure to pass --enable-ipfw to configure when building.");
1748 return TM_ECODE_FAILED;
1749 #endif /* IPFW */
1750 break;
1751 case 'r':
1752 BUG_ON(optarg == NULL); /* for static analysis */
1753 if (suri->run_mode == RUNMODE_UNKNOWN) {
1754 suri->run_mode = RUNMODE_PCAP_FILE;
1755 } else {
1756 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1757 "has been specified");
1758 PrintUsage(argv[0]);
1759 return TM_ECODE_FAILED;
1760 }
1761 #ifdef OS_WIN32
1762 struct _stat buf;
1763 if(_stat(optarg, &buf) != 0) {
1764 #else
1765 struct stat buf;
1766 if (stat(optarg, &buf) != 0) {
1767 #endif /* OS_WIN32 */
1768 SCLogError(SC_ERR_INITIALIZATION, "ERROR: Pcap file does not exist\n");
1769 return TM_ECODE_FAILED;
1770 }
1771 if (ConfSetFinal("pcap-file.file", optarg) != 1) {
1772 SCLogError(SC_ERR_INITIALIZATION, "ERROR: Failed to set pcap-file.file\n");
1773 return TM_ECODE_FAILED;
1774 }
1775
1776 break;
1777 case 's':
1778 if (suri->sig_file != NULL) {
1779 SCLogError(SC_ERR_CMD_LINE, "can't have multiple -s options or mix -s and -S.");
1780 return TM_ECODE_FAILED;
1781 }
1782 suri->sig_file = optarg;
1783 break;
1784 case 'S':
1785 if (suri->sig_file != NULL) {
1786 SCLogError(SC_ERR_CMD_LINE, "can't have multiple -S options or mix -s and -S.");
1787 return TM_ECODE_FAILED;
1788 }
1789 suri->sig_file = optarg;
1790 suri->sig_file_exclusive = TRUE;
1791 break;
1792 case 'u':
1793 #ifdef UNITTESTS
1794 if (suri->run_mode == RUNMODE_UNKNOWN) {
1795 suri->run_mode = RUNMODE_UNITTEST;
1796 } else {
1797 SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode has"
1798 " been specified");
1799 PrintUsage(argv[0]);
1800 return TM_ECODE_FAILED;
1801 }
1802 #else
1803 fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
1804 return TM_ECODE_FAILED;
1805 #endif /* UNITTESTS */
1806 break;
1807 case 'U':
1808 #ifdef UNITTESTS
1809 suri->regex_arg = optarg;
1810
1811 if(strlen(suri->regex_arg) == 0)
1812 suri->regex_arg = NULL;
1813 #endif
1814 break;
1815 case 'V':
1816 suri->run_mode = RUNMODE_PRINT_VERSION;
1817 return TM_ECODE_OK;
1818 case 'F':
1819 if (optarg == NULL) {
1820 SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -F");
1821 return TM_ECODE_FAILED;
1822 }
1823
1824 SetBpfStringFromFile(optarg);
1825 break;
1826 case 'v':
1827 suri->verbose++;
1828 break;
1829 case 'k':
1830 if (optarg == NULL) {
1831 SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -k");
1832 return TM_ECODE_FAILED;
1833 }
1834 if (!strcmp("all", optarg))
1835 suri->checksum_validation = 1;
1836 else if (!strcmp("none", optarg))
1837 suri->checksum_validation = 0;
1838 else {
1839 SCLogError(SC_ERR_INITIALIZATION, "option '%s' invalid for -k", optarg);
1840 return TM_ECODE_FAILED;
1841 }
1842 break;
1843 default:
1844 PrintUsage(argv[0]);
1845 return TM_ECODE_FAILED;
1846 }
1847 }
1848
1849 if (suri->disabled_detect && suri->sig_file != NULL) {
1850 SCLogError(SC_ERR_INITIALIZATION, "can't use -s/-S when detection is disabled");
1851 return TM_ECODE_FAILED;
1852 }
1853
1854 if ((suri->run_mode == RUNMODE_UNIX_SOCKET) && suri->set_logdir) {
1855 SCLogError(SC_ERR_INITIALIZATION,
1856 "can't use -l and unix socket runmode at the same time");
1857 return TM_ECODE_FAILED;
1858 }
1859
1860 /* save the runmode from the commandline (if any) */
1861 suri->aux_run_mode = suri->run_mode;
1862
1863 if (list_app_layer_protocols)
1864 suri->run_mode = RUNMODE_LIST_APP_LAYERS;
1865 if (list_keywords)
1866 suri->run_mode = RUNMODE_LIST_KEYWORDS;
1867 if (list_unittests)
1868 suri->run_mode = RUNMODE_LIST_UNITTEST;
1869 if (dump_config)
1870 suri->run_mode = RUNMODE_DUMP_CONFIG;
1871 if (dump_features)
1872 suri->run_mode = RUNMODE_DUMP_FEATURES;
1873 if (conf_test)
1874 suri->run_mode = RUNMODE_CONF_TEST;
1875 if (engine_analysis)
1876 suri->run_mode = RUNMODE_ENGINE_ANALYSIS;
1877
1878 suri->offline = IsRunModeOffline(suri->run_mode);
1879 g_system = suri->system = IsRunModeSystem(suri->run_mode);
1880
1881 ret = SetBpfString(optind, argv);
1882 if (ret != TM_ECODE_OK)
1883 return ret;
1884
1885 return TM_ECODE_OK;
1886 }
1887
1888 #ifdef OS_WIN32
1889 static int WindowsInitService(int argc, char **argv)
1890 {
1891 if (SCRunningAsService()) {
1892 char path[MAX_PATH];
1893 char *p = NULL;
1894 strlcpy(path, argv[0], MAX_PATH);
1895 if ((p = strrchr(path, '\\'))) {
1896 *p = '\0';
1897 }
1898 if (!SetCurrentDirectory(path)) {
1899 SCLogError(SC_ERR_FATAL, "Can't set current directory to: %s", path);
1900 return -1;
1901 }
1902 SCLogInfo("Current directory is set to: %s", path);
1903 SCServiceInit(argc, argv);
1904 }
1905
1906 /* Windows socket subsystem initialization */
1907 WSADATA wsaData;
1908 if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) {
1909 SCLogError(SC_ERR_FATAL, "Can't initialize Windows sockets: %d", WSAGetLastError());
1910 return -1;
1911 }
1912
1913 return 0;
1914 }
1915 #endif /* OS_WIN32 */
1916
1917 static int MayDaemonize(SCInstance *suri)
1918 {
1919 if (suri->daemon == 1 && suri->pid_filename == NULL) {
1920 const char *pid_filename;
1921
1922 if (ConfGet("pid-file", &pid_filename) == 1) {
1923 SCLogInfo("Use pid file %s from config file.", pid_filename);
1924 } else {
1925 pid_filename = DEFAULT_PID_FILENAME;
1926 }
1927 /* The pid file name may be in config memory, but is needed later. */
1928 suri->pid_filename = SCStrdup(pid_filename);
1929 if (suri->pid_filename == NULL) {
1930 SCLogError(SC_ERR_MEM_ALLOC, "strdup failed: %s", strerror(errno));
1931 return TM_ECODE_FAILED;
1932 }
1933 }
1934
1935 if (suri->pid_filename != NULL && SCPidfileTestRunning(suri->pid_filename) != 0) {
1936 SCFree(suri->pid_filename);
1937 suri->pid_filename = NULL;
1938 return TM_ECODE_FAILED;
1939 }
1940
1941 if (suri->daemon == 1) {
1942 Daemonize();
1943 }
1944
1945 if (suri->pid_filename != NULL) {
1946 if (SCPidfileCreate(suri->pid_filename) != 0) {
1947 SCFree(suri->pid_filename);
1948 suri->pid_filename = NULL;
1949 SCLogError(SC_ERR_PIDFILE_DAEMON,
1950 "Unable to create PID file, concurrent run of"
1951 " Suricata can occur.");
1952 SCLogError(SC_ERR_PIDFILE_DAEMON,
1953 "PID file creation WILL be mandatory for daemon mode"
1954 " in future version");
1955 }
1956 }
1957
1958 return TM_ECODE_OK;
1959 }
1960
1961 static int InitSignalHandler(SCInstance *suri)
1962 {
1963 /* registering signals we use */
1964 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1965 UtilSignalHandlerSetup(SIGINT, SignalHandlerSigint);
1966 UtilSignalHandlerSetup(SIGTERM, SignalHandlerSigterm);
1967 #endif
1968 #ifndef OS_WIN32
1969 UtilSignalHandlerSetup(SIGHUP, SignalHandlerSigHup);
1970 UtilSignalHandlerSetup(SIGPIPE, SIG_IGN);
1971 UtilSignalHandlerSetup(SIGSYS, SIG_IGN);
1972
1973 /* Try to get user/group to run suricata as if
1974 command line as not decide of that */
1975 if (suri->do_setuid == FALSE && suri->do_setgid == FALSE) {
1976 const char *id;
1977 if (ConfGet("run-as.user", &id) == 1) {
1978 suri->do_setuid = TRUE;
1979 suri->user_name = id;
1980 }
1981 if (ConfGet("run-as.group", &id) == 1) {
1982 suri->do_setgid = TRUE;
1983 suri->group_name = id;
1984 }
1985 }
1986 /* Get the suricata user ID to given user ID */
1987 if (suri->do_setuid == TRUE) {
1988 if (SCGetUserID(suri->user_name, suri->group_name,
1989 &suri->userid, &suri->groupid) != 0) {
1990 SCLogError(SC_ERR_UID_FAILED, "failed in getting user ID");
1991 return TM_ECODE_FAILED;
1992 }
1993
1994 sc_set_caps = TRUE;
1995 /* Get the suricata group ID to given group ID */
1996 } else if (suri->do_setgid == TRUE) {
1997 if (SCGetGroupID(suri->group_name, &suri->groupid) != 0) {
1998 SCLogError(SC_ERR_GID_FAILED, "failed in getting group ID");
1999 return TM_ECODE_FAILED;
2000 }
2001
2002 sc_set_caps = TRUE;
2003 }
2004 #endif /* OS_WIN32 */
2005
2006 return TM_ECODE_OK;
2007 }
2008
2009 /* initialization code for both the main modes and for
2010 * unix socket mode.
2011 *
2012 * Will be run once per pcap in unix-socket mode */
2013 void PreRunInit(const int runmode)
2014 {
2015 /* Initialize Datasets to be able to use them with unix socket */
2016 DatasetsInit();
2017 if (runmode == RUNMODE_UNIX_SOCKET)
2018 return;
2019
2020 StatsInit();
2021 #ifdef PROFILING
2022 SCProfilingRulesGlobalInit();
2023 SCProfilingKeywordsGlobalInit();
2024 SCProfilingPrefilterGlobalInit();
2025 SCProfilingSghsGlobalInit();
2026 SCProfilingInit();
2027 #endif /* PROFILING */
2028 DefragInit();
2029 FlowInitConfig(FLOW_QUIET);
2030 IPPairInitConfig(FLOW_QUIET);
2031 StreamTcpInitConfig(STREAM_VERBOSE);
2032 AppLayerParserPostStreamSetup();
2033 AppLayerRegisterGlobalCounters();
2034 OutputFilestoreRegisterGlobalCounters();
2035 }
2036
2037 /* tasks we need to run before packets start flowing,
2038 * but after we dropped privs */
2039 void PreRunPostPrivsDropInit(const int runmode)
2040 {
2041 StatsSetupPostConfigPreOutput();
2042 RunModeInitializeOutputs();
2043
2044 if (runmode == RUNMODE_UNIX_SOCKET) {
2045 /* As the above did some necessary startup initialization, it
2046 * also setup some outputs where only one is allowed, so
2047 * deinitialize to the state that unix-mode does after every
2048 * pcap. */
2049 PostRunDeinit(RUNMODE_PCAP_FILE, NULL);
2050 return;
2051 }
2052
2053 StatsSetupPostConfigPostOutput();
2054 }
2055
2056 /* clean up / shutdown code for both the main modes and for
2057 * unix socket mode.
2058 *
2059 * Will be run once per pcap in unix-socket mode */
2060 void PostRunDeinit(const int runmode, struct timeval *start_time)
2061 {
2062 if (runmode == RUNMODE_UNIX_SOCKET)
2063 return;
2064
2065 /* needed by FlowForceReassembly */
2066 PacketPoolInit();
2067
2068 /* handle graceful shutdown of the flow engine, it's helper
2069 * threads and the packet threads */
2070 FlowDisableFlowManagerThread();
2071 TmThreadDisableReceiveThreads();
2072 FlowForceReassembly();
2073 TmThreadDisablePacketThreads();
2074 SCPrintElapsedTime(start_time);
2075 FlowDisableFlowRecyclerThread();
2076
2077 /* kill the stats threads */
2078 TmThreadKillThreadsFamily(TVT_MGMT);
2079 TmThreadClearThreadsFamily(TVT_MGMT);
2080
2081 /* kill packet threads -- already in 'disabled' state */
2082 TmThreadKillThreadsFamily(TVT_PPT);
2083 TmThreadClearThreadsFamily(TVT_PPT);
2084
2085 PacketPoolDestroy();
2086
2087 /* mgt and ppt threads killed, we can run non thread-safe
2088 * shutdown functions */
2089 StatsReleaseResources();
2090 DecodeUnregisterCounters();
2091 RunModeShutDown();
2092 FlowShutdown();
2093 IPPairShutdown();
2094 HostCleanup();
2095 StreamTcpFreeConfig(STREAM_VERBOSE);
2096 DefragDestroy();
2097
2098 TmqResetQueues();
2099 #ifdef PROFILING
2100 if (profiling_rules_enabled)
2101 SCProfilingDump();
2102 SCProfilingDestroy();
2103 #endif
2104 }
2105
2106
2107 static int StartInternalRunMode(SCInstance *suri, int argc, char **argv)
2108 {
2109 /* Treat internal running mode */
2110 switch(suri->run_mode) {
2111 case RUNMODE_LIST_KEYWORDS:
2112 ListKeywords(suri->keyword_info);
2113 return TM_ECODE_DONE;
2114 case RUNMODE_LIST_APP_LAYERS:
2115 if (suri->conf_filename != NULL) {
2116 ListAppLayerProtocols(suri->conf_filename);
2117 } else {
2118 ListAppLayerProtocols(DEFAULT_CONF_FILE);
2119 }
2120 return TM_ECODE_DONE;
2121 case RUNMODE_PRINT_VERSION:
2122 PrintVersion();
2123 return TM_ECODE_DONE;
2124 case RUNMODE_PRINT_BUILDINFO:
2125 PrintBuildInfo();
2126 return TM_ECODE_DONE;
2127 case RUNMODE_PRINT_USAGE:
2128 PrintUsage(argv[0]);
2129 return TM_ECODE_DONE;
2130 case RUNMODE_LIST_RUNMODES:
2131 RunModeListRunmodes();
2132 return TM_ECODE_DONE;
2133 case RUNMODE_LIST_UNITTEST:
2134 RunUnittests(1, suri->regex_arg);
2135 case RUNMODE_UNITTEST:
2136 RunUnittests(0, suri->regex_arg);
2137 #ifdef OS_WIN32
2138 case RUNMODE_INSTALL_SERVICE:
2139 if (SCServiceInstall(argc, argv)) {
2140 return TM_ECODE_FAILED;
2141 }
2142 SCLogInfo("Suricata service has been successfuly installed.");
2143 return TM_ECODE_DONE;
2144 case RUNMODE_REMOVE_SERVICE:
2145 if (SCServiceRemove(argc, argv)) {
2146 return TM_ECODE_FAILED;
2147 }
2148 SCLogInfo("Suricata service has been successfuly removed.");
2149 return TM_ECODE_DONE;
2150 case RUNMODE_CHANGE_SERVICE_PARAMS:
2151 if (SCServiceChangeParams(argc, argv)) {
2152 return TM_ECODE_FAILED;
2153 }
2154 SCLogInfo("Suricata service startup parameters has been successfuly changed.");
2155 return TM_ECODE_DONE;
2156 #endif /* OS_WIN32 */
2157 default:
2158 /* simply continue for other running mode */
2159 break;
2160 }
2161 return TM_ECODE_OK;
2162 }
2163
2164 static int FinalizeRunMode(SCInstance *suri, char **argv)
2165 {
2166 switch (suri->run_mode) {
2167 case RUNMODE_UNKNOWN:
2168 PrintUsage(argv[0]);
2169 return TM_ECODE_FAILED;
2170 default:
2171 break;
2172 }
2173 /* Set the global run mode and offline flag. */
2174 run_mode = suri->run_mode;
2175
2176 if (!CheckValidDaemonModes(suri->daemon, suri->run_mode)) {
2177 return TM_ECODE_FAILED;
2178 }
2179
2180 return TM_ECODE_OK;
2181 }
2182
2183 static void SetupDelayedDetect(SCInstance *suri)
2184 {
2185 /* In offline mode delayed init of detect is a bad idea */
2186 if (suri->offline) {
2187 suri->delayed_detect = 0;
2188 } else {
2189 if (ConfGetBool("detect.delayed-detect", &suri->delayed_detect) != 1) {
2190 ConfNode *denode = NULL;
2191 ConfNode *decnf = ConfGetNode("detect-engine");
2192 if (decnf != NULL) {
2193 TAILQ_FOREACH(denode, &decnf->head, next) {
2194 if (strcmp(denode->val, "delayed-detect") == 0) {
2195 (void)ConfGetChildValueBool(denode, "delayed-detect", &suri->delayed_detect);
2196 }
2197 }
2198 }
2199 }
2200 }
2201
2202 SCLogConfig("Delayed detect %s", suri->delayed_detect ? "enabled" : "disabled");
2203 if (suri->delayed_detect) {
2204 SCLogInfo("Packets will start being processed before signatures are active.");
2205 }
2206
2207 }
2208
2209 static int LoadSignatures(DetectEngineCtx *de_ctx, SCInstance *suri)
2210 {
2211 if (SigLoadSignatures(de_ctx, suri->sig_file, suri->sig_file_exclusive) < 0) {
2212 SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed.");
2213 if (de_ctx->failure_fatal)
2214 return TM_ECODE_FAILED;
2215 }
2216
2217 return TM_ECODE_OK;
2218 }
2219
2220 static int ConfigGetCaptureValue(SCInstance *suri)
2221 {
2222 /* Pull the max pending packets from the config, if not found fall
2223 * back on a sane default. */
2224 if (ConfGetInt("max-pending-packets", &max_pending_packets) != 1)
2225 max_pending_packets = DEFAULT_MAX_PENDING_PACKETS;
2226 if (max_pending_packets >= 65535) {
2227 SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
2228 "Maximum max-pending-packets setting is 65534. "
2229 "Please check %s for errors", suri->conf_filename);
2230 return TM_ECODE_FAILED;
2231 }
2232
2233 SCLogDebug("Max pending packets set to %"PRIiMAX, max_pending_packets);
2234
2235 /* Pull the default packet size from the config, if not found fall
2236 * back on a sane default. */
2237 const char *temp_default_packet_size;
2238 if ((ConfGet("default-packet-size", &temp_default_packet_size)) != 1) {
2239 int mtu = 0;
2240 int lthread;
2241 int nlive;
2242 int strip_trailing_plus = 0;
2243 switch (suri->run_mode) {
2244 #ifdef WINDIVERT
2245 case RUNMODE_WINDIVERT:
2246 /* by default, WinDivert collects from all devices */
2247 mtu = GetGlobalMTUWin32();
2248
2249 if (mtu > 0) {
2250 g_default_mtu = mtu;
2251 /* SLL_HEADER_LEN is the longest header + 8 for VLAN */
2252 default_packet_size = mtu + SLL_HEADER_LEN + 8;
2253 break;
2254 }
2255
2256 g_default_mtu = DEFAULT_MTU;
2257 default_packet_size = DEFAULT_PACKET_SIZE;
2258 break;
2259 #endif /* WINDIVERT */
2260 case RUNMODE_NETMAP:
2261 /* in netmap igb0+ has a special meaning, however the
2262 * interface really is igb0 */
2263 strip_trailing_plus = 1;
2264 /* fall through */
2265 case RUNMODE_PCAP_DEV:
2266 case RUNMODE_AFP_DEV:
2267 case RUNMODE_PFRING:
2268 nlive = LiveGetDeviceNameCount();
2269 for (lthread = 0; lthread < nlive; lthread++) {
2270 const char *live_dev = LiveGetDeviceNameName(lthread);
2271 char dev[128]; /* need to be able to support GUID names on Windows */
2272 (void)strlcpy(dev, live_dev, sizeof(dev));
2273
2274 if (strip_trailing_plus) {
2275 size_t len = strlen(dev);
2276 if (len &&
2277 (dev[len-1] == '+' ||
2278 dev[len-1] == '^' ||
2279 dev[len-1] == '*'))
2280 {
2281 dev[len-1] = '\0';
2282 }
2283 }
2284 mtu = GetIfaceMTU(dev);
2285 g_default_mtu = MAX(mtu, g_default_mtu);
2286
2287 unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(dev);
2288 if (iface_max_packet_size > default_packet_size)
2289 default_packet_size = iface_max_packet_size;
2290 }
2291 if (default_packet_size)
2292 break;
2293 /* fall through */
2294 default:
2295 g_default_mtu = DEFAULT_MTU;
2296 default_packet_size = DEFAULT_PACKET_SIZE;
2297 }
2298 } else {
2299 if (ParseSizeStringU32(temp_default_packet_size, &default_packet_size) < 0) {
2300 SCLogError(SC_ERR_SIZE_PARSE, "Error parsing max-pending-packets "
2301 "from conf file - %s. Killing engine",
2302 temp_default_packet_size);
2303 return TM_ECODE_FAILED;
2304 }
2305 }
2306
2307 SCLogDebug("Default packet size set to %"PRIu32, default_packet_size);
2308
2309 return TM_ECODE_OK;
2310 }
2311
2312 static void PostRunStartedDetectSetup(const SCInstance *suri)
2313 {
2314 #ifndef OS_WIN32
2315 /* registering signal handlers we use. We setup usr2 here, so that one
2316 * can't call it during the first sig load phase or while threads are still
2317 * starting up. */
2318 if (DetectEngineEnabled() && suri->delayed_detect == 0) {
2319 UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
2320 UtilSignalUnblock(SIGUSR2);
2321 }
2322 #endif
2323 if (suri->delayed_detect) {
2324 /* force 'reload', this will load the rules and swap engines */
2325 DetectEngineReload(suri);
2326 SCLogNotice("Signature(s) loaded, Detect thread(s) activated.");
2327 #ifndef OS_WIN32
2328 UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
2329 UtilSignalUnblock(SIGUSR2);
2330 #endif
2331 }
2332 }
2333
2334 void PostConfLoadedDetectSetup(SCInstance *suri)
2335 {
2336 DetectEngineCtx *de_ctx = NULL;
2337 if (!suri->disabled_detect) {
2338 SCClassConfInit();
2339 SCReferenceConfInit();
2340 SetupDelayedDetect(suri);
2341 int mt_enabled = 0;
2342 (void)ConfGetBool("multi-detect.enabled", &mt_enabled);
2343 int default_tenant = 0;
2344 if (mt_enabled)
2345 (void)ConfGetBool("multi-detect.default", &default_tenant);
2346 if (DetectEngineMultiTenantSetup() == -1) {
2347 FatalError(SC_ERR_FATAL, "initializing multi-detect "
2348 "detection engine contexts failed.");
2349 }
2350 if (suri->delayed_detect && suri->run_mode != RUNMODE_CONF_TEST) {
2351 de_ctx = DetectEngineCtxInitStubForDD();
2352 } else if (mt_enabled && !default_tenant && suri->run_mode != RUNMODE_CONF_TEST) {
2353 de_ctx = DetectEngineCtxInitStubForMT();
2354 } else {
2355 de_ctx = DetectEngineCtxInit();
2356 }
2357 if (de_ctx == NULL) {
2358 FatalError(SC_ERR_FATAL, "initializing detection engine "
2359 "context failed.");
2360 }
2361
2362 if (de_ctx->type == DETECT_ENGINE_TYPE_NORMAL) {
2363 if (LoadSignatures(de_ctx, suri) != TM_ECODE_OK)
2364 exit(EXIT_FAILURE);
2365 }
2366
2367 gettimeofday(&de_ctx->last_reload, NULL);
2368 DetectEngineAddToMaster(de_ctx);
2369 DetectEngineBumpVersion();
2370 }
2371 }
2372
2373 static int PostDeviceFinalizedSetup(SCInstance *suri)
2374 {
2375 SCEnter();
2376
2377 #ifdef HAVE_AF_PACKET
2378 if (suri->run_mode == RUNMODE_AFP_DEV) {
2379 if (AFPRunModeIsIPS()) {
2380 SCLogInfo("AF_PACKET: Setting IPS mode");
2381 EngineModeSetIPS();
2382 }
2383 }
2384 #endif
2385 #ifdef HAVE_NETMAP
2386 if (suri->run_mode == RUNMODE_NETMAP) {
2387 if (NetmapRunModeIsIPS()) {
2388 SCLogInfo("Netmap: Setting IPS mode");
2389 EngineModeSetIPS();
2390 }
2391 }
2392 #endif
2393
2394 SCReturnInt(TM_ECODE_OK);
2395 }
2396
2397 static void PostConfLoadedSetupHostMode(void)
2398 {
2399 const char *hostmode = NULL;
2400
2401 if (ConfGetValue("host-mode", &hostmode) == 1) {
2402 if (!strcmp(hostmode, "router")) {
2403 host_mode = SURI_HOST_IS_ROUTER;
2404 } else if (!strcmp(hostmode, "sniffer-only")) {
2405 host_mode = SURI_HOST_IS_SNIFFER_ONLY;
2406 } else {
2407 if (strcmp(hostmode, "auto") != 0) {
2408 WarnInvalidConfEntry("host-mode", "%s", "auto");
2409 }
2410 if (EngineModeIsIPS()) {
2411 host_mode = SURI_HOST_IS_ROUTER;
2412 } else {
2413 host_mode = SURI_HOST_IS_SNIFFER_ONLY;
2414 }
2415 }
2416 } else {
2417 if (EngineModeIsIPS()) {
2418 host_mode = SURI_HOST_IS_ROUTER;
2419 SCLogInfo("No 'host-mode': suricata is in IPS mode, using "
2420 "default setting 'router'");
2421 } else {
2422 host_mode = SURI_HOST_IS_SNIFFER_ONLY;
2423 SCLogInfo("No 'host-mode': suricata is in IDS mode, using "
2424 "default setting 'sniffer-only'");
2425 }
2426 }
2427
2428 }
2429
2430 static void SetupUserMode(SCInstance *suri)
2431 {
2432 /* apply 'user mode' config updates here */
2433 if (suri->system == false) {
2434 if (suri->set_logdir == false) {
2435 /* override log dir to current work dir" */
2436 if (ConfigSetLogDirectory((char *)".") != TM_ECODE_OK) {
2437 FatalError(SC_ERR_LOGDIR_CONFIG, "could not set USER mode logdir");
2438 }
2439 }
2440 if (suri->set_datadir == false) {
2441 /* override data dir to current work dir" */
2442 if (ConfigSetDataDirectory((char *)".") != TM_ECODE_OK) {
2443 FatalError(SC_ERR_LOGDIR_CONFIG, "could not set USER mode datadir");
2444 }
2445 }
2446 }
2447 }
2448
2449 /**
2450 * This function is meant to contain code that needs
2451 * to be run once the configuration has been loaded.
2452 */
2453 int PostConfLoadedSetup(SCInstance *suri)
2454 {
2455 /* do this as early as possible #1577 #1955 */
2456 #ifdef HAVE_LUAJIT
2457 if (LuajitSetupStatesPool() != 0) {
2458 SCReturnInt(TM_ECODE_FAILED);
2459 }
2460 #endif
2461
2462 /* load the pattern matchers */
2463 MpmTableSetup();
2464 SpmTableSetup();
2465
2466 int disable_offloading;
2467 if (ConfGetBool("capture.disable-offloading", &disable_offloading) == 0)
2468 disable_offloading = 1;
2469 if (disable_offloading) {
2470 LiveSetOffloadDisable();
2471 } else {
2472 LiveSetOffloadWarn();
2473 }
2474
2475 if (suri->checksum_validation == -1) {
2476 const char *cv = NULL;
2477 if (ConfGetValue("capture.checksum-validation", &cv) == 1) {
2478 if (strcmp(cv, "none") == 0) {
2479 suri->checksum_validation = 0;
2480 } else if (strcmp(cv, "all") == 0) {
2481 suri->checksum_validation = 1;
2482 }
2483 }
2484 }
2485 switch (suri->checksum_validation) {
2486 case 0:
2487 ConfSet("stream.checksum-validation", "0");
2488 break;
2489 case 1:
2490 ConfSet("stream.checksum-validation", "1");
2491 break;
2492 }
2493
2494 if (suri->runmode_custom_mode) {
2495 ConfSet("runmode", suri->runmode_custom_mode);
2496 }
2497
2498 StorageInit();
2499 #ifdef HAVE_PACKET_EBPF
2500 if (suri->run_mode == RUNMODE_AFP_DEV) {
2501 EBPFRegisterExtension();
2502 LiveDevRegisterExtension();
2503 }
2504 #endif
2505 RegisterFlowBypassInfo();
2506
2507 MacSetRegisterFlowStorage();
2508
2509 AppLayerSetup();
2510
2511 /* Suricata will use this umask if provided. By default it will use the
2512 umask passed on from the shell. */
2513 const char *custom_umask;
2514 if (ConfGet("umask", &custom_umask) == 1) {
2515 uint16_t mask;
2516 if (StringParseUint16(&mask, 8, strlen(custom_umask),
2517 custom_umask) > 0) {
2518 umask((mode_t)mask);
2519 }
2520 }
2521
2522
2523 if (ConfigGetCaptureValue(suri) != TM_ECODE_OK) {
2524 SCReturnInt(TM_ECODE_FAILED);
2525 }
2526
2527 #ifdef NFQ
2528 if (suri->run_mode == RUNMODE_NFQ)
2529 NFQInitConfig(FALSE);
2530 #endif
2531
2532 /* Load the Host-OS lookup. */
2533 SCHInfoLoadFromConfig();
2534
2535 if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) {
2536 SCLogInfo("== Carrying out Engine Analysis ==");
2537 const char *temp = NULL;
2538 if (ConfGet("engine-analysis", &temp) == 0) {
2539 SCLogInfo("no engine-analysis parameter(s) defined in conf file. "
2540 "Please define/enable them in the conf to use this "
2541 "feature.");
2542 SCReturnInt(TM_ECODE_FAILED);
2543 }
2544 }
2545
2546 /* hardcoded initialization code */
2547 SigTableSetup(); /* load the rule keywords */
2548 SigTableApplyStrictCommandlineOption(suri->strict_rule_parsing_string);
2549 TmqhSetup();
2550
2551 CIDRInit();
2552 SCProtoNameInit();
2553
2554 TagInitCtx();
2555 PacketAlertTagInit();
2556 ThresholdInit();
2557 HostBitInitCtx();
2558 IPPairBitInitCtx();
2559
2560 if (DetectAddressTestConfVars() < 0) {
2561 SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
2562 "basic address vars test failed. Please check %s for errors",
2563 suri->conf_filename);
2564 SCReturnInt(TM_ECODE_FAILED);
2565 }
2566 if (DetectPortTestConfVars() < 0) {
2567 SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
2568 "basic port vars test failed. Please check %s for errors",
2569 suri->conf_filename);
2570 SCReturnInt(TM_ECODE_FAILED);
2571 }
2572
2573 FeatureTrackingRegister(); /* must occur prior to output mod registration */
2574 RegisterAllModules();
2575 #ifdef HAVE_PLUGINS
2576 SCPluginsLoad(suri->capture_plugin_name, suri->capture_plugin_args);
2577 #endif
2578 AppLayerHtpNeedFileInspection();
2579
2580 StorageFinalize();
2581
2582 TmModuleRunInit();
2583
2584 if (MayDaemonize(suri) != TM_ECODE_OK)
2585 SCReturnInt(TM_ECODE_FAILED);
2586
2587 if (InitSignalHandler(suri) != TM_ECODE_OK)
2588 SCReturnInt(TM_ECODE_FAILED);
2589
2590 /* Check for the existance of the default logging directory which we pick
2591 * from suricata.yaml. If not found, shut the engine down */
2592 suri->log_dir = ConfigGetLogDirectory();
2593
2594 if (ConfigCheckLogDirectoryExists(suri->log_dir) != TM_ECODE_OK) {
2595 SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" "
2596 "supplied by %s (default-log-dir) doesn't exist. "
2597 "Shutting down the engine", suri->log_dir, suri->conf_filename);
2598 SCReturnInt(TM_ECODE_FAILED);
2599 }
2600 if (!IsLogDirectoryWritable(suri->log_dir)) {
2601 SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" "
2602 "supplied by %s (default-log-dir) is not writable. "
2603 "Shutting down the engine", suri->log_dir, suri->conf_filename);
2604 SCReturnInt(TM_ECODE_FAILED);
2605 }
2606
2607
2608 #ifdef HAVE_NSS
2609 if (suri->run_mode != RUNMODE_CONF_TEST) {
2610 /* init NSS for hashing */
2611 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
2612 NSS_NoDB_Init(NULL);
2613 }
2614 #endif
2615
2616 if (suri->disabled_detect) {
2617 SCLogConfig("detection engine disabled");
2618 /* disable raw reassembly */
2619 (void)ConfSetFinal("stream.reassembly.raw", "false");
2620 }
2621
2622 HostInitConfig(HOST_VERBOSE);
2623
2624 CoredumpLoadConfig();
2625
2626 DecodeGlobalConfig();
2627
2628 LiveDeviceFinalize();
2629
2630 /* set engine mode if L2 IPS */
2631 if (PostDeviceFinalizedSetup(suri) != TM_ECODE_OK) {
2632 exit(EXIT_FAILURE);
2633 }
2634
2635 /* hostmode depends on engine mode being set */
2636 PostConfLoadedSetupHostMode();
2637
2638 PreRunInit(suri->run_mode);
2639
2640 SCReturnInt(TM_ECODE_OK);
2641 }
2642
2643 static void SuricataMainLoop(SCInstance *suri)
2644 {
2645 while(1) {
2646 if (sigterm_count || sigint_count) {
2647 suricata_ctl_flags |= SURICATA_STOP;
2648 }
2649
2650 if (suricata_ctl_flags & SURICATA_STOP) {
2651 SCLogNotice("Signal Received. Stopping engine.");
2652 break;
2653 }
2654
2655 TmThreadCheckThreadState();
2656
2657 if (sighup_count > 0) {
2658 OutputNotifyFileRotation();
2659 sighup_count--;
2660 }
2661
2662 if (sigusr2_count > 0) {
2663 if (!(DetectEngineReloadIsStart())) {
2664 DetectEngineReloadStart();
2665 DetectEngineReload(suri);
2666 DetectEngineReloadSetIdle();
2667 sigusr2_count--;
2668 }
2669
2670 } else if (DetectEngineReloadIsStart()) {
2671 DetectEngineReload(suri);
2672 DetectEngineReloadSetIdle();
2673 }
2674
2675 usleep(10* 1000);
2676 }
2677 }
2678
2679 /**
2680 * \brief Global initialization common to all runmodes.
2681 *
2682 * This can be used by fuzz targets.
2683 */
2684
2685 int InitGlobal(void) {
2686 suricata_context.SCLogMessage = SCLogMessage;
2687 suricata_context.DetectEngineStateFree = DetectEngineStateFree;
2688 suricata_context.AppLayerDecoderEventsSetEventRaw = AppLayerDecoderEventsSetEventRaw;
2689 suricata_context.AppLayerDecoderEventsFreeEvents = AppLayerDecoderEventsFreeEvents;
2690 suricata_context.AppLayerParserTriggerRawStreamReassembly =
2691 AppLayerParserTriggerRawStreamReassembly;
2692
2693 suricata_context.FileOpenFileWithId = FileOpenFileWithId;
2694 suricata_context.FileCloseFileById = FileCloseFileById;
2695 suricata_context.FileAppendDataById = FileAppendDataById;
2696 suricata_context.FileAppendGAPById = FileAppendGAPById;
2697 suricata_context.FileContainerRecycle = FileContainerRecycle;
2698 suricata_context.FilePrune = FilePrune;
2699 suricata_context.FileSetTx = FileContainerSetTx;
2700
2701 rs_init(&suricata_context);
2702
2703 SC_ATOMIC_INIT(engine_stage);
2704
2705 /* initialize the logging subsys */
2706 SCLogInitLogModule(NULL);
2707
2708 (void)SCSetThreadName("Suricata-Main");
2709
2710 /* Ignore SIGUSR2 as early as possble. We redeclare interest
2711 * once we're done launching threads. The goal is to either die
2712 * completely or handle any and all SIGUSR2s correctly.
2713 */
2714 #ifndef OS_WIN32
2715 UtilSignalHandlerSetup(SIGUSR2, SIG_IGN);
2716 if (UtilSignalBlock(SIGUSR2)) {
2717 SCLogError(SC_ERR_INITIALIZATION, "SIGUSR2 initialization error");
2718 return EXIT_FAILURE;
2719 }
2720 #endif
2721
2722 ParseSizeInit();
2723 RunModeRegisterRunModes();
2724
2725 /* Initialize the configuration module. */
2726 ConfInit();
2727
2728 return 0;
2729 }
2730
2731 int SuricataMain(int argc, char **argv)
2732 {
2733 SCInstanceInit(&suricata, argv[0]);
2734
2735 if (InitGlobal() != 0) {
2736 exit(EXIT_FAILURE);
2737 }
2738
2739 #ifdef OS_WIN32
2740 /* service initialization */
2741 if (WindowsInitService(argc, argv) != 0) {
2742 exit(EXIT_FAILURE);
2743 }
2744 #endif /* OS_WIN32 */
2745
2746 if (ParseCommandLine(argc, argv, &suricata) != TM_ECODE_OK) {
2747 exit(EXIT_FAILURE);
2748 }
2749
2750 if (FinalizeRunMode(&suricata, argv) != TM_ECODE_OK) {
2751 exit(EXIT_FAILURE);
2752 }
2753
2754 switch (StartInternalRunMode(&suricata, argc, argv)) {
2755 case TM_ECODE_DONE:
2756 exit(EXIT_SUCCESS);
2757 case TM_ECODE_FAILED:
2758 exit(EXIT_FAILURE);
2759 }
2760
2761 /* Initializations for global vars, queues, etc (memsets, mutex init..) */
2762 GlobalsInitPreConfig();
2763
2764 /* Load yaml configuration file if provided. */
2765 if (LoadYamlConfig(&suricata) != TM_ECODE_OK) {
2766 exit(EXIT_FAILURE);
2767 }
2768
2769 if (suricata.run_mode == RUNMODE_DUMP_CONFIG) {
2770 ConfDump();
2771 exit(EXIT_SUCCESS);
2772 }
2773
2774 int vlan_tracking = 1;
2775 if (ConfGetBool("vlan.use-for-tracking", &vlan_tracking) == 1 && !vlan_tracking) {
2776 /* Ignore vlan_ids when comparing flows. */
2777 g_vlan_mask = 0x0000;
2778 }
2779 SCLogDebug("vlan tracking is %s", vlan_tracking == 1 ? "enabled" : "disabled");
2780
2781 SetupUserMode(&suricata);
2782
2783 /* Since our config is now loaded we can finish configurating the
2784 * logging module. */
2785 SCLogLoadConfig(suricata.daemon, suricata.verbose);
2786
2787 LogVersion(&suricata);
2788 UtilCpuPrintSummary();
2789
2790 if (ParseInterfacesList(suricata.aux_run_mode, suricata.pcap_dev) != TM_ECODE_OK) {
2791 exit(EXIT_FAILURE);
2792 }
2793
2794 if (PostConfLoadedSetup(&suricata) != TM_ECODE_OK) {
2795 exit(EXIT_FAILURE);
2796 }
2797
2798 SCDropMainThreadCaps(suricata.userid, suricata.groupid);
2799
2800 /* Re-enable coredumps after privileges are dropped. */
2801 CoredumpEnable();
2802
2803 PreRunPostPrivsDropInit(suricata.run_mode);
2804
2805 PostConfLoadedDetectSetup(&suricata);
2806 if (suricata.run_mode == RUNMODE_ENGINE_ANALYSIS) {
2807 goto out;
2808 } else if (suricata.run_mode == RUNMODE_CONF_TEST){
2809 SCLogNotice("Configuration provided was successfully loaded. Exiting.");
2810 goto out;
2811 } else if (suricata.run_mode == RUNMODE_DUMP_FEATURES) {
2812 FeatureDump();
2813 goto out;
2814 }
2815
2816 SCSetStartTime(&suricata);
2817 RunModeDispatch(suricata.run_mode, suricata.runmode_custom_mode,
2818 suricata.capture_plugin_name, suricata.capture_plugin_args);
2819 if (suricata.run_mode != RUNMODE_UNIX_SOCKET) {
2820 UnixManagerThreadSpawnNonRunmode();
2821 }
2822
2823 /* Wait till all the threads have been initialized */
2824 if (TmThreadWaitOnThreadInit() == TM_ECODE_FAILED) {
2825 FatalError(SC_ERR_FATAL, "Engine initialization failed, "
2826 "aborting...");
2827 }
2828
2829 SC_ATOMIC_SET(engine_stage, SURICATA_RUNTIME);
2830 PacketPoolPostRunmodes();
2831
2832 /* Un-pause all the paused threads */
2833 TmThreadContinueThreads();
2834
2835 PostRunStartedDetectSetup(&suricata);
2836
2837 SCPledge();
2838 SuricataMainLoop(&suricata);
2839
2840 /* Update the engine stage/status flag */
2841 SC_ATOMIC_SET(engine_stage, SURICATA_DEINIT);
2842
2843 UnixSocketKillSocketThread();
2844 PostRunDeinit(suricata.run_mode, &suricata.start_time);
2845 /* kill remaining threads */
2846 TmThreadKillThreads();
2847
2848 out:
2849 GlobalsDestroy(&suricata);
2850
2851 exit(EXIT_SUCCESS);
2852 }
2853