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