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