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