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