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