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