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