suricata
runmode-unix-socket.c
Go to the documentation of this file.
1 /* Copyright (C) 2012 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 #include "suricata-common.h"
19 #include "tm-threads.h"
20 #include "conf.h"
21 #include "runmodes.h"
22 #include "runmode-pcap-file.h"
23 #include "output.h"
24 #include "output-json.h"
25 
26 #include "util-debug.h"
27 #include "util-time.h"
28 #include "util-cpu.h"
29 #include "util-affinity.h"
30 #include "util-var-name.h"
31 #include "util-path.h"
32 #include "unix-manager.h"
33 
34 #include "detect-engine.h"
35 
36 #include "flow-manager.h"
37 #include "flow-timeout.h"
38 #include "flow-hash.h"
39 #include "stream-tcp.h"
40 #include "stream-tcp-reassemble.h"
42 #include "host.h"
43 #include "defrag.h"
44 #include "defrag-hash.h"
45 #include "ippair.h"
46 #include "app-layer.h"
47 #include "app-layer-ftp.h"
48 #include "app-layer-htp-mem.h"
49 #include "app-layer-htp-range.h"
50 #include "host-bit.h"
51 
52 #include "util-misc.h"
53 #include "util-profiling.h"
54 
55 #include "conf-yaml-loader.h"
56 
57 #include "datasets.h"
58 #include "runmode-unix-socket.h"
59 
61 
62 typedef struct PcapFiles_ {
63  char *filename;
64  char *output_dir;
65  uint32_t tenant_id;
66  time_t delay;
67  time_t poll_interval;
68  bool continuous;
72 
73 typedef struct PcapCommand_ {
74  TAILQ_HEAD(, PcapFiles_) files;
75  int running;
76  PcapFiles *current_file;
78 
79 typedef struct MemcapCommand_ {
80  const char *name;
81  int (*SetFunc)(uint64_t);
82  uint64_t (*GetFunc)(void);
83  uint64_t (*GetMemuseFunc)(void);
85 
87 {
88  return "autofp";
89 }
90 
91 static MemcapCommand memcaps[] = {
92  {
93  "stream",
97  },
101  { "applayer-proto-http", HTPSetMemcap, HTPGetMemcap, HTPMemuseGlobalCounter },
102  { "applayer-proto-http-byterange", HTPByteRangeSetMemcap, HTPByteRangeMemcapGlobalCounter,
108 };
109 
111 {
112  float percent = 0.0;
113  for (int i = 0; i < 4; i++) { // only flow, streams, http
114  uint64_t memcap = memcaps[i].GetFunc();
115  if (memcap) {
116  uint64_t memuse = memcaps[i].GetMemuseFunc();
117  float p = (float)((double)memuse / (double)memcap);
118  // SCLogNotice("%s: memuse %"PRIu64", memcap %"PRIu64" => %f%%",
119  // memcaps[i].name, memuse, memcap, (p * 100));
120  percent = MAX(p, percent);
121  }
122  }
123  return percent;
124 }
125 
126 #ifdef BUILD_UNIX_SOCKET
127 
128 static int RunModeUnixSocketMaster(void);
129 static int unix_manager_pcap_task_running = 0;
130 static int unix_manager_pcap_task_failed = 0;
131 static int unix_manager_pcap_task_interrupted = 0;
132 static struct timespec unix_manager_pcap_last_processed;
133 static SCCtrlMutex unix_manager_pcap_last_processed_mutex;
134 
135 /**
136  * \brief return list of files in the queue
137  *
138  * \retval 0 in case of error, 1 in case of success
139  */
140 static TmEcode UnixSocketPcapFilesList(json_t *cmd, json_t* answer, void *data)
141 {
142  PcapCommand *this = (PcapCommand *) data;
143  int i = 0;
144  PcapFiles *file;
145  json_t *jdata;
146  json_t *jarray;
147 
148  jdata = json_object();
149  if (jdata == NULL) {
150  json_object_set_new(answer, "message",
151  json_string("internal error at json object creation"));
152  return TM_ECODE_FAILED;
153  }
154  jarray = json_array();
155  if (jarray == NULL) {
156  json_decref(jdata);
157  json_object_set_new(answer, "message",
158  json_string("internal error at json object creation"));
159  return TM_ECODE_FAILED;
160  }
161  TAILQ_FOREACH(file, &this->files, next) {
162  json_array_append_new(jarray, SCJsonString(file->filename));
163  i++;
164  }
165  json_object_set_new(jdata, "count", json_integer(i));
166  json_object_set_new(jdata, "files", jarray);
167  json_object_set_new(answer, "message", jdata);
168  return TM_ECODE_OK;
169 }
170 
171 static TmEcode UnixSocketPcapFilesNumber(json_t *cmd, json_t* answer, void *data)
172 {
173  PcapCommand *this = (PcapCommand *) data;
174  int i = 0;
175  PcapFiles *file;
176 
177  TAILQ_FOREACH(file, &this->files, next) {
178  i++;
179  }
180  json_object_set_new(answer, "message", json_integer(i));
181  return TM_ECODE_OK;
182 }
183 
184 static TmEcode UnixSocketPcapCurrent(json_t *cmd, json_t* answer, void *data)
185 {
186  PcapCommand *this = (PcapCommand *) data;
187 
188  if (this->current_file != NULL && this->current_file->filename != NULL) {
189  json_object_set_new(answer, "message",
190  json_string(this->current_file->filename));
191  } else {
192  json_object_set_new(answer, "message", json_string("None"));
193  }
194  return TM_ECODE_OK;
195 }
196 
197 static TmEcode UnixSocketPcapLastProcessed(json_t *cmd, json_t *answer, void *data)
198 {
199  json_int_t epoch_millis;
200  SCCtrlMutexLock(&unix_manager_pcap_last_processed_mutex);
201  epoch_millis = SCTimespecAsEpochMillis(&unix_manager_pcap_last_processed);
202  SCCtrlMutexUnlock(&unix_manager_pcap_last_processed_mutex);
203 
204  json_object_set_new(answer, "message",
205  json_integer(epoch_millis));
206 
207  return TM_ECODE_OK;
208 }
209 
210 static TmEcode UnixSocketPcapInterrupt(json_t *cmd, json_t *answer, void *data)
211 {
212  unix_manager_pcap_task_interrupted = 1;
213 
214  json_object_set_new(answer, "message", json_string("Interrupted"));
215 
216  return TM_ECODE_OK;
217 }
218 
219 static void PcapFilesFree(PcapFiles *cfile)
220 {
221  if (cfile == NULL)
222  return;
223  if (cfile->filename)
224  SCFree(cfile->filename);
225  if (cfile->output_dir)
226  SCFree(cfile->output_dir);
227  SCFree(cfile);
228 }
229 
230 /**
231  * \brief Add file to file queue
232  *
233  * \param this a UnixCommand:: structure
234  * \param filename absolute filename
235  * \param output_dir absolute name of directory where log will be put
236  * \param tenant_id Id of tenant associated with this file
237  * \param continuous If file should be run in continuous mode
238  * \param delete If file should be deleted when done
239  * \param delay Delay required for file modified time before being processed
240  * \param poll_interval How frequently directory mode polls for new files
241  *
242  * \retval 0 in case of error, 1 in case of success
243  */
244 static TmEcode UnixListAddFile(PcapCommand *this, const char *filename, const char *output_dir,
245  uint32_t tenant_id, bool continuous, bool should_delete, time_t delay, time_t poll_interval)
246 {
247  PcapFiles *cfile = NULL;
248  if (filename == NULL || this == NULL)
249  return TM_ECODE_FAILED;
250  cfile = SCCalloc(1, sizeof(PcapFiles));
251  if (unlikely(cfile == NULL)) {
252  SCLogError("Unable to allocate new file");
253  return TM_ECODE_FAILED;
254  }
255 
256  cfile->filename = SCStrdup(filename);
257  if (unlikely(cfile->filename == NULL)) {
258  SCFree(cfile);
259  SCLogError("Unable to dup filename");
260  return TM_ECODE_FAILED;
261  }
262 
263  if (output_dir) {
264  cfile->output_dir = SCStrdup(output_dir);
265  if (unlikely(cfile->output_dir == NULL)) {
266  SCFree(cfile->filename);
267  SCFree(cfile);
268  SCLogError("Unable to dup output_dir");
269  return TM_ECODE_FAILED;
270  }
271  }
272 
273  cfile->tenant_id = tenant_id;
274  cfile->continuous = continuous;
275  cfile->should_delete = should_delete;
276  cfile->delay = delay;
277  cfile->poll_interval = poll_interval;
278 
279  TAILQ_INSERT_TAIL(&this->files, cfile, next);
280  return TM_ECODE_OK;
281 }
282 
283 /**
284  * \brief Command to add a file to treatment list
285  *
286  * \param cmd the content of command Arguments as a json_t object
287  * \param answer the json_t object that has to be used to answer
288  * \param data pointer to data defining the context here a PcapCommand::
289  * \param continuous If this should run in continuous mode
290  */
291 static TmEcode UnixSocketAddPcapFileImpl(json_t *cmd, json_t* answer, void *data,
292  bool continuous)
293 {
294  PcapCommand *this = (PcapCommand *) data;
295  const char *filename;
296  const char *output_dir;
297  uint32_t tenant_id = 0;
298  bool should_delete = false;
299  time_t delay = 30;
300  time_t poll_interval = 5;
301  SCStat st;
302 
303  json_t *jarg = json_object_get(cmd, "filename");
304  if (!json_is_string(jarg)) {
305  SCLogError("filename is not a string");
306  json_object_set_new(answer, "message",
307  json_string("filename is not a string"));
308  return TM_ECODE_FAILED;
309  }
310  filename = json_string_value(jarg);
311  if (SCStatFn(filename, &st) != 0) {
312  json_object_set_new(answer, "message",
313  json_string("filename does not exist"));
314  return TM_ECODE_FAILED;
315  }
316 
317  json_t *oarg = json_object_get(cmd, "output-dir");
318  if (oarg != NULL) {
319  if (!json_is_string(oarg)) {
320  SCLogError("output-dir is not a string");
321 
322  json_object_set_new(answer, "message",
323  json_string("output-dir is not a string"));
324  return TM_ECODE_FAILED;
325  }
326  output_dir = json_string_value(oarg);
327  } else {
328  SCLogError("can't get output-dir");
329 
330  json_object_set_new(answer, "message",
331  json_string("output-dir param is mandatory"));
332  return TM_ECODE_FAILED;
333  }
334 
335  if (SCStatFn(output_dir, &st) != 0) {
336  json_object_set_new(answer, "message",
337  json_string("output-dir does not exist"));
338  return TM_ECODE_FAILED;
339  }
340 
341  json_t *targ = json_object_get(cmd, "tenant");
342  if (targ != NULL) {
343  if (!json_is_integer(targ)) {
344  json_object_set_new(answer, "message",
345  json_string("tenant is not a number"));
346  return TM_ECODE_FAILED;
347  }
348  tenant_id = json_number_value(targ);
349  }
350 
351  json_t *delete_arg = json_object_get(cmd, "delete-when-done");
352  if (delete_arg != NULL) {
353  should_delete = json_is_true(delete_arg);
354  }
355 
356  json_t *delay_arg = json_object_get(cmd, "delay");
357  if (delay_arg != NULL) {
358  if (!json_is_integer(delay_arg)) {
359  SCLogError("delay is not a integer");
360  json_object_set_new(answer, "message",
361  json_string("delay is not a integer"));
362  return TM_ECODE_FAILED;
363  }
364  delay = json_integer_value(delay_arg);
365  }
366 
367  json_t *interval_arg = json_object_get(cmd, "poll-interval");
368  if (interval_arg != NULL) {
369  if (!json_is_integer(interval_arg)) {
370  SCLogError("poll-interval is not a integer");
371 
372  json_object_set_new(answer, "message",
373  json_string("poll-interval is not a integer"));
374  return TM_ECODE_FAILED;
375  }
376  poll_interval = json_integer_value(interval_arg);
377  }
378 
379  switch (UnixListAddFile(this, filename, output_dir, tenant_id, continuous,
380  should_delete, delay, poll_interval)) {
381  case TM_ECODE_FAILED:
382  case TM_ECODE_DONE:
383  json_object_set_new(answer, "message",
384  json_string("Unable to add file to list"));
385  return TM_ECODE_FAILED;
386  case TM_ECODE_OK:
387  SCLogInfo("Added file '%s' to list", filename);
388  json_object_set_new(answer, "message",
389  json_string("Successfully added file to list"));
390  return TM_ECODE_OK;
391  }
392  return TM_ECODE_OK;
393 }
394 
395 /**
396  * \brief Command to add a file to treatment list
397  *
398  * \param cmd the content of command Arguments as a json_t object
399  * \param answer the json_t object that has to be used to answer
400  * \param data pointer to data defining the context here a PcapCommand::
401  */
402 static TmEcode UnixSocketAddPcapFile(json_t *cmd, json_t* answer, void *data)
403 {
404  bool continuous = false;
405 
406  json_t *cont_arg = json_object_get(cmd, "continuous");
407  if (cont_arg != NULL) {
408  continuous = json_is_true(cont_arg);
409  }
410 
411  return UnixSocketAddPcapFileImpl(cmd, answer, data, continuous);
412 }
413 
414 /**
415  * \brief Command to add a file to treatment list, forcing continuous mode
416  *
417  * \param cmd the content of command Arguments as a json_t object
418  * \param answer the json_t object that has to be used to answer
419  * \param data pointer to data defining the context here a PcapCommand::
420  */
421 static TmEcode UnixSocketAddPcapFileContinuous(json_t *cmd, json_t* answer, void *data)
422 {
423  return UnixSocketAddPcapFileImpl(cmd, answer, data, true);
424 }
425 
426 /**
427  * \brief Handle the file queue
428  *
429  * This function check if there is currently a file
430  * being parse. If it is not the case, it will start to
431  * work on a new file. This implies to start a new 'pcap-file'
432  * running mode after having set the file and the output dir.
433  * This function also handles the cleaning of the previous
434  * running mode.
435  *
436  * \param this a UnixCommand:: structure
437  * \retval 0 in case of error, 1 in case of success
438  */
439 static TmEcode UnixSocketPcapFilesCheck(void *data)
440 {
441  PcapCommand *this = (PcapCommand *) data;
442  if (unix_manager_pcap_task_running == 1) {
443  return TM_ECODE_OK;
444  }
445  if ((unix_manager_pcap_task_failed == 1) || (this->running == 1)) {
446  if (unix_manager_pcap_task_failed) {
447  SCLogInfo("Preceeding task failed, cleaning the running mode");
448  }
449  unix_manager_pcap_task_failed = 0;
450  this->running = 0;
451 
452  SCLogInfo("Resetting engine state");
453  PostRunDeinit(RUNMODE_PCAP_FILE, NULL /* no ts */);
454 
455  if (this->current_file) {
456  PcapFilesFree(this->current_file);
457  }
458  this->current_file = NULL;
459  }
460 
461  if (TAILQ_EMPTY(&this->files)) {
462  // nothing to do
463  return TM_ECODE_OK;
464  }
465 
466  PcapFiles *cfile = TAILQ_FIRST(&this->files);
467  TAILQ_REMOVE(&this->files, cfile, next);
468 
469  unix_manager_pcap_task_running = 1;
470  this->running = 1;
471 
472  if (ConfSetFinal("pcap-file.file", cfile->filename) != 1) {
473  SCLogError("Can not set working file to '%s'", cfile->filename);
474  PcapFilesFree(cfile);
475  return TM_ECODE_FAILED;
476  }
477 
478  int set_res = 0;
479  if (cfile->continuous) {
480  set_res = ConfSetFinal("pcap-file.continuous", "true");
481  } else {
482  set_res = ConfSetFinal("pcap-file.continuous", "false");
483  }
484  if (set_res != 1) {
485  SCLogError("Can not set continuous mode for pcap processing");
486  PcapFilesFree(cfile);
487  return TM_ECODE_FAILED;
488  }
489  if (cfile->should_delete) {
490  set_res = ConfSetFinal("pcap-file.delete-when-done", "true");
491  } else {
492  set_res = ConfSetFinal("pcap-file.delete-when-done", "false");
493  }
494  if (set_res != 1) {
495  SCLogError("Can not set delete mode for pcap processing");
496  PcapFilesFree(cfile);
497  return TM_ECODE_FAILED;
498  }
499 
500  if (cfile->delay > 0) {
501  char tstr[32];
502  snprintf(tstr, sizeof(tstr), "%" PRIuMAX, (uintmax_t)cfile->delay);
503  if (ConfSetFinal("pcap-file.delay", tstr) != 1) {
504  SCLogError("Can not set delay to '%s'", tstr);
505  PcapFilesFree(cfile);
506  return TM_ECODE_FAILED;
507  }
508  }
509 
510  if (cfile->poll_interval > 0) {
511  char tstr[32];
512  snprintf(tstr, sizeof(tstr), "%" PRIuMAX, (uintmax_t)cfile->poll_interval);
513  if (ConfSetFinal("pcap-file.poll-interval", tstr) != 1) {
514  SCLogError("Can not set poll-interval to '%s'", tstr);
515  PcapFilesFree(cfile);
516  return TM_ECODE_FAILED;
517  }
518  }
519 
520  if (cfile->tenant_id > 0) {
521  char tstr[16];
522  snprintf(tstr, sizeof(tstr), "%u", cfile->tenant_id);
523  if (ConfSetFinal("pcap-file.tenant-id", tstr) != 1) {
524  SCLogError("Can not set working tenant-id to '%s'", tstr);
525  PcapFilesFree(cfile);
526  return TM_ECODE_FAILED;
527  }
528  } else {
529  SCLogInfo("pcap-file.tenant-id not set");
530  }
531 
532  if (cfile->output_dir) {
533  if (ConfSetFinal("default-log-dir", cfile->output_dir) != 1) {
534  SCLogError("Can not set output dir to '%s'", cfile->output_dir);
535  PcapFilesFree(cfile);
536  return TM_ECODE_FAILED;
537  }
538  }
539 
540  this->current_file = cfile;
541 
542  SCLogInfo("Starting run for '%s'", this->current_file->filename);
543 
546  RunModeDispatch(RUNMODE_PCAP_FILE, NULL, NULL, NULL);
547 
548  /* Un-pause all the paused threads */
552 
553  return TM_ECODE_OK;
554 }
555 #endif
556 
558 {
559 #ifdef BUILD_UNIX_SOCKET
560  /* a bit of a hack, but register twice to --list-runmodes shows both */
562  RUNMODE_UNIX_SOCKET, "single", "Unix socket mode", RunModeUnixSocketMaster, NULL);
564  RUNMODE_UNIX_SOCKET, "autofp", "Unix socket mode", RunModeUnixSocketMaster, NULL);
565 #endif
566 }
567 
568 TmEcode UnixSocketPcapFile(TmEcode tm, struct timespec *last_processed)
569 {
570 #ifdef BUILD_UNIX_SOCKET
571  if(last_processed) {
572  SCCtrlMutexLock(&unix_manager_pcap_last_processed_mutex);
573  unix_manager_pcap_last_processed.tv_sec = last_processed->tv_sec;
574  unix_manager_pcap_last_processed.tv_nsec = last_processed->tv_nsec;
575  SCCtrlMutexUnlock(&unix_manager_pcap_last_processed_mutex);
576  }
577  switch (tm) {
578  case TM_ECODE_DONE:
579  SCLogInfo("Marking current task as done");
580  unix_manager_pcap_task_running = 0;
581  return TM_ECODE_DONE;
582  case TM_ECODE_FAILED:
583  SCLogInfo("Marking current task as failed");
584  unix_manager_pcap_task_running = 0;
585  unix_manager_pcap_task_failed = 1;
586  //if we return failed, we can't stop the thread and suricata will fail to close
587  return TM_ECODE_FAILED;
588  case TM_ECODE_OK:
589  if (unix_manager_pcap_task_interrupted == 1) {
590  SCLogInfo("Interrupting current run mode");
591  unix_manager_pcap_task_interrupted = 0;
592  return TM_ECODE_DONE;
593  } else {
594  return TM_ECODE_OK;
595  }
596  }
597 #endif
598  return TM_ECODE_FAILED;
599 }
600 
601 #ifdef BUILD_UNIX_SOCKET
602 /**
603  * \brief Command to add data to a dataset
604  *
605  * \param cmd the content of command Arguments as a json_t object
606  * \param answer the json_t object that has to be used to answer
607  * \param data pointer to data defining the context here a PcapCommand::
608  */
609 TmEcode UnixSocketDatasetAdd(json_t *cmd, json_t* answer, void *data)
610 {
611  /* 1 get dataset name */
612  json_t *narg = json_object_get(cmd, "setname");
613  if (!json_is_string(narg)) {
614  json_object_set_new(answer, "message", json_string("setname is not a string"));
615  return TM_ECODE_FAILED;
616  }
617  const char *set_name = json_string_value(narg);
618 
619  /* 2 get the data type */
620  json_t *targ = json_object_get(cmd, "settype");
621  if (!json_is_string(targ)) {
622  json_object_set_new(answer, "message", json_string("settype is not a string"));
623  return TM_ECODE_FAILED;
624  }
625  const char *type = json_string_value(targ);
626 
627  /* 3 get value */
628  json_t *varg = json_object_get(cmd, "datavalue");
629  if (!json_is_string(varg)) {
630  json_object_set_new(answer, "message", json_string("datavalue is not string"));
631  return TM_ECODE_FAILED;
632  }
633  const char *value = json_string_value(varg);
634 
635  SCLogDebug("dataset-add: %s type %s value %s", set_name, type, value);
636 
638  if (t == DATASET_TYPE_NOTSET) {
639  json_object_set_new(answer, "message", json_string("unknown settype"));
640  return TM_ECODE_FAILED;
641  }
642 
643  Dataset *set = DatasetFind(set_name, t);
644  if (set == NULL) {
645  json_object_set_new(answer, "message", json_string("set not found or wrong type"));
646  return TM_ECODE_FAILED;
647  }
648 
649  int r = DatasetAddSerialized(set, value);
650  if (r == 1) {
651  json_object_set_new(answer, "message", json_string("data added"));
652  return TM_ECODE_OK;
653  } else if (r == 0) {
654  json_object_set_new(answer, "message", json_string("data already in set"));
655  return TM_ECODE_OK;
656  } else {
657  json_object_set_new(answer, "message", json_string("failed to add data"));
658  return TM_ECODE_FAILED;
659  }
660 }
661 
662 TmEcode UnixSocketDatasetRemove(json_t *cmd, json_t* answer, void *data)
663 {
664  /* 1 get dataset name */
665  json_t *narg = json_object_get(cmd, "setname");
666  if (!json_is_string(narg)) {
667  json_object_set_new(answer, "message", json_string("setname is not a string"));
668  return TM_ECODE_FAILED;
669  }
670  const char *set_name = json_string_value(narg);
671 
672  /* 2 get the data type */
673  json_t *targ = json_object_get(cmd, "settype");
674  if (!json_is_string(targ)) {
675  json_object_set_new(answer, "message", json_string("settype is not a string"));
676  return TM_ECODE_FAILED;
677  }
678  const char *type = json_string_value(targ);
679 
680  /* 3 get value */
681  json_t *varg = json_object_get(cmd, "datavalue");
682  if (!json_is_string(varg)) {
683  json_object_set_new(answer, "message", json_string("datavalue is not string"));
684  return TM_ECODE_FAILED;
685  }
686  const char *value = json_string_value(varg);
687 
688  SCLogDebug("dataset-remove: %s type %s value %s", set_name, type, value);
689 
691  if (t == DATASET_TYPE_NOTSET) {
692  json_object_set_new(answer, "message", json_string("unknown settype"));
693  return TM_ECODE_FAILED;
694  }
695 
696  Dataset *set = DatasetFind(set_name, t);
697  if (set == NULL) {
698  json_object_set_new(answer, "message", json_string("set not found or wrong type"));
699  return TM_ECODE_FAILED;
700  }
701 
702  int r = DatasetRemoveSerialized(set, value);
703  if (r == 1) {
704  json_object_set_new(answer, "message", json_string("data removed"));
705  return TM_ECODE_OK;
706  } else if (r == 0) {
707  json_object_set_new(answer, "message", json_string("data is busy, try again"));
708  return TM_ECODE_OK;
709  } else {
710  json_object_set_new(answer, "message", json_string("failed to remove data"));
711  return TM_ECODE_FAILED;
712  }
713 }
714 
715 TmEcode UnixSocketDatasetDump(json_t *cmd, json_t *answer, void *data)
716 {
717  SCEnter();
718  SCLogDebug("Going to dump datasets");
719  DatasetsSave();
720  json_object_set_new(answer, "message", json_string("datasets dump done"));
722 }
723 
724 TmEcode UnixSocketDatasetClear(json_t *cmd, json_t *answer, void *data)
725 {
726  /* 1 get dataset name */
727  json_t *narg = json_object_get(cmd, "setname");
728  if (!json_is_string(narg)) {
729  json_object_set_new(answer, "message", json_string("setname is not a string"));
730  return TM_ECODE_FAILED;
731  }
732  const char *set_name = json_string_value(narg);
733 
734  /* 2 get the data type */
735  json_t *targ = json_object_get(cmd, "settype");
736  if (!json_is_string(targ)) {
737  json_object_set_new(answer, "message", json_string("settype is not a string"));
738  return TM_ECODE_FAILED;
739  }
740  const char *type = json_string_value(targ);
741 
743  if (t == DATASET_TYPE_NOTSET) {
744  json_object_set_new(answer, "message", json_string("unknown settype"));
745  return TM_ECODE_FAILED;
746  }
747 
748  Dataset *set = DatasetFind(set_name, t);
749  if (set == NULL) {
750  json_object_set_new(answer, "message", json_string("set not found or wrong type"));
751  return TM_ECODE_FAILED;
752  }
753 
754  THashCleanup(set->hash);
755 
756  json_object_set_new(answer, "message", json_string("dataset cleared"));
757  return TM_ECODE_OK;
758 }
759 
760 TmEcode UnixSocketDatasetLookup(json_t *cmd, json_t *answer, void *data)
761 {
762  /* 1 get dataset name */
763  json_t *narg = json_object_get(cmd, "setname");
764  if (!json_is_string(narg)) {
765  json_object_set_new(answer, "message", json_string("setname is not a string"));
766  return TM_ECODE_FAILED;
767  }
768  const char *set_name = json_string_value(narg);
769 
770  /* 2 get the data type */
771  json_t *targ = json_object_get(cmd, "settype");
772  if (!json_is_string(targ)) {
773  json_object_set_new(answer, "message", json_string("settype is not a string"));
774  return TM_ECODE_FAILED;
775  }
776  const char *type = json_string_value(targ);
777 
778  /* 3 get value */
779  json_t *varg = json_object_get(cmd, "datavalue");
780  if (!json_is_string(varg)) {
781  json_object_set_new(answer, "message", json_string("datavalue is not string"));
782  return TM_ECODE_FAILED;
783  }
784  const char *value = json_string_value(varg);
785 
786  SCLogDebug("dataset-exist: %s type %s value %s", set_name, type, value);
787 
789  if (t == DATASET_TYPE_NOTSET) {
790  json_object_set_new(answer, "message", json_string("unknown settype"));
791  return TM_ECODE_FAILED;
792  }
793 
794  Dataset *set = DatasetFind(set_name, t);
795  if (set == NULL) {
796  json_object_set_new(answer, "message", json_string("set not found or wrong type"));
797  return TM_ECODE_FAILED;
798  }
799 
800  if (DatasetLookupSerialized(set, value) > 0) {
801  json_object_set_new(answer, "message", json_string("item found in set"));
802  return TM_ECODE_OK;
803  } else {
804  json_object_set_new(answer, "message", json_string("item not found in set"));
805  return TM_ECODE_FAILED;
806  }
807 }
808 
809 static bool JsonU32Value(json_t *jarg, uint32_t *ret)
810 {
811  int64_t r = json_integer_value(jarg);
812  if (r < 0 || r > UINT32_MAX) {
813  return false;
814  }
815  *ret = (uint32_t)r;
816  return true;
817 }
818 
819 /**
820  * \brief Command to add a tenant handler
821  *
822  * \param cmd the content of command Arguments as a json_t object
823  * \param answer the json_t object that has to be used to answer
824  * \param data pointer to data defining the context here a PcapCommand::
825  */
826 TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data)
827 {
828  const char *htype;
829  json_int_t traffic_id = -1;
830 
832  SCLogInfo("error: multi-tenant support not enabled");
833  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
834  return TM_ECODE_FAILED;
835  }
836 
837  /* 1 get tenant id */
838  json_t *jarg = json_object_get(cmd, "id");
839  if (!json_is_integer(jarg)) {
840  SCLogInfo("error: command is not a string");
841  json_object_set_new(answer, "message", json_string("id is not an integer"));
842  return TM_ECODE_FAILED;
843  }
844  uint32_t tenant_id;
845  if (!JsonU32Value(jarg, &tenant_id)) {
846  SCLogInfo("tenant_id is not a uint32");
847  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
848  return TM_ECODE_FAILED;
849  }
850 
851  /* 2 get tenant handler type */
852  jarg = json_object_get(cmd, "htype");
853  if (!json_is_string(jarg)) {
854  SCLogInfo("error: command is not a string");
855  json_object_set_new(answer, "message", json_string("command is not a string"));
856  return TM_ECODE_FAILED;
857  }
858  htype = json_string_value(jarg);
859 
860  SCLogDebug("add-tenant-handler: %d %s", tenant_id, htype);
861 
862  /* 3 get optional hargs */
863  json_t *hargs = json_object_get(cmd, "hargs");
864  if (hargs != NULL) {
865  if (!json_is_integer(hargs)) {
866  SCLogInfo("error: hargs not a number");
867  json_object_set_new(answer, "message", json_string("hargs not a number"));
868  return TM_ECODE_FAILED;
869  }
870  traffic_id = json_integer_value(hargs);
871  }
872 
873  /* 4 add to system */
874  int r = -1;
875  if (strcmp(htype, "pcap") == 0) {
876  r = DetectEngineTenantRegisterPcapFile(tenant_id);
877  } else if (strcmp(htype, "vlan") == 0) {
878  if (traffic_id < 0) {
879  json_object_set_new(answer, "message", json_string("vlan requires argument"));
880  return TM_ECODE_FAILED;
881  }
882  if (traffic_id > USHRT_MAX) {
883  json_object_set_new(answer, "message", json_string("vlan argument out of range"));
884  return TM_ECODE_FAILED;
885  }
886 
887  SCLogInfo("VLAN handler: id %u maps to tenant %u", (uint32_t)traffic_id, tenant_id);
888  r = DetectEngineTenantRegisterVlanId(tenant_id, (uint16_t)traffic_id);
889  }
890  if (r != 0) {
891  json_object_set_new(answer, "message", json_string("handler setup failure"));
892  return TM_ECODE_FAILED;
893  }
894 
895  if (DetectEngineMTApply() < 0) {
896  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
897  // TODO cleanup
898  return TM_ECODE_FAILED;
899  }
900 
901  json_object_set_new(answer, "message", json_string("handler added"));
902  return TM_ECODE_OK;
903 }
904 
905 /**
906  * \brief Command to remove a tenant handler
907  *
908  * \param cmd the content of command Arguments as a json_t object
909  * \param answer the json_t object that has to be used to answer
910  * \param data pointer to data defining the context here a PcapCommand::
911  */
912 TmEcode UnixSocketUnregisterTenantHandler(json_t *cmd, json_t* answer, void *data)
913 {
914  const char *htype;
915  json_int_t traffic_id = -1;
916 
918  SCLogInfo("error: multi-tenant support not enabled");
919  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
920  return TM_ECODE_FAILED;
921  }
922 
923  /* 1 get tenant id */
924  json_t *jarg = json_object_get(cmd, "id");
925  if (!json_is_integer(jarg)) {
926  SCLogInfo("error: command is not a string");
927  json_object_set_new(answer, "message", json_string("id is not an integer"));
928  return TM_ECODE_FAILED;
929  }
930  uint32_t tenant_id;
931  if (!JsonU32Value(jarg, &tenant_id)) {
932  SCLogInfo("tenant_id is not a uint32");
933  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
934  return TM_ECODE_FAILED;
935  }
936 
937  /* 2 get tenant handler type */
938  jarg = json_object_get(cmd, "htype");
939  if (!json_is_string(jarg)) {
940  SCLogInfo("error: command is not a string");
941  json_object_set_new(answer, "message", json_string("command is not a string"));
942  return TM_ECODE_FAILED;
943  }
944  htype = json_string_value(jarg);
945 
946  SCLogDebug("add-tenant-handler: %d %s", tenant_id, htype);
947 
948  /* 3 get optional hargs */
949  json_t *hargs = json_object_get(cmd, "hargs");
950  if (hargs != NULL) {
951  if (!json_is_integer(hargs)) {
952  SCLogInfo("error: hargs not a number");
953  json_object_set_new(answer, "message", json_string("hargs not a number"));
954  return TM_ECODE_FAILED;
955  }
956  traffic_id = json_integer_value(hargs);
957  }
958 
959  /* 4 add to system */
960  int r = -1;
961  if (strcmp(htype, "pcap") == 0) {
963  } else if (strcmp(htype, "vlan") == 0) {
964  if (traffic_id < 0) {
965  json_object_set_new(answer, "message", json_string("vlan requires argument"));
966  return TM_ECODE_FAILED;
967  }
968  if (traffic_id > USHRT_MAX) {
969  json_object_set_new(answer, "message", json_string("vlan argument out of range"));
970  return TM_ECODE_FAILED;
971  }
972 
973  SCLogInfo("VLAN handler: removing mapping of %u to tenant %u", (uint32_t)traffic_id, tenant_id);
974  r = DetectEngineTenantUnregisterVlanId(tenant_id, (uint16_t)traffic_id);
975  }
976  if (r != 0) {
977  json_object_set_new(answer, "message", json_string("handler unregister failure"));
978  return TM_ECODE_FAILED;
979  }
980 
981  /* 5 apply it */
982  if (DetectEngineMTApply() < 0) {
983  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
984  // TODO cleanup
985  return TM_ECODE_FAILED;
986  }
987 
988  json_object_set_new(answer, "message", json_string("handler removed"));
989  return TM_ECODE_OK;
990 }
991 
992 /**
993  * \brief Command to add a tenant
994  *
995  * \param cmd the content of command Arguments as a json_t object
996  * \param answer the json_t object that has to be used to answer
997  * \param data pointer to data defining the context here a PcapCommand::
998  */
999 TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data)
1000 {
1001  const char *filename;
1002  SCStat st;
1003 
1004  if (!(DetectEngineMultiTenantEnabled())) {
1005  SCLogInfo("error: multi-tenant support not enabled");
1006  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1007  return TM_ECODE_FAILED;
1008  }
1009 
1010  /* 1 get tenant id */
1011  json_t *jarg = json_object_get(cmd, "id");
1012  if (!json_is_integer(jarg)) {
1013  json_object_set_new(answer, "message", json_string("id is not an integer"));
1014  return TM_ECODE_FAILED;
1015  }
1016  uint32_t tenant_id;
1017  if (!JsonU32Value(jarg, &tenant_id)) {
1018  SCLogInfo("tenant_id is not a uint32");
1019  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
1020  return TM_ECODE_FAILED;
1021  }
1022 
1023  /* 2 get tenant yaml */
1024  jarg = json_object_get(cmd, "filename");
1025  if (!json_is_string(jarg)) {
1026  json_object_set_new(answer, "message", json_string("command is not a string"));
1027  return TM_ECODE_FAILED;
1028  }
1029  filename = json_string_value(jarg);
1030  if (SCStatFn(filename, &st) != 0) {
1031  json_object_set_new(answer, "message", json_string("file does not exist"));
1032  return TM_ECODE_FAILED;
1033  }
1034 
1035  SCLogDebug("add-tenant: %d %s", tenant_id, filename);
1036 
1037  /* setup the yaml in this loop so that it's not done by the loader
1038  * threads. ConfYamlLoadFileWithPrefix is not thread safe. */
1039  char prefix[64];
1040  snprintf(prefix, sizeof(prefix), "multi-detect.%u", tenant_id);
1041  if (ConfYamlLoadFileWithPrefix(filename, prefix) != 0) {
1042  SCLogError("failed to load yaml %s", filename);
1043  json_object_set_new(answer, "message", json_string("failed to load yaml"));
1044  return TM_ECODE_FAILED;
1045  }
1046 
1047  /* 3 load into the system */
1048  if (DetectEngineLoadTenantBlocking(tenant_id, filename) != 0) {
1049  json_object_set_new(answer, "message", json_string("adding tenant failed"));
1050  return TM_ECODE_FAILED;
1051  }
1052 
1053  /* 4 apply to the running system */
1054  if (DetectEngineMTApply() < 0) {
1055  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1056  // TODO cleanup
1057  return TM_ECODE_FAILED;
1058  }
1059 
1060  json_object_set_new(answer, "message", json_string("adding tenant succeeded"));
1061  return TM_ECODE_OK;
1062 }
1063 
1064 static int reload_cnt = 1;
1065 /**
1066  * \brief Command to reload a tenant
1067  *
1068  * \param cmd the content of command Arguments as a json_t object
1069  * \param answer the json_t object that has to be used to answer
1070  * \param data pointer to data defining the context here a PcapCommand::
1071  */
1072 TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data)
1073 {
1074  const char *filename = NULL;
1075  SCStat st;
1076 
1077  if (!(DetectEngineMultiTenantEnabled())) {
1078  SCLogInfo("error: multi-tenant support not enabled");
1079  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1080  return TM_ECODE_FAILED;
1081  }
1082 
1083  /* 1 get tenant id */
1084  json_t *jarg = json_object_get(cmd, "id");
1085  if (!json_is_integer(jarg)) {
1086  json_object_set_new(answer, "message", json_string("id is not an integer"));
1087  return TM_ECODE_FAILED;
1088  }
1089  uint32_t tenant_id;
1090  if (!JsonU32Value(jarg, &tenant_id)) {
1091  SCLogInfo("tenant_id is not a uint32");
1092  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
1093  return TM_ECODE_FAILED;
1094  }
1095 
1096  /* 2 get tenant yaml */
1097  jarg = json_object_get(cmd, "filename");
1098  if (jarg) {
1099  if (!json_is_string(jarg)) {
1100  json_object_set_new(answer, "message", json_string("command is not a string"));
1101  return TM_ECODE_FAILED;
1102  }
1103  filename = json_string_value(jarg);
1104  if (SCStatFn(filename, &st) != 0) {
1105  json_object_set_new(answer, "message", json_string("file does not exist"));
1106  return TM_ECODE_FAILED;
1107  }
1108  }
1109 
1110  SCLogDebug("reload-tenant: %d %s", tenant_id, filename);
1111 
1112  /* 3 load into the system */
1113  if (DetectEngineReloadTenantBlocking(tenant_id, filename, reload_cnt) != 0) {
1114  json_object_set_new(answer, "message", json_string("reload tenant failed"));
1115  return TM_ECODE_FAILED;
1116  }
1117 
1118  reload_cnt++;
1119 
1120  /* apply to the running system */
1121  if (DetectEngineMTApply() < 0) {
1122  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1123  // TODO cleanup
1124  return TM_ECODE_FAILED;
1125  }
1126 
1127  json_object_set_new(answer, "message", json_string("reloading tenant succeeded"));
1128  return TM_ECODE_OK;
1129 }
1130 
1131 /**
1132  * \brief Command to reload all tenants
1133  *
1134  * \param cmd the content of command Arguments as a json_t object
1135  * \param answer the json_t object that has to be used to answer
1136  * \param data pointer to data defining the context here a PcapCommand::
1137  */
1138 TmEcode UnixSocketReloadTenants(json_t *cmd, json_t *answer, void *data)
1139 {
1140  if (!(DetectEngineMultiTenantEnabled())) {
1141  SCLogInfo("error: multi-tenant support not enabled");
1142  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1143  return TM_ECODE_FAILED;
1144  }
1145 
1146  if (DetectEngineReloadTenantsBlocking(reload_cnt) != 0) {
1147  json_object_set_new(answer, "message", json_string("reload tenants failed"));
1148  return TM_ECODE_FAILED;
1149  }
1150 
1151  reload_cnt++;
1152 
1153  /* apply to the running system */
1154  if (DetectEngineMTApply() < 0) {
1155  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1156  // TODO cleanup
1157  return TM_ECODE_FAILED;
1158  }
1159 
1160  SCLogNotice("reload-tenants complete");
1161 
1162  json_object_set_new(answer, "message", json_string("reloading tenants succeeded"));
1163  return TM_ECODE_OK;
1164 }
1165 
1166 /**
1167  * \brief Command to remove a tenant
1168  *
1169  * \param cmd the content of command Arguments as a json_t object
1170  * \param answer the json_t object that has to be used to answer
1171  * \param data pointer to data defining the context here a PcapCommand::
1172  */
1173 TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data)
1174 {
1175  if (!(DetectEngineMultiTenantEnabled())) {
1176  SCLogInfo("error: multi-tenant support not enabled");
1177  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1178  return TM_ECODE_FAILED;
1179  }
1180 
1181  /* 1 get tenant id */
1182  json_t *jarg = json_object_get(cmd, "id");
1183  if (!json_is_integer(jarg)) {
1184  SCLogInfo("error: command is not a string");
1185  json_object_set_new(answer, "message", json_string("id is not an integer"));
1186  return TM_ECODE_FAILED;
1187  }
1188  uint32_t tenant_id;
1189  if (!JsonU32Value(jarg, &tenant_id)) {
1190  SCLogInfo("tenant_id is not a uint32");
1191  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
1192  return TM_ECODE_FAILED;
1193  }
1194 
1195  SCLogInfo("remove-tenant: removing tenant %d", tenant_id);
1196 
1197  /* 2 remove it from the system */
1198  char prefix[64];
1199  snprintf(prefix, sizeof(prefix), "multi-detect.%u", tenant_id);
1200 
1202  if (de_ctx == NULL) {
1203  json_object_set_new(answer, "message", json_string("tenant detect engine not found"));
1204  return TM_ECODE_FAILED;
1205  }
1206 
1207  /* move to free list */
1210 
1211  /* update the threads */
1212  if (DetectEngineMTApply() < 0) {
1213  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1214  // TODO cleanup
1215  return TM_ECODE_FAILED;
1216  }
1217 
1218  /* walk free list, freeing the removed de_ctx */
1220 
1221  json_object_set_new(answer, "message", json_string("removing tenant succeeded"));
1222  return TM_ECODE_OK;
1223 }
1224 
1225 /**
1226  * \brief Command to add a hostbit
1227  *
1228  * \param cmd the content of command Arguments as a json_t object
1229  * \param answer the json_t object that has to be used to answer
1230  */
1231 TmEcode UnixSocketHostbitAdd(json_t *cmd, json_t* answer, void *data_usused)
1232 {
1233  /* 1 get ip address */
1234  json_t *jarg = json_object_get(cmd, "ipaddress");
1235  if (!json_is_string(jarg)) {
1236  json_object_set_new(answer, "message", json_string("ipaddress is not an string"));
1237  return TM_ECODE_FAILED;
1238  }
1239  const char *ipaddress = json_string_value(jarg);
1240 
1241  Address a;
1242  struct in_addr in;
1243  memset(&in, 0, sizeof(in));
1244  if (inet_pton(AF_INET, ipaddress, &in) != 1) {
1245  uint32_t in6[4];
1246  memset(&in6, 0, sizeof(in6));
1247  if (inet_pton(AF_INET6, ipaddress, &in) != 1) {
1248  json_object_set_new(answer, "message", json_string("invalid address string"));
1249  return TM_ECODE_FAILED;
1250  } else {
1251  a.family = AF_INET6;
1252  a.addr_data32[0] = in6[0];
1253  a.addr_data32[1] = in6[1];
1254  a.addr_data32[2] = in6[2];
1255  a.addr_data32[3] = in6[3];
1256  }
1257  } else {
1258  a.family = AF_INET;
1259  a.addr_data32[0] = in.s_addr;
1260  a.addr_data32[1] = 0;
1261  a.addr_data32[2] = 0;
1262  a.addr_data32[3] = 0;
1263  }
1264 
1265  /* 2 get variable name */
1266  jarg = json_object_get(cmd, "hostbit");
1267  if (!json_is_string(jarg)) {
1268  json_object_set_new(answer, "message", json_string("hostbit is not a string"));
1269  return TM_ECODE_FAILED;
1270  }
1271  const char *hostbit = json_string_value(jarg);
1272  uint32_t idx = VarNameStoreLookupByName(hostbit, VAR_TYPE_HOST_BIT);
1273  if (idx == 0) {
1274  json_object_set_new(answer, "message", json_string("hostbit not found"));
1275  return TM_ECODE_FAILED;
1276  }
1277 
1278  /* 3 get expire */
1279  jarg = json_object_get(cmd, "expire");
1280  if (!json_is_integer(jarg)) {
1281  json_object_set_new(answer, "message", json_string("expire is not an integer"));
1282  return TM_ECODE_FAILED;
1283  }
1284  uint32_t expire;
1285  if (!JsonU32Value(jarg, &expire)) {
1286  SCLogInfo("expire is not a uint32");
1287  json_object_set_new(answer, "message", json_string("expire is not a uint32"));
1288  return TM_ECODE_FAILED;
1289  }
1290 
1291  SCLogInfo("add-hostbit: ip %s hostbit %s expire %us", ipaddress, hostbit, expire);
1292 
1293  SCTime_t current_time = TimeGet();
1294  Host *host = HostGetHostFromHash(&a);
1295  if (host) {
1296  if (SCTIME_SECS(current_time) + expire > UINT32_MAX) {
1297  json_object_set_new(answer, "message", json_string("couldn't set host expire"));
1298  HostRelease(host);
1299  return TM_ECODE_FAILED;
1300  }
1301  HostBitSet(host, idx, (uint32_t)(SCTIME_SECS(current_time) + expire));
1302  HostRelease(host);
1303 
1304  json_object_set_new(answer, "message", json_string("hostbit added"));
1305  return TM_ECODE_OK;
1306  } else {
1307  json_object_set_new(answer, "message", json_string("couldn't create host"));
1308  return TM_ECODE_FAILED;
1309  }
1310 }
1311 
1312 /**
1313  * \brief Command to remove a hostbit
1314  *
1315  * \param cmd the content of command Arguments as a json_t object
1316  * \param answer the json_t object that has to be used to answer
1317  */
1318 TmEcode UnixSocketHostbitRemove(json_t *cmd, json_t* answer, void *data_unused)
1319 {
1320  /* 1 get ip address */
1321  json_t *jarg = json_object_get(cmd, "ipaddress");
1322  if (!json_is_string(jarg)) {
1323  json_object_set_new(answer, "message", json_string("ipaddress is not an string"));
1324  return TM_ECODE_FAILED;
1325  }
1326  const char *ipaddress = json_string_value(jarg);
1327 
1328  Address a;
1329  struct in_addr in;
1330  memset(&in, 0, sizeof(in));
1331  if (inet_pton(AF_INET, ipaddress, &in) != 1) {
1332  uint32_t in6[4];
1333  memset(&in6, 0, sizeof(in6));
1334  if (inet_pton(AF_INET6, ipaddress, &in) != 1) {
1335  json_object_set_new(answer, "message", json_string("invalid address string"));
1336  return TM_ECODE_FAILED;
1337  } else {
1338  a.family = AF_INET6;
1339  a.addr_data32[0] = in6[0];
1340  a.addr_data32[1] = in6[1];
1341  a.addr_data32[2] = in6[2];
1342  a.addr_data32[3] = in6[3];
1343  }
1344  } else {
1345  a.family = AF_INET;
1346  a.addr_data32[0] = in.s_addr;
1347  a.addr_data32[1] = 0;
1348  a.addr_data32[2] = 0;
1349  a.addr_data32[3] = 0;
1350  }
1351 
1352  /* 2 get variable name */
1353  jarg = json_object_get(cmd, "hostbit");
1354  if (!json_is_string(jarg)) {
1355  json_object_set_new(answer, "message", json_string("hostbit is not a string"));
1356  return TM_ECODE_FAILED;
1357  }
1358 
1359  const char *hostbit = json_string_value(jarg);
1360  uint32_t idx = VarNameStoreLookupByName(hostbit, VAR_TYPE_HOST_BIT);
1361  if (idx == 0) {
1362  json_object_set_new(answer, "message", json_string("hostbit not found"));
1363  return TM_ECODE_FAILED;
1364  }
1365 
1366  SCLogInfo("remove-hostbit: %s %s", ipaddress, hostbit);
1367 
1368  Host *host = HostLookupHostFromHash(&a);
1369  if (host) {
1370  HostBitUnset(host, idx);
1371  HostRelease(host);
1372  json_object_set_new(answer, "message", json_string("hostbit removed"));
1373  return TM_ECODE_OK;
1374  } else {
1375  json_object_set_new(answer, "message", json_string("host not found"));
1376  return TM_ECODE_FAILED;
1377  }
1378 }
1379 
1380 /**
1381  * \brief Command to list hostbits for an ip
1382  *
1383  * \param cmd the content of command Arguments as a json_t object
1384  * \param answer the json_t object that has to be used to answer
1385  *
1386  * Message looks like:
1387  * {"message": {"count": 1, "hostbits": [{"expire": 3222, "name": "firefox-users"}]}, "return": "OK"}
1388  *
1389  * \retval r TM_ECODE_OK or TM_ECODE_FAILED
1390  */
1391 TmEcode UnixSocketHostbitList(json_t *cmd, json_t* answer, void *data_unused)
1392 {
1393  /* 1 get ip address */
1394  json_t *jarg = json_object_get(cmd, "ipaddress");
1395  if (!json_is_string(jarg)) {
1396  json_object_set_new(answer, "message", json_string("ipaddress is not an string"));
1397  return TM_ECODE_FAILED;
1398  }
1399  const char *ipaddress = json_string_value(jarg);
1400 
1401  Address a;
1402  struct in_addr in;
1403  memset(&in, 0, sizeof(in));
1404  if (inet_pton(AF_INET, ipaddress, &in) != 1) {
1405  uint32_t in6[4];
1406  memset(&in6, 0, sizeof(in6));
1407  if (inet_pton(AF_INET6, ipaddress, &in) != 1) {
1408  json_object_set_new(answer, "message", json_string("invalid address string"));
1409  return TM_ECODE_FAILED;
1410  } else {
1411  a.family = AF_INET6;
1412  a.addr_data32[0] = in6[0];
1413  a.addr_data32[1] = in6[1];
1414  a.addr_data32[2] = in6[2];
1415  a.addr_data32[3] = in6[3];
1416  }
1417  } else {
1418  a.family = AF_INET;
1419  a.addr_data32[0] = in.s_addr;
1420  a.addr_data32[1] = 0;
1421  a.addr_data32[2] = 0;
1422  a.addr_data32[3] = 0;
1423  }
1424 
1425  SCLogInfo("list-hostbit: %s", ipaddress);
1426 
1427  SCTime_t ts = TimeGet();
1428 
1429  struct Bit {
1430  uint32_t id;
1431  uint32_t expire;
1432  } bits[256];
1433  memset(&bits, 0, sizeof(bits));
1434  int i = 0, use = 0;
1435 
1436  Host *host = HostLookupHostFromHash(&a);
1437  if (!host) {
1438  json_object_set_new(answer, "message", json_string("host not found"));
1439  return TM_ECODE_FAILED;
1440  }
1441 
1442  XBit *iter = NULL;
1443  while (use < 256 && HostBitList(host, &iter) == 1) {
1444  bits[use].id = iter->idx;
1445  bits[use].expire = iter->expire;
1446  use++;
1447  }
1448  HostRelease(host);
1449 
1450  json_t *jdata = json_object();
1451  json_t *jarray = json_array();
1452  if (jarray == NULL || jdata == NULL) {
1453  if (jdata != NULL)
1454  json_decref(jdata);
1455  if (jarray != NULL)
1456  json_decref(jarray);
1457  json_object_set_new(answer, "message",
1458  json_string("internal error at json object creation"));
1459  return TM_ECODE_FAILED;
1460  }
1461 
1462  for (i = 0; i < use; i++) {
1463  json_t *bitobject = json_object();
1464  if (bitobject == NULL)
1465  continue;
1466  uint32_t expire = 0;
1467  if ((uint32_t)SCTIME_SECS(ts) < bits[i].expire)
1468  expire = bits[i].expire - (uint32_t)SCTIME_SECS(ts);
1469 
1470  const char *name = VarNameStoreLookupById(bits[i].id, VAR_TYPE_HOST_BIT);
1471  if (name == NULL)
1472  continue;
1473  json_object_set_new(bitobject, "name", json_string(name));
1474  SCLogDebug("xbit %s expire %u", name, expire);
1475  json_object_set_new(bitobject, "expire", json_integer(expire));
1476  json_array_append_new(jarray, bitobject);
1477  }
1478 
1479  json_object_set_new(jdata, "count", json_integer(i));
1480  json_object_set_new(jdata, "hostbits", jarray);
1481  json_object_set_new(answer, "message", jdata);
1482  return TM_ECODE_OK;
1483 }
1484 
1485 static void MemcapBuildValue(uint64_t val, char *str, uint32_t str_len)
1486 {
1487  if ((val / (1024 * 1024 * 1024)) != 0) {
1488  snprintf(str, str_len, "%"PRIu64"gb", val / (1024*1024*1024));
1489  } else if ((val / (1024 * 1024)) != 0) {
1490  snprintf(str, str_len, "%"PRIu64"mb", val / (1024*1024));
1491  } else {
1492  snprintf(str, str_len, "%"PRIu64"kb", val / (1024));
1493  }
1494 }
1495 
1496 TmEcode UnixSocketSetMemcap(json_t *cmd, json_t* answer, void *data)
1497 {
1498  char *memcap = NULL;
1499  char *value_str = NULL;
1500  uint64_t value;
1501 
1502  json_t *jarg = json_object_get(cmd, "config");
1503  if (!json_is_string(jarg)) {
1504  json_object_set_new(answer, "message", json_string("memcap key is not a string"));
1505  return TM_ECODE_FAILED;
1506  }
1507  memcap = (char *)json_string_value(jarg);
1508 
1509  jarg = json_object_get(cmd, "memcap");
1510  if (!json_is_string(jarg)) {
1511  json_object_set_new(answer, "message", json_string("memcap value is not a string"));
1512  return TM_ECODE_FAILED;
1513  }
1514  value_str = (char *)json_string_value(jarg);
1515 
1516  if (ParseSizeStringU64(value_str, &value) < 0) {
1517  SCLogError("Error parsing "
1518  "memcap from unix socket: %s",
1519  value_str);
1520  json_object_set_new(answer, "message",
1521  json_string("error parsing memcap specified, "
1522  "value not changed"));
1523  return TM_ECODE_FAILED;
1524  }
1525 
1526  for (size_t i = 0; i < ARRAY_SIZE(memcaps); i++) {
1527  if (strcmp(memcaps[i].name, memcap) == 0 && memcaps[i].SetFunc) {
1528  int updated = memcaps[i].SetFunc(value);
1529  char message[150];
1530 
1531  if (updated) {
1532  snprintf(message, sizeof(message),
1533  "memcap value for '%s' updated: %"PRIu64" %s",
1534  memcaps[i].name, value,
1535  (value == 0) ? "(unlimited)" : "");
1536  json_object_set_new(answer, "message", json_string(message));
1537  return TM_ECODE_OK;
1538  } else {
1539  if (value == 0) {
1540  snprintf(message, sizeof(message),
1541  "Unlimited value is not allowed for '%s'", memcaps[i].name);
1542  } else {
1543  if (memcaps[i].GetMemuseFunc()) {
1544  char memuse[50];
1545  MemcapBuildValue(memcaps[i].GetMemuseFunc(), memuse, sizeof(memuse));
1546  snprintf(message, sizeof(message),
1547  "memcap value specified for '%s' is less than the memory in use: %s",
1548  memcaps[i].name, memuse);
1549  } else {
1550  snprintf(message, sizeof(message),
1551  "memcap value specified for '%s' is less than the memory in use",
1552  memcaps[i].name);
1553  }
1554  }
1555  json_object_set_new(answer, "message", json_string(message));
1556  return TM_ECODE_FAILED;
1557  }
1558  }
1559  }
1560 
1561  json_object_set_new(answer, "message",
1562  json_string("Memcap value not found. Use 'memcap-list' to show all"));
1563  return TM_ECODE_FAILED;
1564 }
1565 
1566 TmEcode UnixSocketShowMemcap(json_t *cmd, json_t *answer, void *data)
1567 {
1568  char *memcap = NULL;
1569 
1570  json_t *jarg = json_object_get(cmd, "config");
1571  if (!json_is_string(jarg)) {
1572  json_object_set_new(answer, "message", json_string("memcap name is not a string"));
1573  return TM_ECODE_FAILED;
1574  }
1575  memcap = (char *)json_string_value(jarg);
1576 
1577  for (size_t i = 0; i < ARRAY_SIZE(memcaps); i++) {
1578  if (strcmp(memcaps[i].name, memcap) == 0 && memcaps[i].GetFunc) {
1579  char str[50];
1580  uint64_t val = memcaps[i].GetFunc();
1581  json_t *jobj = json_object();
1582  if (jobj == NULL) {
1583  json_object_set_new(answer, "message",
1584  json_string("internal error at json object creation"));
1585  return TM_ECODE_FAILED;
1586  }
1587 
1588  if (val == 0) {
1589  strlcpy(str, "unlimited", sizeof(str));
1590  } else {
1591  MemcapBuildValue(val, str, sizeof(str));
1592  }
1593 
1594  json_object_set_new(jobj, "value", json_string(str));
1595  json_object_set_new(answer, "message", jobj);
1596  return TM_ECODE_OK;
1597  }
1598  }
1599 
1600  json_object_set_new(answer, "message",
1601  json_string("Memcap value not found. Use 'memcap-list' to show all"));
1602  return TM_ECODE_FAILED;
1603 }
1604 
1605 TmEcode UnixSocketShowAllMemcap(json_t *cmd, json_t *answer, void *data)
1606 {
1607  json_t *jmemcaps = json_array();
1608 
1609  if (jmemcaps == NULL) {
1610  json_object_set_new(answer, "message",
1611  json_string("internal error at json array creation"));
1612  return TM_ECODE_FAILED;
1613  }
1614 
1615  for (size_t i = 0; i < ARRAY_SIZE(memcaps); i++) {
1616  json_t *jobj = json_object();
1617  if (jobj == NULL) {
1618  json_decref(jmemcaps);
1619  json_object_set_new(answer, "message",
1620  json_string("internal error at json object creation"));
1621  return TM_ECODE_FAILED;
1622  }
1623  char str[50];
1624  uint64_t val = memcaps[i].GetFunc();
1625 
1626  if (val == 0) {
1627  strlcpy(str, "unlimited", sizeof(str));
1628  } else {
1629  MemcapBuildValue(val, str, sizeof(str));
1630  }
1631 
1632  json_object_set_new(jobj, "name", json_string(memcaps[i].name));
1633  json_object_set_new(jobj, "value", json_string(str));
1634  json_array_append_new(jmemcaps, jobj);
1635  }
1636 
1637  json_object_set_new(answer, "message", jmemcaps);
1639 }
1640 
1641 TmEcode UnixSocketGetFlowStatsById(json_t *cmd, json_t *answer, void *data)
1642 {
1643  /* Input: we need the IP tuple including VLAN/tenant and the flow ID */
1644  json_t *jarg = json_object_get(cmd, "flow_id");
1645  if (!json_is_integer(jarg)) {
1646  SCLogInfo("error: command is not a string");
1647  json_object_set_new(answer, "message", json_string("flow_id is not an integer"));
1648  return TM_ECODE_FAILED;
1649  }
1650  int64_t flow_id = json_integer_value(jarg);
1651 
1652  Flow *f = FlowGetExistingFlowFromFlowId(flow_id);
1653  if (f == NULL) {
1654  json_object_set_new(answer, "message", json_string("Not found"));
1656  }
1657  uint32_t tosrcpktcnt = f->tosrcpktcnt;
1658  uint32_t todstpktcnt = f->todstpktcnt;
1659  uint64_t tosrcbytecnt = f->tosrcbytecnt;
1660  uint64_t todstbytecnt = f->todstbytecnt;
1661  uint64_t age = SCTIME_SECS(f->lastts) - SCTIME_SECS(f->startts);
1662  FLOWLOCK_UNLOCK(f);
1663 
1664  json_t *flow_info = json_object();
1665  if (flow_info == NULL) {
1667  }
1668  json_object_set_new(flow_info, "pkts_toclient", json_integer(tosrcpktcnt));
1669  json_object_set_new(flow_info, "pkts_toserver", json_integer(todstpktcnt));
1670  json_object_set_new(flow_info, "bytes_toclient", json_integer(tosrcbytecnt));
1671  json_object_set_new(flow_info, "bytes_toserver", json_integer(todstbytecnt));
1672  json_object_set_new(flow_info, "age", json_integer(age));
1673  json_object_set_new(answer, "message", flow_info);
1675 }
1676 #endif /* BUILD_UNIX_SOCKET */
1677 
1678 #ifdef BUILD_UNIX_SOCKET
1679 /**
1680  * \brief Single thread version of the Pcap file processing.
1681  */
1682 static int RunModeUnixSocketMaster(void)
1683 {
1684  if (UnixManagerInit() != 0)
1685  return 1;
1686 
1687  PcapCommand *pcapcmd = SCMalloc(sizeof(PcapCommand));
1688  if (unlikely(pcapcmd == NULL)) {
1689  SCLogError("Can not allocate pcap command");
1690  return 1;
1691  }
1692  TAILQ_INIT(&pcapcmd->files);
1693  pcapcmd->running = 0;
1694  pcapcmd->current_file = NULL;
1695 
1696  memset(&unix_manager_pcap_last_processed, 0, sizeof(struct timespec));
1697 
1698  SCCtrlMutexInit(&unix_manager_pcap_last_processed_mutex, NULL);
1699 
1700  UnixManagerRegisterCommand("pcap-file", UnixSocketAddPcapFile, pcapcmd, UNIX_CMD_TAKE_ARGS);
1701  UnixManagerRegisterCommand("pcap-file-continuous", UnixSocketAddPcapFileContinuous, pcapcmd, UNIX_CMD_TAKE_ARGS);
1702  UnixManagerRegisterCommand("pcap-file-number", UnixSocketPcapFilesNumber, pcapcmd, 0);
1703  UnixManagerRegisterCommand("pcap-file-list", UnixSocketPcapFilesList, pcapcmd, 0);
1704  UnixManagerRegisterCommand("pcap-last-processed", UnixSocketPcapLastProcessed, pcapcmd, 0);
1705  UnixManagerRegisterCommand("pcap-interrupt", UnixSocketPcapInterrupt, pcapcmd, 0);
1706  UnixManagerRegisterCommand("pcap-current", UnixSocketPcapCurrent, pcapcmd, 0);
1707 
1708  UnixManagerRegisterBackgroundTask(UnixSocketPcapFilesCheck, pcapcmd);
1709 
1712 
1713  return 0;
1714 }
1715 #endif
1716 
1718 {
1720 }
1721 
1722 
1723 
1724 
host.h
tm-threads.h
HostBitList
int HostBitList(Host *h, XBit **iter)
Definition: host-bit.c:184
ts
uint64_t ts
Definition: source-erf-file.c:55
XBit_::expire
uint32_t expire
Definition: util-var.h:62
ippair.h
THashCleanup
void THashCleanup(THashTableContext *ctx)
Cleanup the thash engine.
Definition: util-thash.c:489
app-layer-htp-range.h
detect-engine.h
DetectEngineMTApply
int DetectEngineMTApply(void)
Definition: detect-engine.c:4884
RUNMODE_UNIX_SOCKET
@ RUNMODE_UNIX_SOCKET
Definition: runmodes.h:41
MemcapCommand_::GetFunc
uint64_t(* GetFunc)(void)
Definition: runmode-unix-socket.c:82
PcapFiles_::continuous
bool continuous
Definition: runmode-unix-socket.c:68
DetectEngineDeReference
void DetectEngineDeReference(DetectEngineCtx **de_ctx)
Definition: detect-engine.c:4613
PcapFiles_::should_delete
bool should_delete
Definition: runmode-unix-socket.c:69
TAILQ_INIT
#define TAILQ_INIT(head)
Definition: queue.h:262
TmThreadContinueThreads
void TmThreadContinueThreads(void)
Unpauses all threads present in tv_root.
Definition: tm-threads.c:1908
Flow_::startts
SCTime_t startts
Definition: flow.h:495
stream-tcp.h
DetectEnginePruneFreeList
void DetectEnginePruneFreeList(void)
Definition: detect-engine.c:4707
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:190
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
TM_ECODE_DONE
@ TM_ECODE_DONE
Definition: tm-threads-common.h:82
RunModeDispatch
void RunModeDispatch(int runmode, const char *custom_mode, const char *capture_plugin_name, const char *capture_plugin_args)
Definition: runmodes.c:390
Dataset::hash
THashTableContext * hash
Definition: datasets.h:46
Flow_
Flow data structure.
Definition: flow.h:356
HostRelease
void HostRelease(Host *h)
Definition: host.c:461
DetectEngineReloadTenantBlocking
int DetectEngineReloadTenantBlocking(uint32_t tenant_id, const char *yaml, int reload_cnt)
Reload a tenant and wait for loading to complete.
Definition: detect-engine.c:4125
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:843
ConfYamlLoadFileWithPrefix
int ConfYamlLoadFileWithPrefix(const char *filename, const char *prefix)
Load configuration from a YAML file, insert in tree at 'prefix'.
Definition: conf-yaml-loader.c:554
HostGetHostFromHash
Host * HostGetHostFromHash(Address *a)
Definition: host.c:486
flow-hash.h
UnixManagerThreadSpawn
void UnixManagerThreadSpawn(int mode)
Definition: unix-manager.c:1274
HostSetMemcap
int HostSetMemcap(uint64_t size)
Update memcap value.
Definition: host.c:68
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:248
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
FTPMemuseGlobalCounter
uint64_t FTPMemuseGlobalCounter(void)
Definition: app-layer-ftp.c:165
PcapCommand_
Definition: runmode-unix-socket.c:73
MemcapCommand_::GetMemuseFunc
uint64_t(* GetMemuseFunc)(void)
Definition: runmode-unix-socket.c:83
util-var-name.h
FlowGetMemuse
uint64_t FlowGetMemuse(void)
Definition: flow.c:126
FlowGetMemcap
uint64_t FlowGetMemcap(void)
Return memcap value.
Definition: flow.c:120
ConfSetFinal
int ConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:303
Address_
Definition: decode.h:108
PreRunInit
void PreRunInit(const int runmode)
Definition: suricata.c:2212
stream-tcp-reassemble.h
DetectEngineReloadTenantsBlocking
int DetectEngineReloadTenantsBlocking(const int reload_cnt)
Reload all tenants and wait for loading to complete.
Definition: detect-engine.c:4139
unix_socket_mode_is_running
int unix_socket_mode_is_running
Definition: runmode-unix-socket.c:60
TAILQ_INSERT_TAIL
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:294
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:81
DefragTrackerGetMemuse
uint64_t DefragTrackerGetMemuse(void)
Return memuse value.
Definition: defrag-hash.c:74
PacketPoolPostRunmodes
void PacketPoolPostRunmodes(void)
Set the max_pending_return_packets value.
Definition: tmqh-packetpool.c:459
app-layer-ftp.h
MAX
#define MAX(x, y)
Definition: suricata-common.h:395
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
MemcapCommand_::SetFunc
int(* SetFunc)(uint64_t)
Definition: runmode-unix-socket.c:81
runmode-unix-socket.h
SCJsonString
json_t * SCJsonString(const char *val)
Definition: output-json.c:96
HTPSetMemcap
int HTPSetMemcap(uint64_t size)
Update memcap value.
Definition: app-layer-htp-mem.c:113
DatasetLookupSerialized
int DatasetLookupSerialized(Dataset *set, const char *string)
add serialized data to set
Definition: datasets.c:1671
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:273
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
HostGetMemcap
uint64_t HostGetMemcap(void)
Return memcap value.
Definition: host.c:83
MemcapCommand_::name
const char * name
Definition: runmode-unix-socket.c:80
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
TAILQ_ENTRY
#define TAILQ_ENTRY(type)
Definition: queue.h:239
RunModeUnixSocketGetDefaultMode
const char * RunModeUnixSocketGetDefaultMode(void)
Definition: runmode-unix-socket.c:86
Flow_::tosrcbytecnt
uint64_t tosrcbytecnt
Definition: flow.h:500
DetectEngineMultiTenantEnabled
int DetectEngineMultiTenantEnabled(void)
Definition: detect-engine.c:3854
HTPByteRangeSetMemcap
int HTPByteRangeSetMemcap(uint64_t size)
Definition: app-layer-htp-range.c:45
datasets.h
VarNameStoreLookupByName
uint32_t VarNameStoreLookupByName(const char *name, const enum VarTypes type)
find name for id+type at packet time.
Definition: util-var-name.c:315
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:312
PreRunPostPrivsDropInit
void PreRunPostPrivsDropInit(const int runmode)
Definition: suricata.c:2241
util-debug.h
DetectEngineMoveToFreeList
int DetectEngineMoveToFreeList(DetectEngineCtx *de_ctx)
Definition: detect-engine.c:4697
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:250
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
TmThreadWaitOnThreadInit
TmEcode TmThreadWaitOnThreadInit(void)
Used to check if all threads have finished their initialization. On finding an un-initialized thread,...
Definition: tm-threads.c:1947
HTPGetMemcap
uint64_t HTPGetMemcap(void)
Update memcap value.
Definition: app-layer-htp-mem.c:127
util-cpu.h
Flow_::todstpktcnt
uint32_t todstpktcnt
Definition: flow.h:497
output-json.h
RunModeRegisterNewRunMode
void RunModeRegisterNewRunMode(enum RunModes runmode, const char *name, const char *description, int(*RunModeFunc)(void), int(*RunModeIsIPSEnabled)(void))
Registers a new runmode.
Definition: runmodes.c:465
HostBitUnset
void HostBitUnset(Host *h, uint32_t idx)
Definition: host-bit.c:139
HTPByteRangeMemuseGlobalCounter
uint64_t HTPByteRangeMemuseGlobalCounter(void)
Definition: app-layer-htp-range.c:61
SCTimespecAsEpochMillis
uint64_t SCTimespecAsEpochMillis(const struct timespec *ts)
Definition: util-time.c:639
Flow_::lastts
SCTime_t lastts
Definition: flow.h:415
DATASET_TYPE_NOTSET
#define DATASET_TYPE_NOTSET
Definition: datasets.h:31
IPPairGetMemcap
uint64_t IPPairGetMemcap(void)
Return memcap value.
Definition: ippair.c:81
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
util-affinity.h
MemcapsGetPressure
float MemcapsGetPressure(void)
Definition: runmode-unix-socket.c:110
util-time.h
source-pcap-file-directory-helper.h
RunModeUnixSocketIsActive
int RunModeUnixSocketIsActive(void)
Definition: runmode-unix-socket.c:1717
HostGetMemuse
uint64_t HostGetMemuse(void)
Return memuse value.
Definition: host.c:94
DefragTrackerGetMemcap
uint64_t DefragTrackerGetMemcap(void)
Return memcap value.
Definition: defrag-hash.c:63
Flow_::todstbytecnt
uint64_t todstbytecnt
Definition: flow.h:499
util-profiling.h
HostBitSet
void HostBitSet(Host *h, uint32_t idx, uint32_t expire)
Definition: host-bit.c:131
DetectEngineLoadTenantBlocking
int DetectEngineLoadTenantBlocking(uint32_t tenant_id, const char *yaml)
Load a tenant and wait for loading to complete.
Definition: detect-engine.c:4111
SCCtrlMutexLock
#define SCCtrlMutexLock(mut)
Definition: threads-debug.h:376
type
uint16_t type
Definition: decode-vlan.c:107
conf-yaml-loader.h
TimeGet
SCTime_t TimeGet(void)
Definition: util-time.c:152
PcapFiles_
Definition: runmode-unix-socket.c:62
FlowGetExistingFlowFromFlowId
Flow * FlowGetExistingFlowFromFlowId(int64_t flow_id)
Look for existing Flow using a flow id value.
Definition: flow-hash.c:992
DatasetsSave
void DatasetsSave(void)
Definition: datasets.c:1068
conf.h
PcapCommand
struct PcapCommand_ PcapCommand
UNIX_CMD_TAKE_ARGS
#define UNIX_CMD_TAKE_ARGS
Definition: unix-manager.h:29
SCTime_t
Definition: util-time.h:40
runmode-pcap-file.h
TmEcode
TmEcode
Definition: tm-threads-common.h:79
flow-timeout.h
DatasetRemoveSerialized
int DatasetRemoveSerialized(Dataset *set, const char *string)
remove serialized data from set
Definition: datasets.c:1749
defrag.h
FTPMemcapGlobalCounter
uint64_t FTPMemcapGlobalCounter(void)
Definition: app-layer-ftp.c:171
runmodes.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
PcapFiles_::poll_interval
time_t poll_interval
Definition: runmode-unix-socket.c:67
ARRAY_SIZE
#define ARRAY_SIZE(arr)
Definition: suricata-common.h:545
DatasetTypes
DatasetTypes
Definition: datasets.h:30
SCCtrlMutexUnlock
#define SCCtrlMutexUnlock(mut)
Definition: threads-debug.h:378
StreamTcpSetMemcap
int StreamTcpSetMemcap(uint64_t size)
Update memcap value.
Definition: stream-tcp.c:279
RunModeUnixSocketRegister
void RunModeUnixSocketRegister(void)
Definition: runmode-unix-socket.c:557
flow-manager.h
suricata-common.h
VarNameStoreLookupById
const char * VarNameStoreLookupById(const uint32_t id, const enum VarTypes type)
find name for id+type at packet time.
Definition: util-var-name.c:298
SCCtrlMutex
#define SCCtrlMutex
Definition: threads-debug.h:373
util-path.h
UnixManagerInit
int UnixManagerInit(void)
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
IPPairGetMemuse
uint64_t IPPairGetMemuse(void)
Return memuse value.
Definition: ippair.c:92
MemcapCommand
struct MemcapCommand_ MemcapCommand
DetectEngineTenantRegisterPcapFile
int DetectEngineTenantRegisterPcapFile(uint32_t tenant_id)
Definition: detect-engine.c:4570
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
VAR_TYPE_HOST_BIT
@ VAR_TYPE_HOST_BIT
Definition: util-var.h:40
DefragTrackerSetMemcap
int DefragTrackerSetMemcap(uint64_t size)
Update memcap value.
Definition: defrag-hash.c:48
DatasetFind
Dataset * DatasetFind(const char *name, enum DatasetTypes type)
look for set by name without creating it
Definition: datasets.c:616
PcapFiles
struct PcapFiles_ PcapFiles
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
FTPSetMemcap
int FTPSetMemcap(uint64_t size)
Definition: app-layer-ftp.c:177
unix-manager.h
str
#define str(s)
Definition: suricata-common.h:291
DatasetGetTypeFromString
enum DatasetTypes DatasetGetTypeFromString(const char *s)
Definition: datasets.c:58
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
HTPByteRangeMemcapGlobalCounter
uint64_t HTPByteRangeMemcapGlobalCounter(void)
Definition: app-layer-htp-range.c:55
StreamTcpMemuseCounter
uint64_t StreamTcpMemuseCounter(void)
Definition: stream-tcp.c:254
StreamTcpReassembleMemuseGlobalCounter
uint64_t StreamTcpReassembleMemuseGlobalCounter(void)
Definition: stream-tcp-reassemble.c:148
TAILQ_HEAD
#define TAILQ_HEAD(name, type)
Definition: queue.h:230
SCCtrlMutexInit
#define SCCtrlMutexInit(mut, mutattr)
Definition: threads-debug.h:375
StreamTcpGetMemcap
uint64_t StreamTcpGetMemcap(void)
Return memcap value.
Definition: stream-tcp.c:294
PcapFiles_::delay
time_t delay
Definition: runmode-unix-socket.c:66
UnixSocketPcapFile
TmEcode UnixSocketPcapFile(TmEcode tm, struct timespec *last_processed)
Definition: runmode-unix-socket.c:568
app-layer-htp-mem.h
PcapFiles_::output_dir
char * output_dir
Definition: runmode-unix-socket.c:64
HostLookupHostFromHash
Host * HostLookupHostFromHash(Address *a)
look up a host in the hash
Definition: host.c:585
IPPairSetMemcap
int IPPairSetMemcap(uint64_t size)
Update memcap value.
Definition: ippair.c:66
defrag-hash.h
StreamTcpReassembleGetMemcap
uint64_t StreamTcpReassembleGetMemcap(void)
Return memcap value.
Definition: stream-tcp-reassemble.c:198
Address_::family
char family
Definition: decode.h:109
PostRunDeinit
void PostRunDeinit(const int runmode, struct timeval *start_time)
Definition: suricata.c:2263
XBit_::idx
uint32_t idx
Definition: util-var.h:60
DatasetAddSerialized
int DatasetAddSerialized(Dataset *set, const char *string)
add serialized data to set
Definition: datasets.c:1659
MemcapCommand_
Definition: runmode-unix-socket.c:79
XBit_
Definition: util-var.h:57
Dataset
Definition: datasets.h:40
SCStatFn
#define SCStatFn(pathname, statbuf)
Definition: util-path.h:35
util-misc.h
PcapFiles_::tenant_id
uint32_t tenant_id
Definition: runmode-unix-socket.c:65
StreamTcpReassembleSetMemcap
int StreamTcpReassembleSetMemcap(uint64_t size)
Update memcap value.
Definition: stream-tcp-reassemble.c:183
DetectEngineTenantRegisterVlanId
int DetectEngineTenantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id)
Definition: detect-engine.c:4560
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:237
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
Host_
Definition: host.h:58
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
DetectEngineTenantUnregisterPcapFile
int DetectEngineTenantUnregisterPcapFile(uint32_t tenant_id)
Definition: detect-engine.c:4576
RUNMODE_PCAP_FILE
@ RUNMODE_PCAP_FILE
Definition: runmodes.h:30
DetectEngineGetByTenantId
DetectEngineCtx * DetectEngineGetByTenantId(uint32_t tenant_id)
Definition: detect-engine.c:4587
DetectEngineTenantUnregisterVlanId
int DetectEngineTenantUnregisterVlanId(uint32_t tenant_id, uint16_t vlan_id)
Definition: detect-engine.c:4565
SCStat
struct stat SCStat
Definition: util-path.h:33
Flow_::tosrcpktcnt
uint32_t tosrcpktcnt
Definition: flow.h:498
output.h
host-bit.h
app-layer.h
PcapFiles_::filename
char * filename
Definition: runmode-unix-socket.c:63
FlowSetMemcap
int FlowSetMemcap(uint64_t size)
Update memcap value.
Definition: flow.c:105