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