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