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 
970  json_object_set_new(answer, "message", json_string("handler added"));
971  return TM_ECODE_OK;
972 }
973 
974 /**
975  * \brief Command to remove a tenant handler
976  *
977  * \param cmd the content of command Arguments as a json_t object
978  * \param answer the json_t object that has to be used to answer
979  * \param data pointer to data defining the context here a PcapCommand::
980  */
981 TmEcode UnixSocketUnregisterTenantHandler(json_t *cmd, json_t* answer, void *data)
982 {
983  const char *htype;
984  json_int_t traffic_id = -1;
985 
987  SCLogInfo("error: multi-tenant support not enabled");
988  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
989  return TM_ECODE_FAILED;
990  }
991 
992  /* 1 get tenant id */
993  json_t *jarg = json_object_get(cmd, "id");
994  if (!json_is_integer(jarg)) {
995  SCLogInfo("error: command is not a string");
996  json_object_set_new(answer, "message", json_string("id is not an integer"));
997  return TM_ECODE_FAILED;
998  }
999  uint32_t tenant_id;
1000  if (!JsonU32Value(jarg, &tenant_id)) {
1001  SCLogInfo("tenant_id is not a uint32");
1002  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
1003  return TM_ECODE_FAILED;
1004  }
1005 
1006  /* 2 get tenant handler type */
1007  jarg = json_object_get(cmd, "htype");
1008  if (!json_is_string(jarg)) {
1009  SCLogInfo("error: command is not a string");
1010  json_object_set_new(answer, "message", json_string("command is not a string"));
1011  return TM_ECODE_FAILED;
1012  }
1013  htype = json_string_value(jarg);
1014 
1015  SCLogDebug("add-tenant-handler: %d %s", tenant_id, htype);
1016 
1017  /* 3 get optional hargs */
1018  json_t *hargs = json_object_get(cmd, "hargs");
1019  if (hargs != NULL) {
1020  if (!json_is_integer(hargs)) {
1021  SCLogInfo("error: hargs not a number");
1022  json_object_set_new(answer, "message", json_string("hargs not a number"));
1023  return TM_ECODE_FAILED;
1024  }
1025  traffic_id = json_integer_value(hargs);
1026  }
1027 
1028  /* 4 add to system */
1029  int r = -1;
1030  if (strcmp(htype, "pcap") == 0) {
1031  r = DetectEngineTenantUnregisterPcapFile(tenant_id);
1032  } else if (strcmp(htype, "vlan") == 0) {
1033  if (traffic_id < 0) {
1034  json_object_set_new(answer, "message", json_string("vlan requires argument"));
1035  return TM_ECODE_FAILED;
1036  }
1037  if (traffic_id > USHRT_MAX) {
1038  json_object_set_new(answer, "message", json_string("vlan argument out of range"));
1039  return TM_ECODE_FAILED;
1040  }
1041 
1042  SCLogInfo("VLAN handler: removing mapping of %u to tenant %u", (uint32_t)traffic_id, tenant_id);
1043  r = DetectEngineTenantUnregisterVlanId(tenant_id, (uint16_t)traffic_id);
1044  }
1045  if (r != 0) {
1046  json_object_set_new(answer, "message", json_string("handler unregister failure"));
1047  return TM_ECODE_FAILED;
1048  }
1049 
1050  /* 5 apply it */
1051  if (DetectEngineMTApply() < 0) {
1052  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1053  // TODO cleanup
1054  return TM_ECODE_FAILED;
1055  }
1056 
1057  json_object_set_new(answer, "message", json_string("handler removed"));
1058  return TM_ECODE_OK;
1059 }
1060 
1061 /**
1062  * \brief Command to add a tenant
1063  *
1064  * \param cmd the content of command Arguments as a json_t object
1065  * \param answer the json_t object that has to be used to answer
1066  * \param data pointer to data defining the context here a PcapCommand::
1067  */
1068 TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data)
1069 {
1070  const char *filename;
1071  SCStat st;
1072 
1073  if (!(DetectEngineMultiTenantEnabled())) {
1074  SCLogInfo("error: multi-tenant support not enabled");
1075  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1076  return TM_ECODE_FAILED;
1077  }
1078 
1079  /* 1 get tenant id */
1080  json_t *jarg = json_object_get(cmd, "id");
1081  if (!json_is_integer(jarg)) {
1082  json_object_set_new(answer, "message", json_string("id is not an integer"));
1083  return TM_ECODE_FAILED;
1084  }
1085  uint32_t tenant_id;
1086  if (!JsonU32Value(jarg, &tenant_id)) {
1087  SCLogInfo("tenant_id is not a uint32");
1088  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
1089  return TM_ECODE_FAILED;
1090  }
1091 
1092  /* 2 get tenant yaml */
1093  jarg = json_object_get(cmd, "filename");
1094  if (!json_is_string(jarg)) {
1095  json_object_set_new(answer, "message", json_string("command is not a string"));
1096  return TM_ECODE_FAILED;
1097  }
1098  filename = json_string_value(jarg);
1099  if (SCStatFn(filename, &st) != 0) {
1100  json_object_set_new(answer, "message", json_string("file does not exist"));
1101  return TM_ECODE_FAILED;
1102  }
1103 
1104  SCLogDebug("add-tenant: %d %s", tenant_id, filename);
1105 
1106  /* setup the yaml in this loop so that it's not done by the loader
1107  * threads. SCConfYamlLoadFileWithPrefix is not thread safe. */
1108  char prefix[64];
1109  snprintf(prefix, sizeof(prefix), "multi-detect.%u", tenant_id);
1110  if (SCConfYamlLoadFileWithPrefix(filename, prefix) != 0) {
1111  SCLogError("failed to load yaml %s", filename);
1112  json_object_set_new(answer, "message", json_string("failed to load yaml"));
1113  return TM_ECODE_FAILED;
1114  }
1115 
1116  /* 3 load into the system */
1117  if (DetectEngineLoadTenantBlocking(tenant_id, filename) != 0) {
1118  json_object_set_new(answer, "message", json_string("adding tenant failed"));
1119  return TM_ECODE_FAILED;
1120  }
1121 
1122  /* 4 apply to the running system */
1123  if (DetectEngineMTApply() < 0) {
1124  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1125  // TODO cleanup
1126  return TM_ECODE_FAILED;
1127  }
1128 
1129  json_object_set_new(answer, "message", json_string("adding tenant succeeded"));
1130  return TM_ECODE_OK;
1131 }
1132 
1133 static int reload_cnt = 1;
1134 /**
1135  * \brief Command to reload a tenant
1136  *
1137  * \param cmd the content of command Arguments as a json_t object
1138  * \param answer the json_t object that has to be used to answer
1139  * \param data pointer to data defining the context here a PcapCommand::
1140  */
1141 TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data)
1142 {
1143  const char *filename = NULL;
1144  SCStat st;
1145 
1146  if (!(DetectEngineMultiTenantEnabled())) {
1147  SCLogInfo("error: multi-tenant support not enabled");
1148  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1149  return TM_ECODE_FAILED;
1150  }
1151 
1152  /* 1 get tenant id */
1153  json_t *jarg = json_object_get(cmd, "id");
1154  if (!json_is_integer(jarg)) {
1155  json_object_set_new(answer, "message", json_string("id is not an integer"));
1156  return TM_ECODE_FAILED;
1157  }
1158  uint32_t tenant_id;
1159  if (!JsonU32Value(jarg, &tenant_id)) {
1160  SCLogInfo("tenant_id is not a uint32");
1161  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
1162  return TM_ECODE_FAILED;
1163  }
1164 
1165  /* 2 get tenant yaml */
1166  jarg = json_object_get(cmd, "filename");
1167  if (jarg) {
1168  if (!json_is_string(jarg)) {
1169  json_object_set_new(answer, "message", json_string("command is not a string"));
1170  return TM_ECODE_FAILED;
1171  }
1172  filename = json_string_value(jarg);
1173  if (SCStatFn(filename, &st) != 0) {
1174  json_object_set_new(answer, "message", json_string("file does not exist"));
1175  return TM_ECODE_FAILED;
1176  }
1177  }
1178 
1179  SCLogDebug("reload-tenant: %d %s", tenant_id, filename);
1180 
1181  /* 3 load into the system */
1182  if (DetectEngineReloadTenantBlocking(tenant_id, filename, reload_cnt) != 0) {
1183  json_object_set_new(answer, "message", json_string("reload tenant failed"));
1184  return TM_ECODE_FAILED;
1185  }
1186 
1187  reload_cnt++;
1188 
1189  /* apply to the running system */
1190  if (DetectEngineMTApply() < 0) {
1191  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1192  // TODO cleanup
1193  return TM_ECODE_FAILED;
1194  }
1195 
1196  json_object_set_new(answer, "message", json_string("reloading tenant succeeded"));
1197  return TM_ECODE_OK;
1198 }
1199 
1200 /**
1201  * \brief Command to reload all tenants
1202  *
1203  * \param cmd the content of command Arguments as a json_t object
1204  * \param answer the json_t object that has to be used to answer
1205  * \param data pointer to data defining the context here a PcapCommand::
1206  */
1207 TmEcode UnixSocketReloadTenants(json_t *cmd, json_t *answer, void *data)
1208 {
1209  if (!(DetectEngineMultiTenantEnabled())) {
1210  SCLogInfo("error: multi-tenant support not enabled");
1211  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1212  return TM_ECODE_FAILED;
1213  }
1214 
1215  if (DetectEngineReloadTenantsBlocking(reload_cnt) != 0) {
1216  json_object_set_new(answer, "message", json_string("reload tenants failed"));
1217  return TM_ECODE_FAILED;
1218  }
1219 
1220  reload_cnt++;
1221 
1222  /* apply to the running system */
1223  if (DetectEngineMTApply() < 0) {
1224  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1225  // TODO cleanup
1226  return TM_ECODE_FAILED;
1227  }
1228 
1229  SCLogNotice("reload-tenants complete");
1230 
1231  json_object_set_new(answer, "message", json_string("reloading tenants succeeded"));
1232  return TM_ECODE_OK;
1233 }
1234 
1235 /**
1236  * \brief Command to remove a tenant
1237  *
1238  * \param cmd the content of command Arguments as a json_t object
1239  * \param answer the json_t object that has to be used to answer
1240  * \param data pointer to data defining the context here a PcapCommand::
1241  */
1242 TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data)
1243 {
1244  if (!(DetectEngineMultiTenantEnabled())) {
1245  SCLogInfo("error: multi-tenant support not enabled");
1246  json_object_set_new(answer, "message", json_string("multi-tenant support not enabled"));
1247  return TM_ECODE_FAILED;
1248  }
1249 
1250  /* 1 get tenant id */
1251  json_t *jarg = json_object_get(cmd, "id");
1252  if (!json_is_integer(jarg)) {
1253  SCLogInfo("error: command is not a string");
1254  json_object_set_new(answer, "message", json_string("id is not an integer"));
1255  return TM_ECODE_FAILED;
1256  }
1257  uint32_t tenant_id;
1258  if (!JsonU32Value(jarg, &tenant_id)) {
1259  SCLogInfo("tenant_id is not a uint32");
1260  json_object_set_new(answer, "message", json_string("tenant_id is not a uint32"));
1261  return TM_ECODE_FAILED;
1262  }
1263 
1264  SCLogInfo("remove-tenant: removing tenant %d", tenant_id);
1265 
1266  /* 2 remove it from the system */
1267  char prefix[64];
1268  snprintf(prefix, sizeof(prefix), "multi-detect.%u", tenant_id);
1269 
1271  if (de_ctx == NULL) {
1272  json_object_set_new(answer, "message", json_string("tenant detect engine not found"));
1273  return TM_ECODE_FAILED;
1274  }
1275 
1276  /* move to free list */
1279 
1280  /* update the threads */
1281  if (DetectEngineMTApply() < 0) {
1282  json_object_set_new(answer, "message", json_string("couldn't apply settings"));
1283  // TODO cleanup
1284  return TM_ECODE_FAILED;
1285  }
1286 
1287  /* walk free list, freeing the removed de_ctx */
1289 
1290  json_object_set_new(answer, "message", json_string("removing tenant succeeded"));
1291  return TM_ECODE_OK;
1292 }
1293 
1294 /**
1295  * \brief Command to add a hostbit
1296  *
1297  * \param cmd the content of command Arguments as a json_t object
1298  * \param answer the json_t object that has to be used to answer
1299  */
1300 TmEcode UnixSocketHostbitAdd(json_t *cmd, json_t* answer, void *data_usused)
1301 {
1302  /* 1 get ip address */
1303  json_t *jarg = json_object_get(cmd, "ipaddress");
1304  if (!json_is_string(jarg)) {
1305  json_object_set_new(answer, "message", json_string("ipaddress is not an string"));
1306  return TM_ECODE_FAILED;
1307  }
1308  const char *ipaddress = json_string_value(jarg);
1309 
1310  Address a;
1311  struct in_addr in;
1312  memset(&in, 0, sizeof(in));
1313  if (inet_pton(AF_INET, ipaddress, &in) != 1) {
1314  uint32_t in6[4];
1315  memset(&in6, 0, sizeof(in6));
1316  if (inet_pton(AF_INET6, ipaddress, &in) != 1) {
1317  json_object_set_new(answer, "message", json_string("invalid address string"));
1318  return TM_ECODE_FAILED;
1319  } else {
1320  a.family = AF_INET6;
1321  a.addr_data32[0] = in6[0];
1322  a.addr_data32[1] = in6[1];
1323  a.addr_data32[2] = in6[2];
1324  a.addr_data32[3] = in6[3];
1325  }
1326  } else {
1327  a.family = AF_INET;
1328  a.addr_data32[0] = in.s_addr;
1329  a.addr_data32[1] = 0;
1330  a.addr_data32[2] = 0;
1331  a.addr_data32[3] = 0;
1332  }
1333 
1334  /* 2 get variable name */
1335  jarg = json_object_get(cmd, "hostbit");
1336  if (!json_is_string(jarg)) {
1337  json_object_set_new(answer, "message", json_string("hostbit is not a string"));
1338  return TM_ECODE_FAILED;
1339  }
1340  const char *hostbit = json_string_value(jarg);
1341  uint32_t idx = VarNameStoreLookupByName(hostbit, VAR_TYPE_HOST_BIT);
1342  if (idx == 0) {
1343  json_object_set_new(answer, "message", json_string("hostbit not found"));
1344  return TM_ECODE_FAILED;
1345  }
1346 
1347  /* 3 get expire */
1348  jarg = json_object_get(cmd, "expire");
1349  if (!json_is_integer(jarg)) {
1350  json_object_set_new(answer, "message", json_string("expire is not an integer"));
1351  return TM_ECODE_FAILED;
1352  }
1353  uint32_t expire;
1354  if (!JsonU32Value(jarg, &expire)) {
1355  SCLogInfo("expire is not a uint32");
1356  json_object_set_new(answer, "message", json_string("expire is not a uint32"));
1357  return TM_ECODE_FAILED;
1358  }
1359 
1360  SCLogInfo("add-hostbit: ip %s hostbit %s expire %us", ipaddress, hostbit, expire);
1361 
1362  SCTime_t current_time = TimeGet();
1363  Host *host = HostGetHostFromHash(&a);
1364  if (host) {
1365  if (SCTIME_SECS(current_time) + expire > UINT32_MAX) {
1366  json_object_set_new(answer, "message", json_string("couldn't set host expire"));
1367  HostRelease(host);
1368  return TM_ECODE_FAILED;
1369  }
1370  HostBitSet(host, idx, SCTIME_ADD_SECS(current_time, expire));
1371  HostRelease(host);
1372 
1373  json_object_set_new(answer, "message", json_string("hostbit added"));
1374  return TM_ECODE_OK;
1375  } else {
1376  json_object_set_new(answer, "message", json_string("couldn't create host"));
1377  return TM_ECODE_FAILED;
1378  }
1379 }
1380 
1381 /**
1382  * \brief Command to remove a hostbit
1383  *
1384  * \param cmd the content of command Arguments as a json_t object
1385  * \param answer the json_t object that has to be used to answer
1386  */
1387 TmEcode UnixSocketHostbitRemove(json_t *cmd, json_t* answer, void *data_unused)
1388 {
1389  /* 1 get ip address */
1390  json_t *jarg = json_object_get(cmd, "ipaddress");
1391  if (!json_is_string(jarg)) {
1392  json_object_set_new(answer, "message", json_string("ipaddress is not an string"));
1393  return TM_ECODE_FAILED;
1394  }
1395  const char *ipaddress = json_string_value(jarg);
1396 
1397  Address a;
1398  struct in_addr in;
1399  memset(&in, 0, sizeof(in));
1400  if (inet_pton(AF_INET, ipaddress, &in) != 1) {
1401  uint32_t in6[4];
1402  memset(&in6, 0, sizeof(in6));
1403  if (inet_pton(AF_INET6, ipaddress, &in) != 1) {
1404  json_object_set_new(answer, "message", json_string("invalid address string"));
1405  return TM_ECODE_FAILED;
1406  } else {
1407  a.family = AF_INET6;
1408  a.addr_data32[0] = in6[0];
1409  a.addr_data32[1] = in6[1];
1410  a.addr_data32[2] = in6[2];
1411  a.addr_data32[3] = in6[3];
1412  }
1413  } else {
1414  a.family = AF_INET;
1415  a.addr_data32[0] = in.s_addr;
1416  a.addr_data32[1] = 0;
1417  a.addr_data32[2] = 0;
1418  a.addr_data32[3] = 0;
1419  }
1420 
1421  /* 2 get variable name */
1422  jarg = json_object_get(cmd, "hostbit");
1423  if (!json_is_string(jarg)) {
1424  json_object_set_new(answer, "message", json_string("hostbit is not a string"));
1425  return TM_ECODE_FAILED;
1426  }
1427 
1428  const char *hostbit = json_string_value(jarg);
1429  uint32_t idx = VarNameStoreLookupByName(hostbit, VAR_TYPE_HOST_BIT);
1430  if (idx == 0) {
1431  json_object_set_new(answer, "message", json_string("hostbit not found"));
1432  return TM_ECODE_FAILED;
1433  }
1434 
1435  SCLogInfo("remove-hostbit: %s %s", ipaddress, hostbit);
1436 
1437  Host *host = HostLookupHostFromHash(&a);
1438  if (host) {
1439  HostBitUnset(host, idx);
1440  HostRelease(host);
1441  json_object_set_new(answer, "message", json_string("hostbit removed"));
1442  return TM_ECODE_OK;
1443  } else {
1444  json_object_set_new(answer, "message", json_string("host not found"));
1445  return TM_ECODE_FAILED;
1446  }
1447 }
1448 
1449 /**
1450  * \brief Command to list hostbits for an ip
1451  *
1452  * \param cmd the content of command Arguments as a json_t object
1453  * \param answer the json_t object that has to be used to answer
1454  *
1455  * Message looks like:
1456  * {"message": {"count": 1, "hostbits": [{"expire": 3222, "name": "firefox-users"}]}, "return": "OK"}
1457  *
1458  * \retval r TM_ECODE_OK or TM_ECODE_FAILED
1459  */
1460 TmEcode UnixSocketHostbitList(json_t *cmd, json_t* answer, void *data_unused)
1461 {
1462  /* 1 get ip address */
1463  json_t *jarg = json_object_get(cmd, "ipaddress");
1464  if (!json_is_string(jarg)) {
1465  json_object_set_new(answer, "message", json_string("ipaddress is not an string"));
1466  return TM_ECODE_FAILED;
1467  }
1468  const char *ipaddress = json_string_value(jarg);
1469 
1470  Address a;
1471  struct in_addr in;
1472  memset(&in, 0, sizeof(in));
1473  if (inet_pton(AF_INET, ipaddress, &in) != 1) {
1474  uint32_t in6[4];
1475  memset(&in6, 0, sizeof(in6));
1476  if (inet_pton(AF_INET6, ipaddress, &in) != 1) {
1477  json_object_set_new(answer, "message", json_string("invalid address string"));
1478  return TM_ECODE_FAILED;
1479  } else {
1480  a.family = AF_INET6;
1481  a.addr_data32[0] = in6[0];
1482  a.addr_data32[1] = in6[1];
1483  a.addr_data32[2] = in6[2];
1484  a.addr_data32[3] = in6[3];
1485  }
1486  } else {
1487  a.family = AF_INET;
1488  a.addr_data32[0] = in.s_addr;
1489  a.addr_data32[1] = 0;
1490  a.addr_data32[2] = 0;
1491  a.addr_data32[3] = 0;
1492  }
1493 
1494  SCLogInfo("list-hostbit: %s", ipaddress);
1495 
1496  SCTime_t ts = TimeGet();
1497 
1498  struct Bit {
1499  uint32_t id;
1500  SCTime_t expire;
1501  } bits[256];
1502  memset(&bits, 0, sizeof(bits));
1503  int i = 0, use = 0;
1504 
1505  Host *host = HostLookupHostFromHash(&a);
1506  if (!host) {
1507  json_object_set_new(answer, "message", json_string("host not found"));
1508  return TM_ECODE_FAILED;
1509  }
1510 
1511  XBit *iter = NULL;
1512  while (use < 256 && HostBitList(host, &iter) == 1) {
1513  bits[use].id = iter->idx;
1514  bits[use].expire = iter->expire;
1515  use++;
1516  }
1517  HostRelease(host);
1518 
1519  json_t *jdata = json_object();
1520  json_t *jarray = json_array();
1521  if (jarray == NULL || jdata == NULL) {
1522  if (jdata != NULL)
1523  json_decref(jdata);
1524  if (jarray != NULL)
1525  json_decref(jarray);
1526  json_object_set_new(answer, "message",
1527  json_string("internal error at json object creation"));
1528  return TM_ECODE_FAILED;
1529  }
1530 
1531  for (i = 0; i < use; i++) {
1532  json_t *bitobject = json_object();
1533  if (bitobject == NULL)
1534  continue;
1535  uint64_t expire = 0;
1536  if (SCTIME_CMP_LT(ts, bits[i].expire))
1537  expire = SCTIME_SECS(bits[i].expire) - SCTIME_SECS(ts);
1538 
1539  const char *name = VarNameStoreLookupById(bits[i].id, VAR_TYPE_HOST_BIT);
1540  if (name == NULL)
1541  continue;
1542  json_object_set_new(bitobject, "name", json_string(name));
1543  SCLogDebug("xbit %s expire %" PRIu64, name, expire);
1544  json_object_set_new(bitobject, "expire", json_integer(expire));
1545  json_array_append_new(jarray, bitobject);
1546  }
1547 
1548  json_object_set_new(jdata, "count", json_integer(i));
1549  json_object_set_new(jdata, "hostbits", jarray);
1550  json_object_set_new(answer, "message", jdata);
1551  return TM_ECODE_OK;
1552 }
1553 
1554 static void MemcapBuildValue(uint64_t val, char *str, uint32_t str_len)
1555 {
1556  if ((val / (1024 * 1024 * 1024)) != 0) {
1557  snprintf(str, str_len, "%"PRIu64"gb", val / (1024*1024*1024));
1558  } else if ((val / (1024 * 1024)) != 0) {
1559  snprintf(str, str_len, "%"PRIu64"mb", val / (1024*1024));
1560  } else {
1561  snprintf(str, str_len, "%"PRIu64"kb", val / (1024));
1562  }
1563 }
1564 
1565 TmEcode UnixSocketSetMemcap(json_t *cmd, json_t* answer, void *data)
1566 {
1567  char *memcap = NULL;
1568  char *value_str = NULL;
1569  uint64_t value;
1570 
1571  json_t *jarg = json_object_get(cmd, "config");
1572  if (!json_is_string(jarg)) {
1573  json_object_set_new(answer, "message", json_string("memcap key is not a string"));
1574  return TM_ECODE_FAILED;
1575  }
1576  memcap = (char *)json_string_value(jarg);
1577 
1578  jarg = json_object_get(cmd, "memcap");
1579  if (!json_is_string(jarg)) {
1580  json_object_set_new(answer, "message", json_string("memcap value is not a string"));
1581  return TM_ECODE_FAILED;
1582  }
1583  value_str = (char *)json_string_value(jarg);
1584 
1585  if (ParseSizeStringU64(value_str, &value) < 0) {
1586  SCLogError("Error parsing "
1587  "memcap from unix socket: %s",
1588  value_str);
1589  json_object_set_new(answer, "message",
1590  json_string("error parsing memcap specified, "
1591  "value not changed"));
1592  return TM_ECODE_FAILED;
1593  }
1594 
1595  for (size_t i = 0; i < ARRAY_SIZE(memcaps); i++) {
1596  if (strcmp(memcaps[i].name, memcap) == 0 && memcaps[i].SetFunc) {
1597  int updated = memcaps[i].SetFunc(value);
1598  char message[150];
1599 
1600  if (updated) {
1601  snprintf(message, sizeof(message),
1602  "memcap value for '%s' updated: %"PRIu64" %s",
1603  memcaps[i].name, value,
1604  (value == 0) ? "(unlimited)" : "");
1605  json_object_set_new(answer, "message", json_string(message));
1606  return TM_ECODE_OK;
1607  } else {
1608  if (value == 0) {
1609  snprintf(message, sizeof(message),
1610  "Unlimited value is not allowed for '%s'", memcaps[i].name);
1611  } else {
1612  if (memcaps[i].GetMemuseFunc()) {
1613  char memuse[50];
1614  MemcapBuildValue(memcaps[i].GetMemuseFunc(), memuse, sizeof(memuse));
1615  snprintf(message, sizeof(message),
1616  "memcap value specified for '%s' is less than the memory in use: %s",
1617  memcaps[i].name, memuse);
1618  } else {
1619  snprintf(message, sizeof(message),
1620  "memcap value specified for '%s' is less than the memory in use",
1621  memcaps[i].name);
1622  }
1623  }
1624  json_object_set_new(answer, "message", json_string(message));
1625  return TM_ECODE_FAILED;
1626  }
1627  }
1628  }
1629 
1630  json_object_set_new(answer, "message",
1631  json_string("Memcap value not found. Use 'memcap-list' to show all"));
1632  return TM_ECODE_FAILED;
1633 }
1634 
1635 TmEcode UnixSocketShowMemcap(json_t *cmd, json_t *answer, void *data)
1636 {
1637  char *memcap = NULL;
1638 
1639  json_t *jarg = json_object_get(cmd, "config");
1640  if (!json_is_string(jarg)) {
1641  json_object_set_new(answer, "message", json_string("memcap name is not a string"));
1642  return TM_ECODE_FAILED;
1643  }
1644  memcap = (char *)json_string_value(jarg);
1645 
1646  for (size_t i = 0; i < ARRAY_SIZE(memcaps); i++) {
1647  if (strcmp(memcaps[i].name, memcap) == 0 && memcaps[i].GetFunc) {
1648  char str[50];
1649  uint64_t val = memcaps[i].GetFunc();
1650  json_t *jobj = json_object();
1651  if (jobj == NULL) {
1652  json_object_set_new(answer, "message",
1653  json_string("internal error at json object creation"));
1654  return TM_ECODE_FAILED;
1655  }
1656 
1657  if (val == 0) {
1658  strlcpy(str, "unlimited", sizeof(str));
1659  } else {
1660  MemcapBuildValue(val, str, sizeof(str));
1661  }
1662 
1663  json_object_set_new(jobj, "value", json_string(str));
1664  json_object_set_new(answer, "message", jobj);
1665  return TM_ECODE_OK;
1666  }
1667  }
1668 
1669  json_object_set_new(answer, "message",
1670  json_string("Memcap value not found. Use 'memcap-list' to show all"));
1671  return TM_ECODE_FAILED;
1672 }
1673 
1674 TmEcode UnixSocketShowAllMemcap(json_t *cmd, json_t *answer, void *data)
1675 {
1676  json_t *jmemcaps = json_array();
1677 
1678  if (jmemcaps == NULL) {
1679  json_object_set_new(answer, "message",
1680  json_string("internal error at json array creation"));
1681  return TM_ECODE_FAILED;
1682  }
1683 
1684  for (size_t i = 0; i < ARRAY_SIZE(memcaps); i++) {
1685  json_t *jobj = json_object();
1686  if (jobj == NULL) {
1687  json_decref(jmemcaps);
1688  json_object_set_new(answer, "message",
1689  json_string("internal error at json object creation"));
1690  return TM_ECODE_FAILED;
1691  }
1692  char str[50];
1693  uint64_t val = memcaps[i].GetFunc();
1694 
1695  if (val == 0) {
1696  strlcpy(str, "unlimited", sizeof(str));
1697  } else {
1698  MemcapBuildValue(val, str, sizeof(str));
1699  }
1700 
1701  json_object_set_new(jobj, "name", json_string(memcaps[i].name));
1702  json_object_set_new(jobj, "value", json_string(str));
1703  json_array_append_new(jmemcaps, jobj);
1704  }
1705 
1706  json_object_set_new(answer, "message", jmemcaps);
1708 }
1709 
1710 TmEcode UnixSocketGetFlowStatsById(json_t *cmd, json_t *answer, void *data)
1711 {
1712  /* Input: we need the IP tuple including VLAN/tenant and the flow ID */
1713  json_t *jarg = json_object_get(cmd, "flow_id");
1714  if (!json_is_integer(jarg)) {
1715  SCLogInfo("error: command is not a string");
1716  json_object_set_new(answer, "message", json_string("flow_id is not an integer"));
1717  return TM_ECODE_FAILED;
1718  }
1719  int64_t flow_id = json_integer_value(jarg);
1720 
1721  Flow *f = FlowGetExistingFlowFromFlowId(flow_id);
1722  if (f == NULL) {
1723  json_object_set_new(answer, "message", json_string("Not found"));
1725  }
1726  uint32_t tosrcpktcnt = f->tosrcpktcnt;
1727  uint32_t todstpktcnt = f->todstpktcnt;
1728  uint64_t tosrcbytecnt = f->tosrcbytecnt;
1729  uint64_t todstbytecnt = f->todstbytecnt;
1730  uint64_t age = SCTIME_SECS(f->lastts) - SCTIME_SECS(f->startts);
1731  FLOWLOCK_UNLOCK(f);
1732 
1733  json_t *flow_info = json_object();
1734  if (flow_info == NULL) {
1736  }
1737  json_object_set_new(flow_info, "pkts_toclient", json_integer(tosrcpktcnt));
1738  json_object_set_new(flow_info, "pkts_toserver", json_integer(todstpktcnt));
1739  json_object_set_new(flow_info, "bytes_toclient", json_integer(tosrcbytecnt));
1740  json_object_set_new(flow_info, "bytes_toserver", json_integer(todstbytecnt));
1741  json_object_set_new(flow_info, "age", json_integer(age));
1742  json_object_set_new(answer, "message", flow_info);
1744 }
1745 #endif /* BUILD_UNIX_SOCKET */
1746 
1747 #ifdef BUILD_UNIX_SOCKET
1748 /**
1749  * \brief Single thread version of the Pcap file processing.
1750  */
1751 static int RunModeUnixSocketMaster(void)
1752 {
1753  if (UnixManagerInit() != 0)
1754  return 1;
1755 
1756  PcapCommand *pcapcmd = SCMalloc(sizeof(PcapCommand));
1757  if (unlikely(pcapcmd == NULL)) {
1758  SCLogError("Can not allocate pcap command");
1759  return 1;
1760  }
1761  TAILQ_INIT(&pcapcmd->files);
1762  pcapcmd->running = 0;
1763  pcapcmd->current_file = NULL;
1764 
1765  memset(&unix_manager_pcap_last_processed, 0, sizeof(struct timespec));
1766 
1767  SCCtrlMutexInit(&unix_manager_pcap_last_processed_mutex, NULL);
1768 
1769  UnixManagerRegisterCommand("pcap-file", UnixSocketAddPcapFile, pcapcmd, UNIX_CMD_TAKE_ARGS);
1770  UnixManagerRegisterCommand("pcap-file-continuous", UnixSocketAddPcapFileContinuous, pcapcmd, UNIX_CMD_TAKE_ARGS);
1771  UnixManagerRegisterCommand("pcap-file-number", UnixSocketPcapFilesNumber, pcapcmd, 0);
1772  UnixManagerRegisterCommand("pcap-file-list", UnixSocketPcapFilesList, pcapcmd, 0);
1773  UnixManagerRegisterCommand("pcap-last-processed", UnixSocketPcapLastProcessed, pcapcmd, 0);
1774  UnixManagerRegisterCommand("pcap-interrupt", UnixSocketPcapInterrupt, pcapcmd, 0);
1775  UnixManagerRegisterCommand("pcap-current", UnixSocketPcapCurrent, pcapcmd, 0);
1776 
1777  UnixManagerRegisterBackgroundTask(UnixSocketPcapFilesCheck, pcapcmd);
1778 
1781 
1782  return 0;
1783 }
1784 #endif
1785 
1787 {
1789 }
1790 
1791 
1792 
1793 
host.h
tm-threads.h
HostBitList
int HostBitList(Host *h, XBit **iter)
Definition: host-bit.c:184
ts
uint64_t ts
Definition: source-erf-file.c:55
ippair.h
THashCleanup
void THashCleanup(THashTableContext *ctx)
Cleanup the thash engine.
Definition: util-thash.c:481
app-layer-htp-range.h
detect-engine.h
DetectEngineMTApply
int DetectEngineMTApply(void)
Definition: detect-engine.c:4908
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:4633
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:1990
Flow_::startts
SCTime_t startts
Definition: flow.h:493
stream-tcp.h
DetectEnginePruneFreeList
void DetectEnginePruneFreeList(void)
Definition: detect-engine.c:4727
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:275
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:190
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
TM_ECODE_DONE
@ TM_ECODE_DONE
Definition: tm-threads-common.h: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:54
Flow_
Flow data structure.
Definition: flow.h:356
XBit_::expire
SCTime_t expire
Definition: util-var.h:65
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:4145
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:1276
HostSetMemcap
int HostSetMemcap(uint64_t size)
Update memcap value.
Definition: host.c:68
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:248
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
FTPMemuseGlobalCounter
uint64_t FTPMemuseGlobalCounter(void)
Definition: app-layer-ftp.c:78
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:128
FlowGetMemcap
uint64_t FlowGetMemcap(void)
Return memcap value.
Definition: flow.c:122
Address_
Definition: decode.h:112
PreRunInit
void PreRunInit(const int runmode)
Definition: suricata.c:2281
stream-tcp-reassemble.h
DetectEngineReloadTenantsBlocking
int DetectEngineReloadTenantsBlocking(const int reload_cnt)
Reload all tenants and wait for loading to complete.
Definition: detect-engine.c:4159
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:553
PacketPoolPostRunmodes
void PacketPoolPostRunmodes(void)
Set the max_pending_return_packets value.
Definition: tmqh-packetpool.c:459
app-layer-ftp.h
MAX
#define MAX(x, y)
Definition: suricata-common.h: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:273
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:498
DetectEngineMultiTenantEnabled
int DetectEngineMultiTenantEnabled(void)
Definition: detect-engine.c:3874
HTPByteRangeSetMemcap
int HTPByteRangeSetMemcap(uint64_t size)
Definition: app-layer-htp-range.c:45
datasets.h
VarNameStoreLookupByName
uint32_t VarNameStoreLookupByName(const char *name, const enum VarTypes type)
find name for id+type at packet time.
Definition: util-var-name.c:315
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:312
PreRunPostPrivsDropInit
void PreRunPostPrivsDropInit(const int runmode)
Definition: suricata.c:2310
util-debug.h
DetectEngineMoveToFreeList
int DetectEngineMoveToFreeList(DetectEngineCtx *de_ctx)
Definition: detect-engine.c:4717
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:250
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
TmThreadWaitOnThreadInit
TmEcode TmThreadWaitOnThreadInit(void)
Used to check if all threads have finished their initialization. On finding an un-initialized thread,...
Definition: tm-threads.c:2029
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:495
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:61
SCTimespecAsEpochMillis
uint64_t SCTimespecAsEpochMillis(const struct timespec *ts)
Definition: util-time.c:639
Flow_::lastts
SCTime_t lastts
Definition: flow.h:410
DATASET_TYPE_NOTSET
#define DATASET_TYPE_NOTSET
Definition: datasets.h:38
IPPairGetMemcap
uint64_t IPPairGetMemcap(void)
Return memcap value.
Definition: ippair.c:81
SCEnter
#define SCEnter(...)
Definition: util-debug.h:277
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:1786
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:497
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:4131
SCCtrlMutexLock
#define SCCtrlMutexLock(mut)
Definition: threads-debug.h:376
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
name
const char * name
Definition: tm-threads.c:2163
flow-timeout.h
DatasetRemoveSerialized
int DatasetRemoveSerialized(Dataset *set, const char *string)
remove serialized data from set
Definition: datasets.c:1536
defrag.h
FTPMemcapGlobalCounter
uint64_t FTPMemcapGlobalCounter(void)
Definition: app-layer-ftp.c:84
runmodes.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:225
SCConfSetFinal
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:318
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:37
SCCtrlMutexUnlock
#define SCCtrlMutexUnlock(mut)
Definition: threads-debug.h:378
StreamTcpSetMemcap
int StreamTcpSetMemcap(uint64_t size)
Update memcap value.
Definition: stream-tcp.c:279
RunModeUnixSocketRegister
void RunModeUnixSocketRegister(void)
Definition: runmode-unix-socket.c: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.
Definition: util-var-name.c:298
SCCtrlMutex
#define SCCtrlMutex
Definition: threads-debug.h:373
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:4590
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
FTPSetMemcap
int FTPSetMemcap(uint64_t size)
Definition: app-layer-ftp.c:90
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:267
SCFree
#define SCFree(p)
Definition: util-mem.h:61
HTPByteRangeMemcapGlobalCounter
uint64_t HTPByteRangeMemcapGlobalCounter(void)
Definition: app-layer-htp-range.c:55
StreamTcpMemuseCounter
uint64_t StreamTcpMemuseCounter(void)
Definition: stream-tcp.c:254
StreamTcpReassembleMemuseGlobalCounter
uint64_t StreamTcpReassembleMemuseGlobalCounter(void)
Definition: stream-tcp-reassemble.c:150
TAILQ_HEAD
#define TAILQ_HEAD(name, type)
Definition: queue.h:230
SCCtrlMutexInit
#define SCCtrlMutexInit(mut, mutattr)
Definition: threads-debug.h:375
StreamTcpGetMemcap
uint64_t StreamTcpGetMemcap(void)
Return memcap value.
Definition: stream-tcp.c:294
PcapFiles_::delay
time_t delay
Definition: runmode-unix-socket.c: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:2326
XBit_::idx
uint32_t idx
Definition: util-var.h:63
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:938
XBit_
Definition: util-var.h:60
Dataset
Definition: datasets.h:47
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:4580
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:243
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:1033
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:281
DetectEngineTenantUnregisterPcapFile
int DetectEngineTenantUnregisterPcapFile(uint32_t tenant_id)
Definition: detect-engine.c:4596
DatajsonAddSerialized
int DatajsonAddSerialized(Dataset *set, const char *value, const char *json)
add serialized data to json set
Definition: datasets-context-json.c:875
DetectEngineGetByTenantId
DetectEngineCtx * DetectEngineGetByTenantId(uint32_t tenant_id)
Definition: detect-engine.c:4607
DetectEngineTenantUnregisterVlanId
int DetectEngineTenantUnregisterVlanId(uint32_t tenant_id, uint16_t vlan_id)
Definition: detect-engine.c:4585
SCStat
struct stat SCStat
Definition: util-path.h:33
Flow_::tosrcpktcnt
uint32_t tosrcpktcnt
Definition: flow.h:496
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:107