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 #ifdef REVISION
692  printf("This is %s version %s (%s)\n", PROG_NAME, PROG_VER, xstr(REVISION));
693 #elif defined RELEASE
694  printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER);
695 #else
696  printf("This is %s version %s\n", PROG_NAME, PROG_VER);
697 #endif
698 
699 #ifdef DEBUG
700  strlcat(features, "DEBUG ", sizeof(features));
701 #endif
702 #ifdef DEBUG_VALIDATION
703  strlcat(features, "DEBUG_VALIDATION ", sizeof(features));
704 #endif
705 #ifdef UNITTESTS
706  strlcat(features, "UNITTESTS ", sizeof(features));
707 #endif
708 #ifdef NFQ
709  strlcat(features, "NFQ ", sizeof(features));
710 #endif
711 #ifdef IPFW
712  strlcat(features, "IPFW ", sizeof(features));
713 #endif
714 #ifdef HAVE_PCAP_SET_BUFF
715  strlcat(features, "PCAP_SET_BUFF ", sizeof(features));
716 #endif
717 #ifdef HAVE_PFRING
718  strlcat(features, "PF_RING ", sizeof(features));
719 #endif
720 #ifdef HAVE_AF_PACKET
721  strlcat(features, "AF_PACKET ", sizeof(features));
722 #endif
723 #ifdef HAVE_NETMAP
724  strlcat(features, "NETMAP ", sizeof(features));
725 #endif
726 #ifdef HAVE_PACKET_FANOUT
727  strlcat(features, "HAVE_PACKET_FANOUT ", sizeof(features));
728 #endif
729 #ifdef HAVE_DAG
730  strlcat(features, "DAG ", sizeof(features));
731 #endif
732 #ifdef HAVE_LIBCAP_NG
733  strlcat(features, "LIBCAP_NG ", sizeof(features));
734 #endif
735 #ifdef HAVE_LIBNET11
736  strlcat(features, "LIBNET1.1 ", sizeof(features));
737 #endif
738 #ifdef HAVE_HTP_URI_NORMALIZE_HOOK
739  strlcat(features, "HAVE_HTP_URI_NORMALIZE_HOOK ", sizeof(features));
740 #endif
741 #ifdef PCRE_HAVE_JIT
742  strlcat(features, "PCRE_JIT ", sizeof(features));
743 #endif
744 #ifdef HAVE_NSS
745  strlcat(features, "HAVE_NSS ", sizeof(features));
746 #endif
747 #ifdef HAVE_LUA
748  strlcat(features, "HAVE_LUA ", sizeof(features));
749 #endif
750 #ifdef HAVE_LUAJIT
751  strlcat(features, "HAVE_LUAJIT ", sizeof(features));
752 #endif
753  strlcat(features, "HAVE_LIBJANSSON ", sizeof(features));
754 #ifdef PROFILING
755  strlcat(features, "PROFILING ", sizeof(features));
756 #endif
757 #ifdef PROFILE_LOCKING
758  strlcat(features, "PROFILE_LOCKING ", sizeof(features));
759 #endif
760 #ifdef TLS
761  strlcat(features, "TLS ", sizeof(features));
762 #endif
763 #ifdef HAVE_MAGIC
764  strlcat(features, "MAGIC ", sizeof(features));
765 #endif
766  strlcat(features, "RUST ", sizeof(features));
767  if (strlen(features) == 0) {
768  strlcat(features, "none", sizeof(features));
769  }
770 
771  printf("Features: %s\n", features);
772 
773  /* SIMD stuff */
774  memset(features, 0x00, sizeof(features));
775 #if defined(__SSE4_2__)
776  strlcat(features, "SSE_4_2 ", sizeof(features));
777 #endif
778 #if defined(__SSE4_1__)
779  strlcat(features, "SSE_4_1 ", sizeof(features));
780 #endif
781 #if defined(__SSE3__)
782  strlcat(features, "SSE_3 ", sizeof(features));
783 #endif
784  if (strlen(features) == 0) {
785  strlcat(features, "none", sizeof(features));
786  }
787  printf("SIMD support: %s\n", features);
788 
789  /* atomics stuff */
790  memset(features, 0x00, sizeof(features));
791 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)
792  strlcat(features, "1 ", sizeof(features));
793 #endif
794 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
795  strlcat(features, "2 ", sizeof(features));
796 #endif
797 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
798  strlcat(features, "4 ", sizeof(features));
799 #endif
800 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
801  strlcat(features, "8 ", sizeof(features));
802 #endif
803 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
804  strlcat(features, "16 ", sizeof(features));
805 #endif
806  if (strlen(features) == 0) {
807  strlcat(features, "none", sizeof(features));
808  } else {
809  strlcat(features, "byte(s)", sizeof(features));
810  }
811  printf("Atomic intrinsics: %s\n", features);
812 
813 #if __WORDSIZE == 64
814  bits = "64-bits";
815 #elif __WORDSIZE == 32
816  bits = "32-bits";
817 #endif
818 
819 #if __BYTE_ORDER == __BIG_ENDIAN
820  endian = "Big-endian";
821 #elif __BYTE_ORDER == __LITTLE_ENDIAN
822  endian = "Little-endian";
823 #endif
824 
825  printf("%s, %s architecture\n", bits, endian);
826 #ifdef __GNUC__
827  printf("GCC version %s, C version %"PRIiMAX"\n", __VERSION__, (intmax_t)__STDC_VERSION__);
828 #else
829  printf("C version %"PRIiMAX"\n", (intmax_t)__STDC_VERSION__);
830 #endif
831 
832 #if __SSP__ == 1
833  printf("compiled with -fstack-protector\n");
834 #endif
835 #if __SSP_ALL__ == 2
836  printf("compiled with -fstack-protector-all\n");
837 #endif
838 /*
839  * Workaround for special defines of _FORTIFY_SOURCE like
840  * FORTIFY_SOURCE=((defined __OPTIMIZE && OPTIMIZE > 0) ? 2 : 0)
841  * which is used by Gentoo for example and would result in the error
842  * 'defined' undeclared when _FORTIFY_SOURCE used via %d in printf func
843  *
844  */
845 #if _FORTIFY_SOURCE == 2
846  printf("compiled with _FORTIFY_SOURCE=2\n");
847 #elif _FORTIFY_SOURCE == 1
848  printf("compiled with _FORTIFY_SOURCE=1\n");
849 #elif _FORTIFY_SOURCE == 0
850  printf("compiled with _FORTIFY_SOURCE=0\n");
851 #endif
852 #ifdef CLS
853  printf("L1 cache line size (CLS)=%d\n", CLS);
854 #endif
855 #ifdef TLS
856  tls = "__thread";
857 #endif
858  printf("thread local storage method: %s\n", tls);
859 
860  printf("compiled with %s, linked against %s\n",
861  HTP_VERSION_STRING_FULL, htp_get_version());
862  printf("\n");
863 #include "build-info.h"
864 }
865 
869 
871 {
872  // zero all module storage
873  memset(tmm_modules, 0, TMM_SIZE * sizeof(TmModule));
874 
875  /* commanders */
877  /* managers */
881  /* nfq */
885  /* ipfw */
889  /* pcap live */
892  /* pcap file */
895  /* af-packet */
898  /* netmap */
901  /* pfring */
904  /* dag file */
907  /* dag live */
910  /* napatech */
913 
914  /* flow worker */
916  /* respond-reject */
918 
919  /* log api */
922 
924  /* nflog */
927 
928  /* windivert */
932 }
933 
934 static TmEcode LoadYamlConfig(SCInstance *suri)
935 {
936  SCEnter();
937 
938  if (suri->conf_filename == NULL)
940 
941  if (ConfYamlLoadFile(suri->conf_filename) != 0) {
942  /* Error already displayed. */
944  }
945 
947 }
948 
949 static TmEcode ParseInterfacesList(const int runmode, char *pcap_dev)
950 {
951  SCEnter();
952 
953  /* run the selected runmode */
954  if (runmode == RUNMODE_PCAP_DEV) {
955  if (strlen(pcap_dev) == 0) {
956  int ret = LiveBuildDeviceList("pcap");
957  if (ret == 0) {
958  SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for pcap");
960  }
961  }
962  } else if (runmode == RUNMODE_PFRING) {
963  /* FIXME add backward compat support */
964  /* iface has been set on command line */
965  if (strlen(pcap_dev)) {
966  if (ConfSetFinal("pfring.live-interface", pcap_dev) != 1) {
967  SCLogError(SC_ERR_INITIALIZATION, "Failed to set pfring.live-interface");
969  }
970  } else {
971  /* not an error condition if we have a 1.0 config */
972  LiveBuildDeviceList("pfring");
973  }
974 #ifdef HAVE_AF_PACKET
975  } else if (runmode == RUNMODE_AFP_DEV) {
976  /* iface has been set on command line */
977  if (strlen(pcap_dev)) {
978  if (ConfSetFinal("af-packet.live-interface", pcap_dev) != 1) {
979  SCLogError(SC_ERR_INITIALIZATION, "Failed to set af-packet.live-interface");
981  }
982  } else {
983  int ret = LiveBuildDeviceList("af-packet");
984  if (ret == 0) {
985  SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for af-packet");
987  }
988  }
989 #endif
990 #ifdef HAVE_NETMAP
991  } else if (runmode == RUNMODE_NETMAP) {
992  /* iface has been set on command line */
993  if (strlen(pcap_dev)) {
994  if (ConfSetFinal("netmap.live-interface", pcap_dev) != 1) {
995  SCLogError(SC_ERR_INITIALIZATION, "Failed to set netmap.live-interface");
997  }
998  } else {
999  int ret = LiveBuildDeviceList("netmap");
1000  if (ret == 0) {
1001  SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for netmap");
1003  }
1004  }
1005 #endif
1006 #ifdef HAVE_NFLOG
1007  } else if (runmode == RUNMODE_NFLOG) {
1008  int ret = LiveBuildDeviceListCustom("nflog", "group");
1009  if (ret == 0) {
1010  SCLogError(SC_ERR_INITIALIZATION, "No group found in config for nflog");
1012  }
1013 #endif
1014  }
1015 
1017 }
1018 
1019 static void SCInstanceInit(SCInstance *suri, const char *progname)
1020 {
1021  memset(suri, 0x00, sizeof(*suri));
1022 
1023  suri->progname = progname;
1024  suri->run_mode = RUNMODE_UNKNOWN;
1025 
1026  memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1027  suri->sig_file = NULL;
1028  suri->sig_file_exclusive = FALSE;
1029  suri->pid_filename = NULL;
1030  suri->regex_arg = NULL;
1031 
1032  suri->keyword_info = NULL;
1033  suri->runmode_custom_mode = NULL;
1034 #ifndef OS_WIN32
1035  suri->user_name = NULL;
1036  suri->group_name = NULL;
1037  suri->do_setuid = FALSE;
1038  suri->do_setgid = FALSE;
1039  suri->userid = 0;
1040  suri->groupid = 0;
1041 #endif /* OS_WIN32 */
1042  suri->delayed_detect = 0;
1043  suri->daemon = 0;
1044  suri->offline = 0;
1045  suri->verbose = 0;
1046  /* use -1 as unknown */
1047  suri->checksum_validation = -1;
1048 #if HAVE_DETECT_DISABLED==1
1049  g_detect_disabled = suri->disabled_detect = 1;
1050 #else
1051  g_detect_disabled = suri->disabled_detect = 0;
1052 #endif
1053 }
1054 
1055 static TmEcode PrintVersion(void)
1056 {
1057 #ifdef REVISION
1058  printf("This is %s version %s (%s)\n", PROG_NAME, PROG_VER, xstr(REVISION));
1059 #elif defined RELEASE
1060  printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER);
1061 #else
1062  printf("This is %s version %s\n", PROG_NAME, PROG_VER);
1063 #endif
1064  return TM_ECODE_OK;
1065 }
1066 
1067 static TmEcode LogVersion(SCInstance *suri)
1068 {
1069  const char *mode = suri->system ? "SYSTEM" : "USER";
1070 #ifdef REVISION
1071  SCLogNotice("This is %s version %s (%s) running in %s mode",
1072  PROG_NAME, PROG_VER, xstr(REVISION), mode);
1073 #elif defined RELEASE
1074  SCLogNotice("This is %s version %s RELEASE running in %s mode",
1075  PROG_NAME, PROG_VER, mode);
1076 #else
1077  SCLogNotice("This is %s version %s running in %s mode",
1078  PROG_NAME, PROG_VER, mode);
1079 #endif
1080  return TM_ECODE_OK;
1081 }
1082 
1083 static void SCSetStartTime(SCInstance *suri)
1084 {
1085  memset(&suri->start_time, 0, sizeof(suri->start_time));
1086  gettimeofday(&suri->start_time, NULL);
1087 }
1088 
1089 static void SCPrintElapsedTime(struct timeval *start_time)
1090 {
1091  if (start_time == NULL)
1092  return;
1093  struct timeval end_time;
1094  memset(&end_time, 0, sizeof(end_time));
1095  gettimeofday(&end_time, NULL);
1096  uint64_t milliseconds = ((end_time.tv_sec - start_time->tv_sec) * 1000) +
1097  (((1000000 + end_time.tv_usec - start_time->tv_usec) / 1000) - 1000);
1098  SCLogInfo("time elapsed %.3fs", (float)milliseconds/(float)1000);
1099 }
1100 
1101 static int ParseCommandLineAfpacket(SCInstance *suri, const char *in_arg)
1102 {
1103 #ifdef HAVE_AF_PACKET
1104  if (suri->run_mode == RUNMODE_UNKNOWN) {
1105  suri->run_mode = RUNMODE_AFP_DEV;
1106  if (in_arg) {
1107  LiveRegisterDeviceName(in_arg);
1108  memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1109  strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
1110  }
1111  } else if (suri->run_mode == RUNMODE_AFP_DEV) {
1112  if (in_arg) {
1113  LiveRegisterDeviceName(in_arg);
1114  } else {
1115  SCLogInfo("Multiple af-packet option without interface on each is useless");
1116  }
1117  } else {
1118  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1119  "has been specified");
1120  PrintUsage(suri->progname);
1121  return TM_ECODE_FAILED;
1122  }
1123  return TM_ECODE_OK;
1124 #else
1125  SCLogError(SC_ERR_NO_AF_PACKET,"AF_PACKET not enabled. On Linux "
1126  "host, make sure to pass --enable-af-packet to "
1127  "configure when building.");
1128  return TM_ECODE_FAILED;
1129 #endif
1130 }
1131 
1132 static int ParseCommandLinePcapLive(SCInstance *suri, const char *in_arg)
1133 {
1134  memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1135 
1136  if (in_arg != NULL) {
1137  /* some windows shells require escaping of the \ in \Device. Otherwise
1138  * the backslashes are stripped. We put them back here. */
1139  if (strlen(in_arg) > 9 && strncmp(in_arg, "DeviceNPF", 9) == 0) {
1140  snprintf(suri->pcap_dev, sizeof(suri->pcap_dev), "\\Device\\NPF%s", in_arg+9);
1141  } else {
1142  strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
1143  PcapTranslateIPToDevice(suri->pcap_dev, sizeof(suri->pcap_dev));
1144  }
1145 
1146  if (strcmp(suri->pcap_dev, in_arg) != 0) {
1147  SCLogInfo("translated %s to pcap device %s", in_arg, suri->pcap_dev);
1148  } else if (strlen(suri->pcap_dev) > 0 && isdigit((unsigned char)suri->pcap_dev[0])) {
1149  SCLogError(SC_ERR_PCAP_TRANSLATE, "failed to find a pcap device for IP %s", in_arg);
1150  return TM_ECODE_FAILED;
1151  }
1152  }
1153 
1154  if (suri->run_mode == RUNMODE_UNKNOWN) {
1155  suri->run_mode = RUNMODE_PCAP_DEV;
1156  if (in_arg) {
1158  }
1159  } else if (suri->run_mode == RUNMODE_PCAP_DEV) {
1161  } else {
1162  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1163  "has been specified");
1164  PrintUsage(suri->progname);
1165  return TM_ECODE_FAILED;
1166  }
1167  return TM_ECODE_OK;
1168 }
1169 
1170 /**
1171  * Helper function to check if log directory is writable
1172  */
1173 static bool IsLogDirectoryWritable(const char* str)
1174 {
1175  if (access(str, W_OK) == 0)
1176  return true;
1177  return false;
1178 }
1179 
1180 static void ParseCommandLineAFL(const char *opt_name, char *opt_arg)
1181 {
1182 #ifdef AFLFUZZ_RULES
1183  if(strcmp(opt_name, "afl-rules") == 0) {
1184  MpmTableSetup();
1185  SpmTableSetup();
1186  exit(RuleParseDataFromFile(opt_arg));
1187  } else
1188 #endif
1189 #ifdef AFLFUZZ_APPLAYER
1190  if(strcmp(opt_name, "afl-http-request") == 0) {
1191  //printf("arg: //%s\n", opt_arg);
1192  MpmTableSetup();
1193  SpmTableSetup();
1197  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_HTTP, opt_arg));
1198  } else if(strcmp(opt_name, "afl-http") == 0) {
1199  //printf("arg: //%s\n", opt_arg);
1200  MpmTableSetup();
1201  SpmTableSetup();
1205  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_HTTP, opt_arg));
1206 
1207  } else if(strcmp(opt_name, "afl-tls-request") == 0) {
1208  //printf("arg: //%s\n", opt_arg);
1209  MpmTableSetup();
1210  SpmTableSetup();
1214  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_TLS, opt_arg));
1215  } else if(strcmp(opt_name, "afl-tls") == 0) {
1216  //printf("arg: //%s\n", opt_arg);
1217  MpmTableSetup();
1218  SpmTableSetup();
1222  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_TLS, opt_arg));
1223 
1224  } else if(strcmp(opt_name, "afl-dns-request") == 0) {
1225  //printf("arg: //%s\n", opt_arg);
1227  exit(AppLayerParserRequestFromFile(IPPROTO_UDP, ALPROTO_DNS, opt_arg));
1228  } else if(strcmp(opt_name, "afl-dns") == 0) {
1229  //printf("arg: //%s\n", opt_arg);
1232  exit(AppLayerParserFromFile(IPPROTO_UDP, ALPROTO_DNS, opt_arg));
1233 
1234  } else if(strcmp(opt_name, "afl-dnstcp-request") == 0) {
1235  //printf("arg: //%s\n", opt_arg);
1237  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_DNS, opt_arg));
1238  } else if(strcmp(opt_name, "afl-dnstcp") == 0) {
1239  //printf("arg: //%s\n", opt_arg);
1242  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_DNS, opt_arg));
1243 
1244  } else if(strcmp(opt_name, "afl-ssh-request") == 0) {
1245  //printf("arg: //%s\n", opt_arg);
1246  MpmTableSetup();
1247  SpmTableSetup();
1250  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_SSH, opt_arg));
1251  } else if(strcmp(opt_name, "afl-ssh") == 0) {
1252  //printf("arg: //%s\n", opt_arg);
1253  MpmTableSetup();
1254  SpmTableSetup();
1258  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_SSH, opt_arg));
1259 
1260  } else if(strcmp(opt_name, "afl-ftp-request") == 0) {
1261  //printf("arg: //%s\n", opt_arg);
1263  MpmTableSetup();
1264  SpmTableSetup();
1268  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_FTP, opt_arg));
1269  } else if(strcmp(opt_name, "afl-ftp") == 0) {
1270  //printf("arg: //%s\n", opt_arg);
1272  MpmTableSetup();
1273  SpmTableSetup();
1277  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_FTP, opt_arg));
1278 
1279  } else if(strcmp(opt_name, "afl-smtp-request") == 0) {
1280  //printf("arg: //%s\n", opt_arg);
1281  MpmTableSetup();
1282  SpmTableSetup();
1286  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_SMTP, opt_arg));
1287  } else if(strcmp(opt_name, "afl-smtp") == 0) {
1288  //printf("arg: //%s\n", opt_arg);
1289  MpmTableSetup();
1290  SpmTableSetup();
1294  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_SMTP, opt_arg));
1295 
1296  } else if(strcmp(opt_name, "afl-smb-request") == 0) {
1297  //printf("arg: //%s\n", opt_arg);
1298  MpmTableSetup();
1299  SpmTableSetup();
1302  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_SMB, opt_arg));
1303  } else if(strcmp(opt_name, "afl-smb") == 0) {
1304  //printf("arg: //%s\n", opt_arg);
1305  MpmTableSetup();
1306  SpmTableSetup();
1310  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_SMB, opt_arg));
1311  } else if(strstr(opt_name, "afl-dcerpc-request") != NULL) {
1312  //printf("arg: //%s\n", opt_arg);
1313  MpmTableSetup();
1314  SpmTableSetup();
1318  if (strcmp(opt_name, "afl-dcerpc-request") == 0)
1319  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
1320  else
1321  exit(AppLayerParserRequestFromFileSerie(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
1322  } else if(strstr(opt_name, "afl-dcerpc") != NULL) {
1323  //printf("arg: //%s\n", opt_arg);
1324  MpmTableSetup();
1325  SpmTableSetup();
1329  if (strcmp(opt_name, "afl-dcerpc") == 0)
1330  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
1331  else
1332  exit(AppLayerParserFromFileSerie(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
1333  } else if(strcmp(opt_name, "afl-modbus-request") == 0) {
1334  //printf("arg: //%s\n", opt_arg);
1337  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_MODBUS, opt_arg));
1338  } else if(strcmp(opt_name, "afl-modbus") == 0) {
1339  //printf("arg: //%s\n", opt_arg);
1342  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_MODBUS, opt_arg));
1343  } else if(strcmp(opt_name, "afl-enip-request") == 0) {
1344  //printf("arg: //%s\n", opt_arg);
1347  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_ENIP, opt_arg));
1348  } else if(strcmp(opt_name, "afl-enip") == 0) {
1349  //printf("arg: //%s\n", opt_arg);
1352  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_ENIP, opt_arg));
1353  } else if(strcmp(opt_name, "afl-dnp3-request") == 0) {
1356  exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_DNP3, opt_arg));
1357  } else if(strcmp(opt_name, "afl-dnp3") == 0) {
1360  exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_DNP3, opt_arg));
1361  } else
1362 #endif
1363 #ifdef AFLFUZZ_MIME
1364  if(strcmp(opt_name, "afl-mime") == 0) {
1365  //printf("arg: //%s\n", opt_arg);
1366  exit(MimeParserDataFromFile(opt_arg));
1367  } else
1368 #endif
1369 #ifdef AFLFUZZ_DECODER
1370  if(strstr(opt_name, "afl-decoder-ppp") != NULL) {
1371  StatsInit();
1372  MpmTableSetup();
1373  SpmTableSetup();
1375  if (strcmp(opt_name, "afl-decoder-ppp") == 0)
1376  exit(DecoderParseDataFromFile(opt_arg, DecodePPP));
1377  else
1378  exit(DecoderParseDataFromFileSerie(opt_arg, DecodePPP));
1379  } else if(strstr(opt_name, "afl-decoder-ipv4") != NULL) {
1380  StatsInit();
1381  MpmTableSetup();
1382  SpmTableSetup();
1384  if (strcmp(opt_name, "afl-decoder-ipv4") == 0)
1385  exit(DecoderParseDataFromFile(opt_arg, AFLDecodeIPV4));
1386  else
1387  exit(DecoderParseDataFromFileSerie(opt_arg, AFLDecodeIPV4));
1388  } else if(strstr(opt_name, "afl-decoder-ipv6") != NULL) {
1389  StatsInit();
1390  MpmTableSetup();
1391  SpmTableSetup();
1393  if (strcmp(opt_name, "afl-decoder-ipv6") == 0)
1394  exit(DecoderParseDataFromFile(opt_arg, AFLDecodeIPV6));
1395  else
1396  exit(DecoderParseDataFromFileSerie(opt_arg, AFLDecodeIPV6));
1397  } else if(strstr(opt_name, "afl-decoder-ethernet") != NULL) {
1398  StatsInit();
1399  MpmTableSetup();
1400  SpmTableSetup();
1402  if (strcmp(opt_name, "afl-decoder-ethernet") == 0)
1403  exit(DecoderParseDataFromFile(opt_arg, DecodeEthernet));
1404  else
1405  exit(DecoderParseDataFromFileSerie(opt_arg, DecodeEthernet));
1406  } else if(strstr(opt_name, "afl-decoder-erspan") != NULL) {
1407  StatsInit();
1408  MpmTableSetup();
1409  SpmTableSetup();
1411  if (strcmp(opt_name, "afl-decoder-erspan") == 0)
1412  exit(DecoderParseDataFromFile(opt_arg, DecodeERSPAN));
1413  else
1414  exit(DecoderParseDataFromFileSerie(opt_arg, DecodeERSPAN));
1415  } else
1416 #endif
1417 #ifdef AFLFUZZ_DER
1418  if(strcmp(opt_name, "afl-der") == 0) {
1419  //printf("arg: //%s\n", opt_arg);
1420  exit(DerParseDataFromFile(opt_arg));
1421  } else
1422 #endif
1423  {
1424  abort();
1425  }
1426 }
1427 
1428 static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
1429 {
1430  int opt;
1431 
1432  int dump_config = 0;
1433  int list_app_layer_protocols = 0;
1434  int list_unittests = 0;
1435  int list_runmodes = 0;
1436  int list_keywords = 0;
1437  int build_info = 0;
1438  int conf_test = 0;
1439 #ifdef AFLFUZZ_CONF_TEST
1440  int conf_test_force_success = 0;
1441 #endif
1442  int engine_analysis = 0;
1443  int ret = TM_ECODE_OK;
1444 
1445 #ifdef UNITTESTS
1446  coverage_unittests = 0;
1447  g_ut_modules = 0;
1448  g_ut_covered = 0;
1449 #endif
1450 
1451  struct option long_opts[] = {
1452  {"dump-config", 0, &dump_config, 1},
1453  {"pfring", optional_argument, 0, 0},
1454  {"pfring-int", required_argument, 0, 0},
1455  {"pfring-cluster-id", required_argument, 0, 0},
1456  {"pfring-cluster-type", required_argument, 0, 0},
1457  {"af-packet", optional_argument, 0, 0},
1458  {"netmap", optional_argument, 0, 0},
1459  {"pcap", optional_argument, 0, 0},
1460  {"pcap-file-continuous", 0, 0, 0},
1461  {"pcap-file-delete", 0, 0, 0},
1462  {"simulate-ips", 0, 0 , 0},
1463  {"no-random", 0, &g_disable_randomness, 1},
1464  {"strict-rule-keywords", optional_argument, 0, 0},
1465 
1466  /* AFL app-layer options. */
1467  {"afl-http-request", required_argument, 0 , 0},
1468  {"afl-http", required_argument, 0 , 0},
1469  {"afl-tls-request", required_argument, 0 , 0},
1470  {"afl-tls", required_argument, 0 , 0},
1471  {"afl-dns-request", required_argument, 0 , 0},
1472  {"afl-dns", required_argument, 0 , 0},
1473  {"afl-ssh-request", required_argument, 0 , 0},
1474  {"afl-ssh", required_argument, 0 , 0},
1475  {"afl-ftp-request", required_argument, 0 , 0},
1476  {"afl-ftp", required_argument, 0 , 0},
1477  {"afl-smtp-request", required_argument, 0 , 0},
1478  {"afl-smtp", required_argument, 0 , 0},
1479  {"afl-smb-request", required_argument, 0 , 0},
1480  {"afl-smb", required_argument, 0 , 0},
1481  {"afl-modbus-request", required_argument, 0 , 0},
1482  {"afl-modbus", required_argument, 0 , 0},
1483  {"afl-enip-request", required_argument, 0 , 0},
1484  {"afl-enip", required_argument, 0 , 0},
1485  {"afl-mime", required_argument, 0 , 0},
1486  {"afl-dnp3-request", required_argument, 0, 0},
1487  {"afl-dnp3", required_argument, 0, 0},
1488  {"afl-dcerpc", required_argument, 0, 0},
1489  {"afl-dcerpc-serie", required_argument, 0, 0},
1490  {"afl-dcerpc-request", required_argument, 0, 0},
1491  {"afl-dcerpc-request-serie", required_argument, 0, 0},
1492 
1493  /* Other AFL options. */
1494  {"afl-rules", required_argument, 0 , 0},
1495  {"afl-mime", required_argument, 0 , 0},
1496  {"afl-decoder-ppp", required_argument, 0 , 0},
1497  {"afl-decoder-ppp-serie", required_argument, 0 , 0},
1498  {"afl-decoder-ethernet", required_argument, 0 , 0},
1499  {"afl-decoder-ethernet-serie", required_argument, 0 , 0},
1500  {"afl-decoder-erspan", required_argument, 0 , 0},
1501  {"afl-decoder-erspan-serie", required_argument, 0 , 0},
1502  {"afl-decoder-ipv4", required_argument, 0 , 0},
1503  {"afl-decoder-ipv4-serie", required_argument, 0 , 0},
1504  {"afl-decoder-ipv6", required_argument, 0 , 0},
1505  {"afl-decoder-ipv6-serie", required_argument, 0 , 0},
1506  {"afl-der", required_argument, 0, 0},
1507 
1508 #ifdef BUILD_UNIX_SOCKET
1509  {"unix-socket", optional_argument, 0, 0},
1510 #endif
1511  {"pcap-buffer-size", required_argument, 0, 0},
1512  {"unittest-filter", required_argument, 0, 'U'},
1513  {"list-app-layer-protos", 0, &list_app_layer_protocols, 1},
1514  {"list-unittests", 0, &list_unittests, 1},
1515  {"list-runmodes", 0, &list_runmodes, 1},
1516  {"list-keywords", optional_argument, &list_keywords, 1},
1517  {"runmode", required_argument, NULL, 0},
1518  {"engine-analysis", 0, &engine_analysis, 1},
1519 #ifdef OS_WIN32
1520  {"service-install", 0, 0, 0},
1521  {"service-remove", 0, 0, 0},
1522  {"service-change-params", 0, 0, 0},
1523 #endif /* OS_WIN32 */
1524  {"pidfile", required_argument, 0, 0},
1525  {"init-errors-fatal", 0, 0, 0},
1526  {"disable-detection", 0, 0, 0},
1527  {"fatal-unittests", 0, 0, 0},
1528  {"unittests-coverage", 0, &coverage_unittests, 1},
1529  {"user", required_argument, 0, 0},
1530  {"group", required_argument, 0, 0},
1531  {"erf-in", required_argument, 0, 0},
1532  {"dag", required_argument, 0, 0},
1533  {"napatech", 0, 0, 0},
1534  {"build-info", 0, &build_info, 1},
1535  {"data-dir", required_argument, 0, 0},
1536 #ifdef WINDIVERT
1537  {"windivert", required_argument, 0, 0},
1538  {"windivert-forward", required_argument, 0, 0},
1539 #endif
1540  {"set", required_argument, 0, 0},
1541 #ifdef HAVE_NFLOG
1542  {"nflog", optional_argument, 0, 0},
1543 #endif
1544 #ifdef AFLFUZZ_CONF_TEST
1545  {"afl-parse-rules", 0, &conf_test_force_success, 1},
1546 #endif
1547  {NULL, 0, NULL, 0}
1548  };
1549 
1550  /* getopt_long stores the option index here. */
1551  int option_index = 0;
1552 
1553  char short_opts[] = "c:TDhi:l:q:d:r:us:S:U:VF:vk:";
1554 
1555  while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) {
1556  switch (opt) {
1557  case 0:
1558  if (strcmp((long_opts[option_index]).name , "pfring") == 0 ||
1559  strcmp((long_opts[option_index]).name , "pfring-int") == 0) {
1560 #ifdef HAVE_PFRING
1561  suri->run_mode = RUNMODE_PFRING;
1562  if (optarg != NULL) {
1563  memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1564  strlcpy(suri->pcap_dev, optarg,
1565  ((strlen(optarg) < sizeof(suri->pcap_dev)) ?
1566  (strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
1567  LiveRegisterDeviceName(optarg);
1568  }
1569 #else
1570  SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
1571  "to pass --enable-pfring to configure when building.");
1572  return TM_ECODE_FAILED;
1573 #endif /* HAVE_PFRING */
1574  }
1575  else if(strcmp((long_opts[option_index]).name , "pfring-cluster-id") == 0){
1576 #ifdef HAVE_PFRING
1577  if (ConfSetFinal("pfring.cluster-id", optarg) != 1) {
1578  fprintf(stderr, "ERROR: Failed to set pfring.cluster-id.\n");
1579  return TM_ECODE_FAILED;
1580  }
1581 #else
1582  SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
1583  "to pass --enable-pfring to configure when building.");
1584  return TM_ECODE_FAILED;
1585 #endif /* HAVE_PFRING */
1586  }
1587  else if(strcmp((long_opts[option_index]).name , "pfring-cluster-type") == 0){
1588 #ifdef HAVE_PFRING
1589  if (ConfSetFinal("pfring.cluster-type", optarg) != 1) {
1590  fprintf(stderr, "ERROR: Failed to set pfring.cluster-type.\n");
1591  return TM_ECODE_FAILED;
1592  }
1593 #else
1594  SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
1595  "to pass --enable-pfring to configure when building.");
1596  return TM_ECODE_FAILED;
1597 #endif /* HAVE_PFRING */
1598  }
1599  else if (strcmp((long_opts[option_index]).name , "af-packet") == 0)
1600  {
1601  if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
1602  return TM_ECODE_FAILED;
1603  }
1604  } else if (strcmp((long_opts[option_index]).name , "netmap") == 0){
1605 #ifdef HAVE_NETMAP
1606  if (suri->run_mode == RUNMODE_UNKNOWN) {
1607  suri->run_mode = RUNMODE_NETMAP;
1608  if (optarg) {
1609  LiveRegisterDeviceName(optarg);
1610  memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
1611  strlcpy(suri->pcap_dev, optarg,
1612  ((strlen(optarg) < sizeof(suri->pcap_dev)) ?
1613  (strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
1614  }
1615  } else if (suri->run_mode == RUNMODE_NETMAP) {
1616  if (optarg) {
1617  LiveRegisterDeviceName(optarg);
1618  } else {
1619  SCLogInfo("Multiple netmap option without interface on each is useless");
1620  break;
1621  }
1622  } else {
1623  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1624  "has been specified");
1625  PrintUsage(argv[0]);
1626  return TM_ECODE_FAILED;
1627  }
1628 #else
1629  SCLogError(SC_ERR_NO_NETMAP, "NETMAP not enabled.");
1630  return TM_ECODE_FAILED;
1631 #endif
1632  } else if (strcmp((long_opts[option_index]).name, "nflog") == 0) {
1633 #ifdef HAVE_NFLOG
1634  if (suri->run_mode == RUNMODE_UNKNOWN) {
1635  suri->run_mode = RUNMODE_NFLOG;
1636  LiveBuildDeviceListCustom("nflog", "group");
1637  }
1638 #else
1639  SCLogError(SC_ERR_NFLOG_NOSUPPORT, "NFLOG not enabled.");
1640  return TM_ECODE_FAILED;
1641 #endif /* HAVE_NFLOG */
1642  } else if (strcmp((long_opts[option_index]).name , "pcap") == 0) {
1643  if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
1644  return TM_ECODE_FAILED;
1645  }
1646  } else if(strncmp((long_opts[option_index]).name, "afl-", 4) == 0) {
1647  ParseCommandLineAFL((long_opts[option_index]).name, optarg);
1648  } else if(strcmp((long_opts[option_index]).name, "simulate-ips") == 0) {
1649  SCLogInfo("Setting IPS mode");
1650  EngineModeSetIPS();
1651  } else if(strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) {
1652  if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) {
1653  fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n");
1654  return TM_ECODE_FAILED;
1655  }
1656 #ifdef BUILD_UNIX_SOCKET
1657  } else if (strcmp((long_opts[option_index]).name , "unix-socket") == 0) {
1658  if (suri->run_mode == RUNMODE_UNKNOWN) {
1659  suri->run_mode = RUNMODE_UNIX_SOCKET;
1660  if (optarg) {
1661  if (ConfSetFinal("unix-command.filename", optarg) != 1) {
1662  fprintf(stderr, "ERROR: Failed to set unix-command.filename.\n");
1663  return TM_ECODE_FAILED;
1664  }
1665 
1666  }
1667  } else {
1668  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1669  "has been specified");
1670  PrintUsage(argv[0]);
1671  return TM_ECODE_FAILED;
1672  }
1673 #endif
1674  }
1675  else if(strcmp((long_opts[option_index]).name, "list-app-layer-protocols") == 0) {
1676  /* listing all supported app layer protocols */
1677  }
1678  else if(strcmp((long_opts[option_index]).name, "list-unittests") == 0) {
1679 #ifdef UNITTESTS
1681 #else
1682  fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
1683  return TM_ECODE_FAILED;
1684 #endif /* UNITTESTS */
1685  } else if (strcmp((long_opts[option_index]).name, "list-runmodes") == 0) {
1687  return TM_ECODE_OK;
1688  } else if (strcmp((long_opts[option_index]).name, "list-keywords") == 0) {
1689  if (optarg) {
1690  if (strcmp("short",optarg)) {
1691  suri->keyword_info = optarg;
1692  }
1693  }
1694  } else if (strcmp((long_opts[option_index]).name, "runmode") == 0) {
1695  suri->runmode_custom_mode = optarg;
1696  } else if(strcmp((long_opts[option_index]).name, "engine-analysis") == 0) {
1697  // do nothing for now
1698  }
1699 #ifdef OS_WIN32
1700  else if(strcmp((long_opts[option_index]).name, "service-install") == 0) {
1701  suri->run_mode = RUNMODE_INSTALL_SERVICE;
1702  return TM_ECODE_OK;
1703  }
1704  else if(strcmp((long_opts[option_index]).name, "service-remove") == 0) {
1705  suri->run_mode = RUNMODE_REMOVE_SERVICE;
1706  return TM_ECODE_OK;
1707  }
1708  else if(strcmp((long_opts[option_index]).name, "service-change-params") == 0) {
1709  suri->run_mode = RUNMODE_CHANGE_SERVICE_PARAMS;
1710  return TM_ECODE_OK;
1711  }
1712 #endif /* OS_WIN32 */
1713  else if(strcmp((long_opts[option_index]).name, "pidfile") == 0) {
1714  suri->pid_filename = SCStrdup(optarg);
1715  if (suri->pid_filename == NULL) {
1716  SCLogError(SC_ERR_MEM_ALLOC, "strdup failed: %s",
1717  strerror(errno));
1718  return TM_ECODE_FAILED;
1719  }
1720  }
1721  else if(strcmp((long_opts[option_index]).name, "disable-detection") == 0) {
1722  g_detect_disabled = suri->disabled_detect = 1;
1723  }
1724  else if(strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) {
1725 #ifdef UNITTESTS
1726  unittests_fatal = 1;
1727 #else
1728  fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
1729  return TM_ECODE_FAILED;
1730 #endif /* UNITTESTS */
1731  }
1732  else if(strcmp((long_opts[option_index]).name, "user") == 0) {
1733 #ifndef HAVE_LIBCAP_NG
1734  SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to"
1735  " drop privileges, but it was not compiled into Suricata.");
1736  return TM_ECODE_FAILED;
1737 #else
1738  suri->user_name = optarg;
1739  suri->do_setuid = TRUE;
1740 #endif /* HAVE_LIBCAP_NG */
1741  }
1742  else if(strcmp((long_opts[option_index]).name, "group") == 0) {
1743 #ifndef HAVE_LIBCAP_NG
1744  SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to"
1745  " drop privileges, but it was not compiled into Suricata.");
1746  return TM_ECODE_FAILED;
1747 #else
1748  suri->group_name = optarg;
1749  suri->do_setgid = TRUE;
1750 #endif /* HAVE_LIBCAP_NG */
1751  }
1752  else if (strcmp((long_opts[option_index]).name, "erf-in") == 0) {
1753  suri->run_mode = RUNMODE_ERF_FILE;
1754  if (ConfSetFinal("erf-file.file", optarg) != 1) {
1755  fprintf(stderr, "ERROR: Failed to set erf-file.file\n");
1756  return TM_ECODE_FAILED;
1757  }
1758  }
1759  else if (strcmp((long_opts[option_index]).name, "dag") == 0) {
1760 #ifdef HAVE_DAG
1761  if (suri->run_mode == RUNMODE_UNKNOWN) {
1762  suri->run_mode = RUNMODE_DAG;
1763  }
1764  else if (suri->run_mode != RUNMODE_DAG) {
1766  "more than one run mode has been specified");
1767  PrintUsage(argv[0]);
1768  return TM_ECODE_FAILED;
1769  }
1770  LiveRegisterDeviceName(optarg);
1771 #else
1772  SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required"
1773  " to receive packets using --dag.");
1774  return TM_ECODE_FAILED;
1775 #endif /* HAVE_DAG */
1776  }
1777  else if (strcmp((long_opts[option_index]).name, "napatech") == 0) {
1778 #ifdef HAVE_NAPATECH
1779  suri->run_mode = RUNMODE_NAPATECH;
1780 #else
1781  SCLogError(SC_ERR_NAPATECH_REQUIRED, "libntapi and a Napatech adapter are required"
1782  " to capture packets using --napatech.");
1783  return TM_ECODE_FAILED;
1784 #endif /* HAVE_NAPATECH */
1785  }
1786  else if(strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) {
1787 #ifdef HAVE_PCAP_SET_BUFF
1788  if (ConfSetFinal("pcap.buffer-size", optarg) != 1) {
1789  fprintf(stderr, "ERROR: Failed to set pcap-buffer-size.\n");
1790  return TM_ECODE_FAILED;
1791  }
1792 #else
1793  SCLogError(SC_ERR_NO_PCAP_SET_BUFFER_SIZE, "The version of libpcap you have"
1794  " doesn't support setting buffer size.");
1795 #endif /* HAVE_PCAP_SET_BUFF */
1796  }
1797  else if(strcmp((long_opts[option_index]).name, "build-info") == 0) {
1799  return TM_ECODE_OK;
1800  }
1801  else if(strcmp((long_opts[option_index]).name, "windivert-forward") == 0) {
1802 #ifdef WINDIVERT
1803  if (suri->run_mode == RUNMODE_UNKNOWN) {
1804  suri->run_mode = RUNMODE_WINDIVERT;
1805  if (WinDivertRegisterQueue(true, optarg) == -1) {
1806  exit(EXIT_FAILURE);
1807  }
1808  } else if (suri->run_mode == RUNMODE_WINDIVERT) {
1809  if (WinDivertRegisterQueue(true, optarg) == -1) {
1810  exit(EXIT_FAILURE);
1811  }
1812  } else {
1813  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1814  "has been specified");
1815  PrintUsage(argv[0]);
1816  exit(EXIT_FAILURE);
1817  }
1818  }
1819  else if(strcmp((long_opts[option_index]).name, "windivert") == 0) {
1820  if (suri->run_mode == RUNMODE_UNKNOWN) {
1821  suri->run_mode = RUNMODE_WINDIVERT;
1822  if (WinDivertRegisterQueue(false, optarg) == -1) {
1823  exit(EXIT_FAILURE);
1824  }
1825  } else if (suri->run_mode == RUNMODE_WINDIVERT) {
1826  if (WinDivertRegisterQueue(false, optarg) == -1) {
1827  exit(EXIT_FAILURE);
1828  }
1829  } else {
1830  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1831  "has been specified");
1832  PrintUsage(argv[0]);
1833  exit(EXIT_FAILURE);
1834  }
1835 #else
1836  SCLogError(SC_ERR_WINDIVERT_NOSUPPORT,"WinDivert not enabled. Make sure to pass --enable-windivert to configure when building.");
1837  return TM_ECODE_FAILED;
1838 #endif /* WINDIVERT */
1839  }
1840  else if (strcmp((long_opts[option_index]).name, "set") == 0) {
1841  if (optarg != NULL) {
1842  /* Quick validation. */
1843  char *val = strchr(optarg, '=');
1844  if (val == NULL) {
1846  "Invalid argument for --set, must be key=val.");
1847  exit(EXIT_FAILURE);
1848  }
1849  if (!ConfSetFromString(optarg, 1)) {
1850  fprintf(stderr, "Failed to set configuration value %s.",
1851  optarg);
1852  exit(EXIT_FAILURE);
1853  }
1854  }
1855  }
1856  else if (strcmp((long_opts[option_index]).name, "pcap-file-continuous") == 0) {
1857  if (ConfSetFinal("pcap-file.continuous", "true") != 1) {
1858  SCLogError(SC_ERR_CMD_LINE, "Failed to set pcap-file.continuous");
1859  return TM_ECODE_FAILED;
1860  }
1861  }
1862  else if (strcmp((long_opts[option_index]).name, "pcap-file-delete") == 0) {
1863  if (ConfSetFinal("pcap-file.delete-when-done", "true") != 1) {
1864  SCLogError(SC_ERR_CMD_LINE, "Failed to set pcap-file.delete-when-done");
1865  return TM_ECODE_FAILED;
1866  }
1867  }
1868  else if (strcmp((long_opts[option_index]).name, "data-dir") == 0) {
1869  if (optarg == NULL) {
1870  SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -d");
1871  return TM_ECODE_FAILED;
1872  }
1873 
1874  if (ConfigSetDataDirectory(optarg) != TM_ECODE_OK) {
1875  SCLogError(SC_ERR_FATAL, "Failed to set data directory.");
1876  return TM_ECODE_FAILED;
1877  }
1878  if (ConfigCheckDataDirectory(optarg) != TM_ECODE_OK) {
1879  SCLogError(SC_ERR_LOGDIR_CMDLINE, "The data directory \"%s\""
1880  " supplied at the commandline (-d %s) doesn't "
1881  "exist. Shutting down the engine.", optarg, optarg);
1882  return TM_ECODE_FAILED;
1883  }
1884  suri->set_datadir = true;
1885  } else if (strcmp((long_opts[option_index]).name , "strict-rule-keywords") == 0){
1886  if (optarg == NULL) {
1887  suri->strict_rule_parsing_string = SCStrdup("all");
1888  } else {
1889  suri->strict_rule_parsing_string = SCStrdup(optarg);
1890  }
1891  if (suri->strict_rule_parsing_string == NULL) {
1892  FatalError(SC_ERR_MEM_ALLOC, "failed to duplicate 'strict' string");
1893  }
1894  }
1895  break;
1896  case 'c':
1897  suri->conf_filename = optarg;
1898  break;
1899  case 'T':
1900  SCLogInfo("Running suricata under test mode");
1901  conf_test = 1;
1902  if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) {
1903  fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n");
1904  return TM_ECODE_FAILED;
1905  }
1906  break;
1907 #ifndef OS_WIN32
1908  case 'D':
1909  suri->daemon = 1;
1910  break;
1911 #endif /* OS_WIN32 */
1912  case 'h':
1913  suri->run_mode = RUNMODE_PRINT_USAGE;
1914  return TM_ECODE_OK;
1915  case 'i':
1916  if (optarg == NULL) {
1917  SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -i");
1918  return TM_ECODE_FAILED;
1919  }
1920 #ifdef HAVE_AF_PACKET
1921  if (ParseCommandLineAfpacket(suri, optarg) != TM_ECODE_OK) {
1922  return TM_ECODE_FAILED;
1923  }
1924 #else /* not afpacket */
1925  /* warn user if netmap or pf-ring are available */
1926 #if defined HAVE_PFRING || HAVE_NETMAP
1927  int i = 0;
1928 #ifdef HAVE_PFRING
1929  i++;
1930 #endif
1931 #ifdef HAVE_NETMAP
1932  i++;
1933 #endif
1935  "option%s %s available:"
1936 #ifdef HAVE_PFRING
1937  " PF_RING (--pfring-int=%s)"
1938 #endif
1939 #ifdef HAVE_NETMAP
1940  " NETMAP (--netmap=%s)"
1941 #endif
1942  ". Use --pcap=%s to suppress this warning",
1943  i == 1 ? "" : "s", i == 1 ? "is" : "are"
1944 #ifdef HAVE_PFRING
1945  , optarg
1946 #endif
1947 #ifdef HAVE_NETMAP
1948  , optarg
1949 #endif
1950  , optarg
1951  );
1952 #endif /* have faster methods */
1953  if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
1954  return TM_ECODE_FAILED;
1955  }
1956 #endif
1957  break;
1958  case 'l':
1959  if (optarg == NULL) {
1960  SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -l");
1961  return TM_ECODE_FAILED;
1962  }
1963 
1964  if (ConfigSetLogDirectory(optarg) != TM_ECODE_OK) {
1965  SCLogError(SC_ERR_FATAL, "Failed to set log directory.");
1966  return TM_ECODE_FAILED;
1967  }
1968  if (ConfigCheckLogDirectoryExists(optarg) != TM_ECODE_OK) {
1969  SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\""
1970  " supplied at the commandline (-l %s) doesn't "
1971  "exist. Shutting down the engine.", optarg, optarg);
1972  return TM_ECODE_FAILED;
1973  }
1974  if (!IsLogDirectoryWritable(optarg)) {
1975  SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\""
1976  " supplied at the commandline (-l %s) is not "
1977  "writable. Shutting down the engine.", optarg, optarg);
1978  return TM_ECODE_FAILED;
1979  }
1980  suri->set_logdir = true;
1981 
1982  break;
1983  case 'q':
1984 #ifdef NFQ
1985  if (suri->run_mode == RUNMODE_UNKNOWN) {
1986  suri->run_mode = RUNMODE_NFQ;
1987  EngineModeSetIPS();
1988  if (NFQParseAndRegisterQueues(optarg) == -1)
1989  return TM_ECODE_FAILED;
1990  } else if (suri->run_mode == RUNMODE_NFQ) {
1991  if (NFQParseAndRegisterQueues(optarg) == -1)
1992  return TM_ECODE_FAILED;
1993  } else {
1994  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
1995  "has been specified");
1996  PrintUsage(argv[0]);
1997  return TM_ECODE_FAILED;
1998  }
1999 #else
2000  SCLogError(SC_ERR_NFQ_NOSUPPORT,"NFQUEUE not enabled. Make sure to pass --enable-nfqueue to configure when building.");
2001  return TM_ECODE_FAILED;
2002 #endif /* NFQ */
2003  break;
2004  case 'd':
2005 #ifdef IPFW
2006  if (suri->run_mode == RUNMODE_UNKNOWN) {
2007  suri->run_mode = RUNMODE_IPFW;
2008  EngineModeSetIPS();
2009  if (IPFWRegisterQueue(optarg) == -1)
2010  return TM_ECODE_FAILED;
2011  } else if (suri->run_mode == RUNMODE_IPFW) {
2012  if (IPFWRegisterQueue(optarg) == -1)
2013  return TM_ECODE_FAILED;
2014  } else {
2015  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
2016  "has been specified");
2017  PrintUsage(argv[0]);
2018  return TM_ECODE_FAILED;
2019  }
2020 #else
2021  SCLogError(SC_ERR_IPFW_NOSUPPORT,"IPFW not enabled. Make sure to pass --enable-ipfw to configure when building.");
2022  return TM_ECODE_FAILED;
2023 #endif /* IPFW */
2024  break;
2025  case 'r':
2026  if (suri->run_mode == RUNMODE_UNKNOWN) {
2027  suri->run_mode = RUNMODE_PCAP_FILE;
2028  } else {
2029  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
2030  "has been specified");
2031  PrintUsage(argv[0]);
2032  return TM_ECODE_FAILED;
2033  }
2034 #ifdef OS_WIN32
2035  struct _stat buf;
2036  if(_stat(optarg, &buf) != 0) {
2037 #else
2038  struct stat buf;
2039  if (stat(optarg, &buf) != 0) {
2040 #endif /* OS_WIN32 */
2041  SCLogError(SC_ERR_INITIALIZATION, "ERROR: Pcap file does not exist\n");
2042  return TM_ECODE_FAILED;
2043  }
2044  if (ConfSetFinal("pcap-file.file", optarg) != 1) {
2045  SCLogError(SC_ERR_INITIALIZATION, "ERROR: Failed to set pcap-file.file\n");
2046  return TM_ECODE_FAILED;
2047  }
2048 
2049  break;
2050  case 's':
2051  if (suri->sig_file != NULL) {
2052  SCLogError(SC_ERR_CMD_LINE, "can't have multiple -s options or mix -s and -S.");
2053  return TM_ECODE_FAILED;
2054  }
2055  suri->sig_file = optarg;
2056  break;
2057  case 'S':
2058  if (suri->sig_file != NULL) {
2059  SCLogError(SC_ERR_CMD_LINE, "can't have multiple -S options or mix -s and -S.");
2060  return TM_ECODE_FAILED;
2061  }
2062  suri->sig_file = optarg;
2063  suri->sig_file_exclusive = TRUE;
2064  break;
2065  case 'u':
2066 #ifdef UNITTESTS
2067  if (suri->run_mode == RUNMODE_UNKNOWN) {
2068  suri->run_mode = RUNMODE_UNITTEST;
2069  } else {
2070  SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode has"
2071  " been specified");
2072  PrintUsage(argv[0]);
2073  return TM_ECODE_FAILED;
2074  }
2075 #else
2076  fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n");
2077  return TM_ECODE_FAILED;
2078 #endif /* UNITTESTS */
2079  break;
2080  case 'U':
2081 #ifdef UNITTESTS
2082  suri->regex_arg = optarg;
2083 
2084  if(strlen(suri->regex_arg) == 0)
2085  suri->regex_arg = NULL;
2086 #endif
2087  break;
2088  case 'V':
2090  return TM_ECODE_OK;
2091  case 'F':
2092  if (optarg == NULL) {
2093  SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -F");
2094  return TM_ECODE_FAILED;
2095  }
2096 
2097  SetBpfStringFromFile(optarg);
2098  break;
2099  case 'v':
2100  suri->verbose++;
2101  break;
2102  case 'k':
2103  if (optarg == NULL) {
2104  SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -k");
2105  return TM_ECODE_FAILED;
2106  }
2107  if (!strcmp("all", optarg))
2108  suri->checksum_validation = 1;
2109  else if (!strcmp("none", optarg))
2110  suri->checksum_validation = 0;
2111  else {
2112  SCLogError(SC_ERR_INITIALIZATION, "option '%s' invalid for -k", optarg);
2113  return TM_ECODE_FAILED;
2114  }
2115  break;
2116  default:
2117  PrintUsage(argv[0]);
2118  return TM_ECODE_FAILED;
2119  }
2120  }
2121 
2122  if (suri->disabled_detect && suri->sig_file != NULL) {
2123  SCLogError(SC_ERR_INITIALIZATION, "can't use -s/-S when detection is disabled");
2124  return TM_ECODE_FAILED;
2125  }
2126 #ifdef AFLFUZZ_CONF_TEST
2127  if (conf_test && conf_test_force_success) {
2128  (void)ConfSetFinal("engine.init-failure-fatal", "0");
2129  }
2130 #endif
2131 
2132  if ((suri->run_mode == RUNMODE_UNIX_SOCKET) && suri->set_logdir) {
2134  "can't use -l and unix socket runmode at the same time");
2135  return TM_ECODE_FAILED;
2136  }
2137 
2138  /* save the runmode from the commandline (if any) */
2139  suri->aux_run_mode = suri->run_mode;
2140 
2141  if (list_app_layer_protocols)
2143  if (list_keywords)
2145  if (list_unittests)
2147  if (dump_config)
2148  suri->run_mode = RUNMODE_DUMP_CONFIG;
2149  if (conf_test)
2150  suri->run_mode = RUNMODE_CONF_TEST;
2151  if (engine_analysis)
2153 
2154  suri->offline = IsRunModeOffline(suri->run_mode);
2155  g_system = suri->system = IsRunModeSystem(suri->run_mode);
2156 
2157  ret = SetBpfString(optind, argv);
2158  if (ret != TM_ECODE_OK)
2159  return ret;
2160 
2161  return TM_ECODE_OK;
2162 }
2163 
2164 #ifdef OS_WIN32
2165 static int WindowsInitService(int argc, char **argv)
2166 {
2167  if (SCRunningAsService()) {
2168  char path[MAX_PATH];
2169  char *p = NULL;
2170  strlcpy(path, argv[0], MAX_PATH);
2171  if ((p = strrchr(path, '\\'))) {
2172  *p = '\0';
2173  }
2174  if (!SetCurrentDirectory(path)) {
2175  SCLogError(SC_ERR_FATAL, "Can't set current directory to: %s", path);
2176  return -1;
2177  }
2178  SCLogInfo("Current directory is set to: %s", path);
2179  SCServiceInit(argc, argv);
2180  }
2181 
2182  /* Windows socket subsystem initialization */
2183  WSADATA wsaData;
2184  if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) {
2185  SCLogError(SC_ERR_FATAL, "Can't initialize Windows sockets: %d", WSAGetLastError());
2186  return -1;
2187  }
2188 
2189  return 0;
2190 }
2191 #endif /* OS_WIN32 */
2192 
2193 static int MayDaemonize(SCInstance *suri)
2194 {
2195  if (suri->daemon == 1 && suri->pid_filename == NULL) {
2196  const char *pid_filename;
2197 
2198  if (ConfGet("pid-file", &pid_filename) == 1) {
2199  SCLogInfo("Use pid file %s from config file.", pid_filename);
2200  } else {
2201  pid_filename = DEFAULT_PID_FILENAME;
2202  }
2203  /* The pid file name may be in config memory, but is needed later. */
2204  suri->pid_filename = SCStrdup(pid_filename);
2205  if (suri->pid_filename == NULL) {
2206  SCLogError(SC_ERR_MEM_ALLOC, "strdup failed: %s", strerror(errno));
2207  return TM_ECODE_FAILED;
2208  }
2209  }
2210 
2211  if (suri->pid_filename != NULL && SCPidfileTestRunning(suri->pid_filename) != 0) {
2212  SCFree(suri->pid_filename);
2213  suri->pid_filename = NULL;
2214  return TM_ECODE_FAILED;
2215  }
2216 
2217  if (suri->daemon == 1) {
2218  Daemonize();
2219  }
2220 
2221  if (suri->pid_filename != NULL) {
2222  if (SCPidfileCreate(suri->pid_filename) != 0) {
2223  SCFree(suri->pid_filename);
2224  suri->pid_filename = NULL;
2226  "Unable to create PID file, concurrent run of"
2227  " Suricata can occur.");
2229  "PID file creation WILL be mandatory for daemon mode"
2230  " in future version");
2231  }
2232  }
2233 
2234  return TM_ECODE_OK;
2235 }
2236 
2237 static int InitSignalHandler(SCInstance *suri)
2238 {
2239  /* registering signals we use */
2240  UtilSignalHandlerSetup(SIGINT, SignalHandlerSigint);
2241  UtilSignalHandlerSetup(SIGTERM, SignalHandlerSigterm);
2242 #ifndef OS_WIN32
2243  UtilSignalHandlerSetup(SIGHUP, SignalHandlerSigHup);
2244  UtilSignalHandlerSetup(SIGPIPE, SIG_IGN);
2245  UtilSignalHandlerSetup(SIGSYS, SIG_IGN);
2246 
2247  /* Try to get user/group to run suricata as if
2248  command line as not decide of that */
2249  if (suri->do_setuid == FALSE && suri->do_setgid == FALSE) {
2250  const char *id;
2251  if (ConfGet("run-as.user", &id) == 1) {
2252  suri->do_setuid = TRUE;
2253  suri->user_name = id;
2254  }
2255  if (ConfGet("run-as.group", &id) == 1) {
2256  suri->do_setgid = TRUE;
2257  suri->group_name = id;
2258  }
2259  }
2260  /* Get the suricata user ID to given user ID */
2261  if (suri->do_setuid == TRUE) {
2262  if (SCGetUserID(suri->user_name, suri->group_name,
2263  &suri->userid, &suri->groupid) != 0) {
2264  SCLogError(SC_ERR_UID_FAILED, "failed in getting user ID");
2265  return TM_ECODE_FAILED;
2266  }
2267 
2268  sc_set_caps = TRUE;
2269  /* Get the suricata group ID to given group ID */
2270  } else if (suri->do_setgid == TRUE) {
2271  if (SCGetGroupID(suri->group_name, &suri->groupid) != 0) {
2272  SCLogError(SC_ERR_GID_FAILED, "failed in getting group ID");
2273  return TM_ECODE_FAILED;
2274  }
2275 
2276  sc_set_caps = TRUE;
2277  }
2278 #endif /* OS_WIN32 */
2279 
2280  return TM_ECODE_OK;
2281 }
2282 
2283 /* initialization code for both the main modes and for
2284  * unix socket mode.
2285  *
2286  * Will be run once per pcap in unix-socket mode */
2287 void PreRunInit(const int runmode)
2288 {
2289  if (runmode == RUNMODE_UNIX_SOCKET)
2290  return;
2291 
2292  StatsInit();
2293 #ifdef PROFILING
2298  SCProfilingInit();
2299 #endif /* PROFILING */
2300  DatasetsInit();
2301  DefragInit();
2307 }
2308 
2309 /* tasks we need to run before packets start flowing,
2310  * but after we dropped privs */
2311 void PreRunPostPrivsDropInit(const int runmode)
2312 {
2313  if (runmode == RUNMODE_UNIX_SOCKET)
2314  return;
2315 
2319 }
2320 
2321 /* clean up / shutdown code for both the main modes and for
2322  * unix socket mode.
2323  *
2324  * Will be run once per pcap in unix-socket mode */
2325 void PostRunDeinit(const int runmode, struct timeval *start_time)
2326 {
2327  if (runmode == RUNMODE_UNIX_SOCKET)
2328  return;
2329 
2330  /* needed by FlowForceReassembly */
2331  PacketPoolInit();
2332 
2333  /* handle graceful shutdown of the flow engine, it's helper
2334  * threads and the packet threads */
2339  SCPrintElapsedTime(start_time);
2341 
2342  /* kill the stats threads */
2345 
2346  /* kill packet threads -- already in 'disabled' state */
2349 
2351 
2352  /* mgt and ppt threads killed, we can run non thread-safe
2353  * shutdown functions */
2356  RunModeShutDown();
2357  FlowShutdown();
2358  IPPairShutdown();
2359  HostCleanup();
2361  DefragDestroy();
2362 
2363  TmqResetQueues();
2364 #ifdef PROFILING
2366  SCProfilingDump();
2368 #endif
2369 }
2370 
2371 
2372 static int StartInternalRunMode(SCInstance *suri, int argc, char **argv)
2373 {
2374  /* Treat internal running mode */
2375  switch(suri->run_mode) {
2376  case RUNMODE_LIST_KEYWORDS:
2377  ListKeywords(suri->keyword_info);
2378  return TM_ECODE_DONE;
2381  return TM_ECODE_DONE;
2382  case RUNMODE_PRINT_VERSION:
2383  PrintVersion();
2384  return TM_ECODE_DONE;
2386  PrintBuildInfo();
2387  return TM_ECODE_DONE;
2388  case RUNMODE_PRINT_USAGE:
2389  PrintUsage(argv[0]);
2390  return TM_ECODE_DONE;
2391  case RUNMODE_LIST_RUNMODES:
2393  return TM_ECODE_DONE;
2394  case RUNMODE_LIST_UNITTEST:
2395  RunUnittests(1, suri->regex_arg);
2396  case RUNMODE_UNITTEST:
2397  RunUnittests(0, suri->regex_arg);
2398 #ifdef OS_WIN32
2399  case RUNMODE_INSTALL_SERVICE:
2400  if (SCServiceInstall(argc, argv)) {
2401  return TM_ECODE_FAILED;
2402  }
2403  SCLogInfo("Suricata service has been successfuly installed.");
2404  return TM_ECODE_DONE;
2405  case RUNMODE_REMOVE_SERVICE:
2406  if (SCServiceRemove(argc, argv)) {
2407  return TM_ECODE_FAILED;
2408  }
2409  SCLogInfo("Suricata service has been successfuly removed.");
2410  return TM_ECODE_DONE;
2411  case RUNMODE_CHANGE_SERVICE_PARAMS:
2412  if (SCServiceChangeParams(argc, argv)) {
2413  return TM_ECODE_FAILED;
2414  }
2415  SCLogInfo("Suricata service startup parameters has been successfuly changed.");
2416  return TM_ECODE_DONE;
2417 #endif /* OS_WIN32 */
2418  default:
2419  /* simply continue for other running mode */
2420  break;
2421  }
2422  return TM_ECODE_OK;
2423 }
2424 
2425 static int FinalizeRunMode(SCInstance *suri, char **argv)
2426 {
2427  switch (suri->run_mode) {
2428  case RUNMODE_UNKNOWN:
2429  PrintUsage(argv[0]);
2430  return TM_ECODE_FAILED;
2431  default:
2432  break;
2433  }
2434  /* Set the global run mode and offline flag. */
2435  run_mode = suri->run_mode;
2436 
2437  if (!CheckValidDaemonModes(suri->daemon, suri->run_mode)) {
2438  return TM_ECODE_FAILED;
2439  }
2440 
2441  return TM_ECODE_OK;
2442 }
2443 
2444 static void SetupDelayedDetect(SCInstance *suri)
2445 {
2446  /* In offline mode delayed init of detect is a bad idea */
2447  if (suri->offline) {
2448  suri->delayed_detect = 0;
2449  } else {
2450  if (ConfGetBool("detect.delayed-detect", &suri->delayed_detect) != 1) {
2451  ConfNode *denode = NULL;
2452  ConfNode *decnf = ConfGetNode("detect-engine");
2453  if (decnf != NULL) {
2454  TAILQ_FOREACH(denode, &decnf->head, next) {
2455  if (strcmp(denode->val, "delayed-detect") == 0) {
2456  (void)ConfGetChildValueBool(denode, "delayed-detect", &suri->delayed_detect);
2457  }
2458  }
2459  }
2460  }
2461  }
2462 
2463  SCLogConfig("Delayed detect %s", suri->delayed_detect ? "enabled" : "disabled");
2464  if (suri->delayed_detect) {
2465  SCLogInfo("Packets will start being processed before signatures are active.");
2466  }
2467 
2468 }
2469 
2470 static int LoadSignatures(DetectEngineCtx *de_ctx, SCInstance *suri)
2471 {
2472  if (SigLoadSignatures(de_ctx, suri->sig_file, suri->sig_file_exclusive) < 0) {
2473  SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed.");
2474  if (de_ctx->failure_fatal)
2475  return TM_ECODE_FAILED;
2476  }
2477 
2478  return TM_ECODE_OK;
2479 }
2480 
2481 static int ConfigGetCaptureValue(SCInstance *suri)
2482 {
2483  /* Pull the max pending packets from the config, if not found fall
2484  * back on a sane default. */
2485  if (ConfGetInt("max-pending-packets", &max_pending_packets) != 1)
2487  if (max_pending_packets >= 65535) {
2489  "Maximum max-pending-packets setting is 65534. "
2490  "Please check %s for errors", suri->conf_filename);
2491  return TM_ECODE_FAILED;
2492  }
2493 
2494  SCLogDebug("Max pending packets set to %"PRIiMAX, max_pending_packets);
2495 
2496  /* Pull the default packet size from the config, if not found fall
2497  * back on a sane default. */
2498  const char *temp_default_packet_size;
2499  if ((ConfGet("default-packet-size", &temp_default_packet_size)) != 1) {
2500  int mtu = 0;
2501  int lthread;
2502  int nlive;
2503  int strip_trailing_plus = 0;
2504  switch (suri->run_mode) {
2505 #ifdef WINDIVERT
2506  case RUNMODE_WINDIVERT:
2507  /* by default, WinDivert collects from all devices */
2508  mtu = GetGlobalMTUWin32();
2509 
2510  if (mtu > 0) {
2511  g_default_mtu = mtu;
2512  /* SLL_HEADER_LEN is the longest header + 8 for VLAN */
2513  default_packet_size = mtu + SLL_HEADER_LEN + 8;
2514  break;
2515  }
2516 
2519  break;
2520 #endif /* WINDIVERT */
2521  case RUNMODE_NETMAP:
2522  /* in netmap igb0+ has a special meaning, however the
2523  * interface really is igb0 */
2524  strip_trailing_plus = 1;
2525  /* fall through */
2526  case RUNMODE_PCAP_DEV:
2527  case RUNMODE_AFP_DEV:
2528  case RUNMODE_PFRING:
2529  nlive = LiveGetDeviceCount();
2530  for (lthread = 0; lthread < nlive; lthread++) {
2531  const char *live_dev = LiveGetDeviceName(lthread);
2532  char dev[128]; /* need to be able to support GUID names on Windows */
2533  (void)strlcpy(dev, live_dev, sizeof(dev));
2534 
2535  if (strip_trailing_plus) {
2536  size_t len = strlen(dev);
2537  if (len &&
2538  (dev[len-1] == '+' ||
2539  dev[len-1] == '^' ||
2540  dev[len-1] == '*'))
2541  {
2542  dev[len-1] = '\0';
2543  }
2544  }
2545  mtu = GetIfaceMTU(dev);
2547 
2548  unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(dev);
2549  if (iface_max_packet_size > default_packet_size)
2550  default_packet_size = iface_max_packet_size;
2551  }
2552  if (default_packet_size)
2553  break;
2554  /* fall through */
2555  default:
2558  }
2559  } else {
2560  if (ParseSizeStringU32(temp_default_packet_size, &default_packet_size) < 0) {
2561  SCLogError(SC_ERR_SIZE_PARSE, "Error parsing max-pending-packets "
2562  "from conf file - %s. Killing engine",
2563  temp_default_packet_size);
2564  return TM_ECODE_FAILED;
2565  }
2566  }
2567 
2568  SCLogDebug("Default packet size set to %"PRIu32, default_packet_size);
2569 
2570  return TM_ECODE_OK;
2571 }
2572 
2573 static void PostRunStartedDetectSetup(const SCInstance *suri)
2574 {
2575 #ifndef OS_WIN32
2576  /* registering signal handlers we use. We setup usr2 here, so that one
2577  * can't call it during the first sig load phase or while threads are still
2578  * starting up. */
2579  if (DetectEngineEnabled() && suri->delayed_detect == 0) {
2580  UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
2581  UtilSignalUnblock(SIGUSR2);
2582  }
2583 #endif
2584  if (suri->delayed_detect) {
2585  /* force 'reload', this will load the rules and swap engines */
2586  DetectEngineReload(suri);
2587  SCLogNotice("Signature(s) loaded, Detect thread(s) activated.");
2588 #ifndef OS_WIN32
2589  UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
2590  UtilSignalUnblock(SIGUSR2);
2591 #endif
2592  }
2593 }
2594 
2595 static void PostConfLoadedDetectSetup(SCInstance *suri)
2596 {
2597  DetectEngineCtx *de_ctx = NULL;
2598  if (!suri->disabled_detect) {
2599  SCClassConfInit();
2601  SetupDelayedDetect(suri);
2602  int mt_enabled = 0;
2603  (void)ConfGetBool("multi-detect.enabled", &mt_enabled);
2604  int default_tenant = 0;
2605  if (mt_enabled)
2606  (void)ConfGetBool("multi-detect.default", &default_tenant);
2607  if (DetectEngineMultiTenantSetup() == -1) {
2608  SCLogError(SC_ERR_INITIALIZATION, "initializing multi-detect "
2609  "detection engine contexts failed.");
2610  exit(EXIT_FAILURE);
2611  }
2612  if (suri->delayed_detect && suri->run_mode != RUNMODE_CONF_TEST) {
2613  de_ctx = DetectEngineCtxInitStubForDD();
2614  } else if (mt_enabled && !default_tenant && suri->run_mode != RUNMODE_CONF_TEST) {
2615  de_ctx = DetectEngineCtxInitStubForMT();
2616  } else {
2617  de_ctx = DetectEngineCtxInit();
2618  }
2619  if (de_ctx == NULL) {
2620  SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine "
2621  "context failed.");
2622  exit(EXIT_FAILURE);
2623  }
2624 
2625  if (de_ctx->type == DETECT_ENGINE_TYPE_NORMAL) {
2626  if (LoadSignatures(de_ctx, suri) != TM_ECODE_OK)
2627  exit(EXIT_FAILURE);
2628  }
2629 
2630  gettimeofday(&de_ctx->last_reload, NULL);
2631  DetectEngineAddToMaster(de_ctx);
2633  }
2634 }
2635 
2636 static int PostDeviceFinalizedSetup(SCInstance *suri)
2637 {
2638  SCEnter();
2639 
2640 #ifdef HAVE_AF_PACKET
2641  if (suri->run_mode == RUNMODE_AFP_DEV) {
2642  if (AFPRunModeIsIPS()) {
2643  SCLogInfo("AF_PACKET: Setting IPS mode");
2644  EngineModeSetIPS();
2645  }
2646  }
2647 #endif
2648 #ifdef HAVE_NETMAP
2649  if (suri->run_mode == RUNMODE_NETMAP) {
2650  if (NetmapRunModeIsIPS()) {
2651  SCLogInfo("Netmap: Setting IPS mode");
2652  EngineModeSetIPS();
2653  }
2654  }
2655 #endif
2656 
2658 }
2659 
2660 static void PostConfLoadedSetupHostMode(void)
2661 {
2662  const char *hostmode = NULL;
2663 
2664  if (ConfGetValue("host-mode", &hostmode) == 1) {
2665  if (!strcmp(hostmode, "router")) {
2667  } else if (!strcmp(hostmode, "sniffer-only")) {
2669  } else {
2670  if (strcmp(hostmode, "auto") != 0) {
2671  WarnInvalidConfEntry("host-mode", "%s", "auto");
2672  }
2673  if (EngineModeIsIPS()) {
2675  } else {
2677  }
2678  }
2679  } else {
2680  if (EngineModeIsIPS()) {
2682  SCLogInfo("No 'host-mode': suricata is in IPS mode, using "
2683  "default setting 'router'");
2684  } else {
2686  SCLogInfo("No 'host-mode': suricata is in IDS mode, using "
2687  "default setting 'sniffer-only'");
2688  }
2689  }
2690 
2691 }
2692 
2693 static void SetupUserMode(SCInstance *suri)
2694 {
2695  /* apply 'user mode' config updates here */
2696  if (suri->system == false) {
2697  if (suri->set_logdir == false) {
2698  /* override log dir to current work dir" */
2699  if (ConfigSetLogDirectory((char *)".") != TM_ECODE_OK) {
2700  FatalError(SC_ERR_LOGDIR_CONFIG, "could not set USER mode logdir");
2701  }
2702  }
2703  if (suri->set_datadir == false) {
2704  /* override data dir to current work dir" */
2705  if (ConfigSetDataDirectory((char *)".") != TM_ECODE_OK) {
2706  FatalError(SC_ERR_LOGDIR_CONFIG, "could not set USER mode datadir");
2707  }
2708  }
2709  }
2710 }
2711 
2712 /**
2713  * This function is meant to contain code that needs
2714  * to be run once the configuration has been loaded.
2715  */
2716 static int PostConfLoadedSetup(SCInstance *suri)
2717 {
2718  /* do this as early as possible #1577 #1955 */
2719 #ifdef HAVE_LUAJIT
2720  if (LuajitSetupStatesPool() != 0) {
2722  }
2723 #endif
2724 
2725  /* load the pattern matchers */
2726  MpmTableSetup();
2727  SpmTableSetup();
2728 
2729  int disable_offloading;
2730  if (ConfGetBool("capture.disable-offloading", &disable_offloading) == 0)
2731  disable_offloading = 1;
2732  if (disable_offloading) {
2734  } else {
2736  }
2737 
2738  if (suri->checksum_validation == -1) {
2739  const char *cv = NULL;
2740  if (ConfGetValue("capture.checksum-validation", &cv) == 1) {
2741  if (strcmp(cv, "none") == 0) {
2742  suri->checksum_validation = 0;
2743  } else if (strcmp(cv, "all") == 0) {
2744  suri->checksum_validation = 1;
2745  }
2746  }
2747  }
2748  switch (suri->checksum_validation) {
2749  case 0:
2750  ConfSet("stream.checksum-validation", "0");
2751  break;
2752  case 1:
2753  ConfSet("stream.checksum-validation", "1");
2754  break;
2755  }
2756 
2757  if (suri->runmode_custom_mode) {
2758  ConfSet("runmode", suri->runmode_custom_mode);
2759  }
2760 
2761  StorageInit();
2762 #ifdef HAVE_PACKET_EBPF
2763  EBPFRegisterExtension();
2765 #endif
2767  AppLayerSetup();
2768 
2769  /* Suricata will use this umask if provided. By default it will use the
2770  umask passed on from the shell. */
2771  const char *custom_umask;
2772  if (ConfGet("umask", &custom_umask) == 1) {
2773  uint16_t mask;
2774  if (ByteExtractStringUint16(&mask, 8, strlen(custom_umask),
2775  custom_umask) > 0) {
2776  umask((mode_t)mask);
2777  }
2778  }
2779 
2780 
2781  if (ConfigGetCaptureValue(suri) != TM_ECODE_OK) {
2783  }
2784 
2785 #ifdef NFQ
2786  if (suri->run_mode == RUNMODE_NFQ)
2788 #endif
2789 
2790  /* Load the Host-OS lookup. */
2792 
2793  if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) {
2794  SCLogInfo("== Carrying out Engine Analysis ==");
2795  const char *temp = NULL;
2796  if (ConfGet("engine-analysis", &temp) == 0) {
2797  SCLogInfo("no engine-analysis parameter(s) defined in conf file. "
2798  "Please define/enable them in the conf to use this "
2799  "feature.");
2801  }
2802  }
2803 
2804  /* hardcoded initialization code */
2805  SigTableSetup(); /* load the rule keywords */
2807  TmqhSetup();
2808 
2809  CIDRInit();
2810  SCProtoNameInit();
2811 
2812  TagInitCtx();
2814  ThresholdInit();
2815  HostBitInitCtx();
2816  IPPairBitInitCtx();
2817 
2818  if (DetectAddressTestConfVars() < 0) {
2820  "basic address vars test failed. Please check %s for errors",
2821  suri->conf_filename);
2823  }
2824  if (DetectPortTestConfVars() < 0) {
2826  "basic port vars test failed. Please check %s for errors",
2827  suri->conf_filename);
2829  }
2830 
2832 
2834 
2835  StorageFinalize();
2836 
2837  TmModuleRunInit();
2838 
2839  if (MayDaemonize(suri) != TM_ECODE_OK)
2841 
2842  if (InitSignalHandler(suri) != TM_ECODE_OK)
2844 
2845  /* Check for the existance of the default logging directory which we pick
2846  * from suricata.yaml. If not found, shut the engine down */
2847  suri->log_dir = ConfigGetLogDirectory();
2848 
2850  SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" "
2851  "supplied by %s (default-log-dir) doesn't exist. "
2852  "Shutting down the engine", suri->log_dir, suri->conf_filename);
2854  }
2855  if (!IsLogDirectoryWritable(suri->log_dir)) {
2856  SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" "
2857  "supplied by %s (default-log-dir) is not writable. "
2858  "Shutting down the engine", suri->log_dir, suri->conf_filename);
2860  }
2861 
2862 
2863 #ifdef HAVE_NSS
2864  if (suri->run_mode != RUNMODE_CONF_TEST) {
2865  /* init NSS for hashing */
2866  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
2867  NSS_NoDB_Init(NULL);
2868  }
2869 #endif
2870 
2871  if (suri->disabled_detect) {
2872  SCLogConfig("detection engine disabled");
2873  /* disable raw reassembly */
2874  (void)ConfSetFinal("stream.reassembly.raw", "false");
2875  }
2876 
2878 #ifdef HAVE_MAGIC
2879  if (MagicInit() != 0)
2881 #endif
2882  SCAsn1LoadConfig();
2883 
2885 
2887 
2889 
2890  /* set engine mode if L2 IPS */
2891  if (PostDeviceFinalizedSetup(&suricata) != TM_ECODE_OK) {
2892  exit(EXIT_FAILURE);
2893  }
2894 
2895  /* hostmode depends on engine mode being set */
2896  PostConfLoadedSetupHostMode();
2897 
2898  PreRunInit(suri->run_mode);
2899 
2901 }
2902 
2903 static void SuricataMainLoop(SCInstance *suri)
2904 {
2905  while(1) {
2906  if (sigterm_count || sigint_count) {
2908  }
2909 
2911  SCLogNotice("Signal Received. Stopping engine.");
2912  break;
2913  }
2914 
2916 
2917  if (sighup_count > 0) {
2919  sighup_count--;
2920  }
2921 
2922  if (sigusr2_count > 0) {
2923  if (!(DetectEngineReloadIsStart())) {
2925  DetectEngineReload(suri);
2927  sigusr2_count--;
2928  }
2929 
2930  } else if (DetectEngineReloadIsStart()) {
2931  DetectEngineReload(suri);
2933  }
2934 
2935  usleep(10* 1000);
2936  }
2937 }
2938 
2939 int main(int argc, char **argv)
2940 {
2941  SCInstanceInit(&suricata, argv[0]);
2942 
2943  SuricataContext context;
2944  context.SCLogMessage = SCLogMessage;
2949 
2955  context.FilePrune = FilePrune;
2956  context.FileSetTx = FileContainerSetTx;
2957 
2958  rs_init(&context);
2959 
2960  SC_ATOMIC_INIT(engine_stage);
2961 
2962  /* initialize the logging subsys */
2963  SCLogInitLogModule(NULL);
2964 
2965  (void)SCSetThreadName("Suricata-Main");
2966 
2967  /* Ignore SIGUSR2 as early as possble. We redeclare interest
2968  * once we're done launching threads. The goal is to either die
2969  * completely or handle any and all SIGUSR2s correctly.
2970  */
2971 #ifndef OS_WIN32
2972  UtilSignalHandlerSetup(SIGUSR2, SIG_IGN);
2973  if (UtilSignalBlock(SIGUSR2)) {
2974  SCLogError(SC_ERR_INITIALIZATION, "SIGUSR2 initialization error");
2975  exit(EXIT_FAILURE);
2976  }
2977 #endif
2978 
2979  ParseSizeInit();
2981 
2982 #ifdef OS_WIN32
2983  /* service initialization */
2984  if (WindowsInitService(argc, argv) != 0) {
2985  exit(EXIT_FAILURE);
2986  }
2987 #endif /* OS_WIN32 */
2988 
2989  /* Initialize the configuration module. */
2990  ConfInit();
2991 
2992  if (ParseCommandLine(argc, argv, &suricata) != TM_ECODE_OK) {
2993  exit(EXIT_FAILURE);
2994  }
2995 
2996  if (FinalizeRunMode(&suricata, argv) != TM_ECODE_OK) {
2997  exit(EXIT_FAILURE);
2998  }
2999 
3000  switch (StartInternalRunMode(&suricata, argc, argv)) {
3001  case TM_ECODE_DONE:
3002  exit(EXIT_SUCCESS);
3003  case TM_ECODE_FAILED:
3004  exit(EXIT_FAILURE);
3005  }
3006 
3007  /* Initializations for global vars, queues, etc (memsets, mutex init..) */
3009 
3010  /* Load yaml configuration file if provided. */
3011  if (LoadYamlConfig(&suricata) != TM_ECODE_OK) {
3012  exit(EXIT_FAILURE);
3013  }
3014 
3015  if (suricata.run_mode == RUNMODE_DUMP_CONFIG) {
3016  ConfDump();
3017  exit(EXIT_SUCCESS);
3018  }
3019 
3020  int vlan_tracking = 1;
3021  if (ConfGetBool("vlan.use-for-tracking", &vlan_tracking) == 1 && !vlan_tracking) {
3022  /* Ignore vlan_ids when comparing flows. */
3023  g_vlan_mask = 0x0000;
3024  }
3025  SCLogDebug("vlan tracking is %s", vlan_tracking == 1 ? "enabled" : "disabled");
3026 
3027  SetupUserMode(&suricata);
3028 
3029  /* Since our config is now loaded we can finish configurating the
3030  * logging module. */
3031  SCLogLoadConfig(suricata.daemon, suricata.verbose);
3032 
3033  LogVersion(&suricata);
3035 
3036  if (ParseInterfacesList(suricata.aux_run_mode, suricata.pcap_dev) != TM_ECODE_OK) {
3037  exit(EXIT_FAILURE);
3038  }
3039 
3040  if (PostConfLoadedSetup(&suricata) != TM_ECODE_OK) {
3041  exit(EXIT_FAILURE);
3042  }
3043 
3044  SCDropMainThreadCaps(suricata.userid, suricata.groupid);
3045 
3046  /* Re-enable coredumps after privileges are dropped. */
3047  CoredumpEnable();
3048 
3050 
3051  PostConfLoadedDetectSetup(&suricata);
3052  if (suricata.run_mode == RUNMODE_ENGINE_ANALYSIS) {
3053  goto out;
3054  } else if (suricata.run_mode == RUNMODE_CONF_TEST){
3055  SCLogNotice("Configuration provided was successfully loaded. Exiting.");
3056  goto out;
3057  }
3058 
3059  SCSetStartTime(&suricata);
3060  RunModeDispatch(suricata.run_mode, suricata.runmode_custom_mode);
3061  if (suricata.run_mode != RUNMODE_UNIX_SOCKET) {
3063  }
3064 
3065  /* Wait till all the threads have been initialized */
3067  SCLogError(SC_ERR_INITIALIZATION, "Engine initialization failed, "
3068  "aborting...");
3069  exit(EXIT_FAILURE);
3070  }
3071 
3072  (void) SC_ATOMIC_CAS(&engine_stage, SURICATA_INIT, SURICATA_RUNTIME);
3074 
3075  /* Un-pause all the paused threads */
3077 
3078  PostRunStartedDetectSetup(&suricata);
3079 
3080 #ifdef DBG_MEM_ALLOC
3081  SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem);
3082 #ifdef DBG_MEM_ALLOC_SKIP_STARTUP
3083  print_mem_flag = 1;
3084 #endif
3085 #endif
3086 
3087  SCPledge();
3088  SuricataMainLoop(&suricata);
3089 
3090  /* Update the engine stage/status flag */
3091  (void) SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT);
3092 
3094  PostRunDeinit(suricata.run_mode, &suricata.start_time);
3095  /* kill remaining threads */
3097 
3098 out:
3099  GlobalsDestroy(&suricata);
3100 
3101  exit(EXIT_SUCCESS);
3102 }
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
const char * LiveGetDeviceName(int number)
Get a pointer to the device name at idx.
Definition: util-device.c:177
int ConfSet(const char *name, const char *val)
Set a configuration value.
Definition: conf.c:220
void TmqResetQueues(void)
Definition: tm-queues.c:79
int IPFWRegisterQueue(char *queue)
Add an IPFW divert.
Definition: source-ipfw.c:713
void 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:2051
#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:1636
void DetectEngineDeReference(DetectEngineCtx **de_ctx)
void ConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:722
void RunUnittests(int list_unittests, const char *regex_arg)
void CIDRInit(void)
Definition: util-cidr.c:31
int g_ut_covered
Definition: suricata.c:868
#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:265
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:870
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:201
int LiveGetDeviceCount(void)
Get the number of registered devices.
Definition: util-device.c:157
void DetectEngineReloadSetIdle(void)
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
bool set_datadir
Definition: suricata.h:157
#define CLS
void DecodeGlobalConfig(void)
Definition: decode.c:724
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:1830
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:531
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:980
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:2079
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:453
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 * 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:430
#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:305
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:2287
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:1740
void TmModuleReceiveNetmapRegister(void)
Definition: source-netmap.c:90
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
int(* FileCloseFileById)(FileContainer *, uint32_t track_id, const uint8_t *data, uint32_t data_len, uint16_t flags)
Definition: rust.h:32
void SCProfilingPrefilterGlobalInit(void)
int SCGetUserID(const char *user_name, const char *group_name, uint32_t *uid, uint32_t *gid)
Function to get the user and group ID from the specified user name.
Definition: util-privs.c:150
void ConfInit(void)
Initialize the configuration system.
Definition: conf.c:113
void RunModeRegisterRunModes(void)
Register all runmodes in the engine.
Definition: runmodes.c:209
void ParseSizeDeinit(void)
Definition: util-misc.c:55
void RegisterFTPParsers(void)
void SCPidfileRemove(const char *pid_filename)
Remove the pid file (used at the startup)
Definition: util-pidfile.c:83
void GlobalsInitPreConfig(void)
Definition: suricata.c: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:365
int DetectAddressTestConfVars(void)
void TmModuleReceiveErfDagRegister(void)
Register the ERF file receiver (reader) module.
int ConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:299
int ConfSetFromString(const char *input, int final)
Set a configuration parameter from a string.
Definition: conf.c:245
const char * conf_filename
Definition: suricata.h: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:611
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:1995
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:345
int AppLayerParserSetup(void)
int SCGetGroupID(const char *group_name, uint32_t *gid)
Function to get the group ID from the specified group name.
Definition: util-privs.c:213
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
void UnixSocketKillSocketThread(void)
void OutputDeregisterAll(void)
Deregister all modules. Useful for a memory clean exit.
Definition: output.c: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:1769
int SCPidfileCreate(const char *pidfile)
Write a pid file (used at the startup) This commonly needed by the init scripts.
Definition: util-pidfile.c:41
void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events)
#define STREAM_VERBOSE
Definition: stream-tcp.h:33
DetectEngineCtx * DetectEngineCtxInitStubForMT(void)
void RegisterENIPTCPParsers(void)
Function to register the ENIP protocol parsers and other functions.
int CheckValidDaemonModes(int daemon, int mode)
Check for a valid combination daemon/mode.
Definition: util-daemon.c:174
void UtilCpuPrintSummary(void)
Print a summary of CPUs detected (configured and online)
Definition: util-cpu.c:162
void PcapTranslateIPToDevice(char *pcap_dev, size_t len)
Definition: source-pcap.c:623
void RunModeShutDown(void)
Definition: runmodes.c:522
Definition: conf.h:32
void DetectEngineBumpVersion(void)
void TmModuleReceiveIPFWRegister(void)
Registration Function for RecieveIPFW.
Definition: source-ipfw.c:153
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:719
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:397
#define SCFree(a)
Definition: util-mem.h:322
#define SC_ATOMIC_CAS(name, cmpval, newval)
atomic Compare and Switch
Definition: util-atomic.h:222
int UtilSignalUnblock(int signum)
Definition: util-signal.c:46
int DetectEngineMultiTenantSetup(void)
setup multi-detect / multi-tenancy
void HTPFreeConfig(void)
Clears the HTTP server configuration memory used by HTP library.
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:269
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.h:73
#define DEFAULT_MAX_PENDING_PACKETS
Definition: suricata.c:198
void SCProfilingInit(void)
Initialize profiling.
void TmThreadDisableReceiveThreads(void)
Disable all threads having the specified TMs.
Definition: tm-threads.c:1540
enum DetectEngineType type
Definition: detect.h: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:614
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:617
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:539
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:2939
void RegisterModbusParsers(void)
Function to register the Modbus protocol parsers and other functions.
int LiveBuildDeviceListCustom(const char *runmode, const char *itemname)
Definition: util-device.c:270
char * regex_arg
Definition: suricata.h:142
int FileOpenFileWithId(FileContainer *ffc, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *name, uint16_t name_len, const uint8_t *data, uint32_t data_len, uint16_t flags)
Open a new File.
Definition: util-file.c:869
int g_ut_modules
Definition: suricata.c:867
void(* AppLayerDecoderEventsSetEventRaw)(AppLayerDecoderEvents **, uint8_t)
Definition: rust.h:25
void PostRunDeinit(const int runmode, struct timeval *start_time)
Definition: suricata.c:2325
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:866
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:688
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:2311
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
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