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"
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"
59#include "runmode-unix-socket.h"
60
62
73
74typedef struct PcapCommand_ {
75 TAILQ_HEAD(, PcapFiles_) files;
76 int running;
77 PcapFiles *current_file;
79
80typedef 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
92static 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
129static int RunModeUnixSocketMaster(void);
130static int unix_manager_pcap_task_running = 0;
131static int unix_manager_pcap_task_failed = 0;
132static int unix_manager_pcap_task_interrupted = 0;
133static struct timespec unix_manager_pcap_last_processed;
134static 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 */
141static 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
172static 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
185static 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
198static 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
211static 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
220static 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 */
245static 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 */
292static 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 */
403static 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 */
422static 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 */
440static 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
569TmEcode 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 */
610TmEcode 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
663TmEcode 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
716TmEcode 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
725TmEcode 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
761TmEcode 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 */
817TmEcode 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
878static 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 */
895TmEcode 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) {
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 */
981TmEcode 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) {
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 */
1068TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data)
1069{
1070 const char *filename;
1071 SCStat st;
1072
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
1133static 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 */
1141TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data)
1142{
1143 const char *filename = NULL;
1144 SCStat st;
1145
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 */
1207TmEcode UnixSocketReloadTenants(json_t *cmd, json_t *answer, void *data)
1208{
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 */
1242TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data)
1243{
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 */
1300TmEcode 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 */
1387TmEcode 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 */
1460TmEcode 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
1554static 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
1565TmEcode 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
1635TmEcode 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
1674TmEcode 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
1710TmEcode 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 */
1751static 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
1790
1791
1792
1793
uint64_t FTPMemcapGlobalCounter(void)
int FTPSetMemcap(uint64_t size)
uint64_t FTPMemuseGlobalCounter(void)
uint64_t HTPMemuseGlobalCounter(void)
int HTPSetMemcap(uint64_t size)
Update memcap value.
uint64_t HTPGetMemcap(void)
Update memcap value.
int HTPByteRangeSetMemcap(uint64_t size)
uint64_t HTPByteRangeMemcapGlobalCounter(void)
uint64_t HTPByteRangeMemuseGlobalCounter(void)
struct HtpBodyChunk_ * next
int SCConfYamlLoadFileWithPrefix(const char *filename, const char *prefix)
Load configuration from a YAML file, insert in tree at 'prefix'.
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition conf.c:318
int DatajsonAddSerialized(Dataset *set, const char *value, const char *json)
add serialized data to json set
int DatasetLookupSerialized(Dataset *set, const char *string)
add serialized data to set
Definition datasets.c:1458
int DatasetAddSerialized(Dataset *set, const char *string)
add serialized data to set
Definition datasets.c:1446
int DatasetRemoveSerialized(Dataset *set, const char *string)
remove serialized data from set
Definition datasets.c:1536
void DatasetsSave(void)
Definition datasets.c:852
Dataset * DatasetFind(const char *name, enum DatasetTypes type)
look for set by name without creating it
Definition datasets.c:320
enum DatasetTypes DatasetGetTypeFromString(const char *s)
Definition datasets.c:64
#define DATASET_TYPE_NOTSET
Definition datasets.h:38
DatasetTypes
Definition datasets.h:37
uint16_t type
uint64_t DefragTrackerGetMemcap(void)
Return memcap value.
Definition defrag-hash.c:63
uint64_t DefragTrackerGetMemuse(void)
Return memuse value.
Definition defrag-hash.c:74
int DefragTrackerSetMemcap(uint64_t size)
Update memcap value.
Definition defrag-hash.c:48
void DetectEnginePruneFreeList(void)
int DetectEngineTenantUnregisterPcapFile(uint32_t tenant_id)
int DetectEngineMoveToFreeList(DetectEngineCtx *de_ctx)
int DetectEngineMTApply(void)
int DetectEngineLoadTenantBlocking(uint32_t tenant_id, const char *yaml)
Load a tenant and wait for loading to complete.
int DetectEngineReloadTenantBlocking(uint32_t tenant_id, const char *yaml, int reload_cnt)
Reload a tenant and wait for loading to complete.
DetectEngineCtx * DetectEngineGetByTenantId(uint32_t tenant_id)
int DetectEngineTenantRegisterPcapFile(uint32_t tenant_id)
void DetectEngineDeReference(DetectEngineCtx **de_ctx)
bool DetectEngineMultiTenantEnabled(void)
int DetectEngineReloadTenantsBlocking(const int reload_cnt)
Reload all tenants and wait for loading to complete.
int DetectEngineTenantUnregisterVlanId(uint32_t tenant_id, uint16_t vlan_id)
int DetectEngineTenantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id)
uint32_t id
Flow * FlowGetExistingFlowFromFlowId(uint64_t flow_id)
Look for existing Flow using a flow id value.
Definition flow-hash.c:1033
int FlowSetMemcap(uint64_t size)
Update memcap value.
Definition flow.c:107
uint64_t FlowGetMemuse(void)
Definition flow.c:128
uint64_t FlowGetMemcap(void)
Return memcap value.
Definition flow.c:122
#define FLOWLOCK_UNLOCK(fb)
Definition flow.h:273
DetectEngineCtx * de_ctx
void HostBitSet(Host *h, uint32_t idx, SCTime_t expire)
Definition host-bit.c:131
void HostBitUnset(Host *h, uint32_t idx)
Definition host-bit.c:139
int HostBitList(Host *h, XBit **iter)
Definition host-bit.c:184
uint64_t HostGetMemcap(void)
Return memcap value.
Definition host.c:83
Host * HostLookupHostFromHash(Address *a)
look up a host in the hash
Definition host.c:585
uint64_t HostGetMemuse(void)
Return memuse value.
Definition host.c:94
Host * HostGetHostFromHash(Address *a)
Definition host.c:486
void HostRelease(Host *h)
Definition host.c:461
int HostSetMemcap(uint64_t size)
Update memcap value.
Definition host.c:68
int IPPairSetMemcap(uint64_t size)
Update memcap value.
Definition ippair.c:66
uint64_t IPPairGetMemuse(void)
Return memuse value.
Definition ippair.c:92
uint64_t IPPairGetMemcap(void)
Return memcap value.
Definition ippair.c:81
json_t * SCJsonString(const char *val)
Definition output-json.c:96
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:252
#define TAILQ_INIT(head)
Definition queue.h:262
#define TAILQ_HEAD(name, type)
Definition queue.h:230
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:294
#define TAILQ_FIRST(head)
Definition queue.h:250
#define TAILQ_REMOVE(head, elm, field)
Definition queue.h:312
#define TAILQ_EMPTY(head)
Definition queue.h:248
#define TAILQ_ENTRY(type)
Definition queue.h:239
struct PcapFiles_ PcapFiles
struct MemcapCommand_ MemcapCommand
TmEcode UnixSocketPcapFile(TmEcode tm, struct timespec *last_processed)
void RunModeUnixSocketRegister(void)
int unix_socket_mode_is_running
struct PcapCommand_ PcapCommand
float MemcapsGetPressure(void)
int RunModeUnixSocketIsActive(void)
const char * RunModeUnixSocketGetDefaultMode(void)
void RunModeDispatch(int runmode, const char *custom_mode, const char *capture_plugin_name, const char *capture_plugin_args)
Definition runmodes.c:409
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
@ RUNMODE_PCAP_FILE
Definition runmodes.h:30
@ RUNMODE_UNIX_SOCKET
Definition runmodes.h:42
uint64_t ts
uint64_t StreamTcpReassembleMemuseGlobalCounter(void)
uint64_t StreamTcpReassembleGetMemcap(void)
Return memcap value.
int StreamTcpReassembleSetMemcap(uint64_t size)
Update memcap value.
uint64_t StreamTcpGetMemcap(void)
Return memcap value.
Definition stream-tcp.c:294
int StreamTcpSetMemcap(uint64_t size)
Update memcap value.
Definition stream-tcp.c:279
uint64_t StreamTcpMemuseCounter(void)
Definition stream-tcp.c:254
char family
Definition decode.h:113
THashTableContext * hash
Definition datasets.h:54
main detection engine ctx
Definition detect.h:932
Flow data structure.
Definition flow.h:356
uint64_t tosrcbytecnt
Definition flow.h:498
uint64_t todstbytecnt
Definition flow.h:497
SCTime_t lastts
Definition flow.h:410
uint32_t todstpktcnt
Definition flow.h:495
uint32_t tosrcpktcnt
Definition flow.h:496
SCTime_t startts
Definition flow.h:493
Definition host.h:58
int(* SetFunc)(uint64_t)
uint64_t(* GetFunc)(void)
uint64_t(* GetMemuseFunc)(void)
SCTime_t expire
Definition util-var.h:65
uint32_t idx
Definition util-var.h:63
#define ARRAY_SIZE(arr)
#define MAX(x, y)
#define str(s)
size_t strlcpy(char *dst, const char *src, size_t siz)
void PostRunDeinit(const int runmode, struct timeval *start_time)
clean up / shutdown code for packet modes
Definition suricata.c:2331
void PreRunInit(const int runmode)
Definition suricata.c:2286
void PreRunPostPrivsDropInit(const int runmode)
Definition suricata.c:2315
#define SCCtrlMutexInit(mut, mutattr)
#define SCCtrlMutexLock(mut)
#define SCCtrlMutex
#define SCCtrlMutexUnlock(mut)
@ TM_ECODE_FAILED
@ TM_ECODE_OK
@ TM_ECODE_DONE
TmEcode TmThreadWaitOnThreadInit(void)
Used to check if all threads have finished their initialization. On finding an un-initialized thread,...
const char * name
void TmThreadContinueThreads(void)
Unpauses all threads present in tv_root.
void PacketPoolPostRunmodes(void)
Set the max_pending_return_packets value.
void UnixManagerThreadSpawn(int mode)
#define UNIX_CMD_TAKE_ARGS
int UnixManagerInit(void)
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition util-debug.h:243
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition util-debug.h:225
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define SCStrdup(s)
Definition util-mem.h:56
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition util-misc.c:190
#define unlikely(expr)
#define SCStatFn(pathname, statbuf)
Definition util-path.h:35
struct stat SCStat
Definition util-path.h:33
void THashCleanup(THashTableContext *ctx)
Cleanup the thash engine.
Definition util-thash.c:481
uint64_t SCTimespecAsEpochMillis(const struct timespec *ts)
Definition util-time.c:639
SCTime_t TimeGet(void)
Definition util-time.c:152
#define SCTIME_SECS(t)
Definition util-time.h:57
#define SCTIME_CMP_LT(a, b)
Definition util-time.h:105
#define SCTIME_ADD_SECS(ts, s)
Definition util-time.h:64
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.
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.
@ VAR_TYPE_HOST_BIT
Definition util-var.h:41