suricata
conf.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2023 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/**
19 * \file
20 *
21 * \author Endace Technology Limited - Jason Ish <jason.ish@endace.com>
22 *
23 * This file provides a basic configuration system for the IDPS
24 * engine.
25 *
26 * NOTE: Setting values should only be done from one thread during
27 * engine initialization. Multiple threads should be able access read
28 * configuration data. Allowing run time changes to the configuration
29 * will require some locks.
30 *
31 * \todo Consider having the in-memory configuration database a direct
32 * reflection of the configuration file and moving command line
33 * parameters to a primary lookup table?
34 *
35 * \todo Get rid of allow override and go with a simpler first set,
36 * stays approach?
37 */
38
39#include "suricata-common.h"
40#include "conf.h"
41#include "util-unittest.h"
42#include "util-debug.h"
43#include "util-path.h"
44#include "util-conf.h"
45
46/** Maximum size of a complete domain name. */
47#define NODE_NAME_MAX 1024
48
49static SCConfNode *root = NULL;
50static SCConfNode *root_backup = NULL;
51
52/**
53 * \brief Helper function to get a node, creating it if it does not
54 * exist.
55 *
56 * This function exits on memory failure as creating configuration
57 * nodes is usually part of application initialization.
58 *
59 * \param parent The node to use as the parent
60 * \param name The name of the configuration node to get.
61 * \param final Flag to set created nodes as final or not.
62 *
63 * \retval The existing configuration node if it exists, or a newly
64 * created node for the provided name. On error, NULL will be returned.
65 */
66SCConfNode *SCConfNodeGetNodeOrCreate(SCConfNode *parent, const char *name, int final)
67{
68 SCConfNode *node = NULL;
69 char node_name[NODE_NAME_MAX];
70 char *key;
71 char *next;
72
73 if (strlcpy(node_name, name, sizeof(node_name)) >= sizeof(node_name)) {
74 SCLogError("Configuration name too long: %s", name);
75 return NULL;
76 }
77
78 key = node_name;
79
80 do {
81 if ((next = strchr(key, '.')) != NULL)
82 *next++ = '\0';
83 if ((node = SCConfNodeLookupChild(parent, key)) == NULL) {
84 node = SCConfNodeNew();
85 if (unlikely(node == NULL)) {
86 SCLogWarning("Failed to allocate memory for configuration.");
87 goto end;
88 }
89 node->name = SCStrdup(key);
90 if (unlikely(node->name == NULL)) {
91 SCConfNodeFree(node);
92 node = NULL;
93 SCLogWarning("Failed to allocate memory for configuration.");
94 goto end;
95 }
96 node->parent = parent;
97 node->final = final;
98 TAILQ_INSERT_TAIL(&parent->head, node, next);
99 }
100 key = next;
101 parent = node;
102 } while (next != NULL);
103
104end:
105 return node;
106}
107
108/**
109 * \brief Wrapper function for SCConfNodeGetNodeOrCreate that operates
110 * on the current root node.
111 */
112static SCConfNode *SCConfGetNodeOrCreate(const char *name, int final)
113{
114 return SCConfNodeGetNodeOrCreate(root, name, final);
115}
116
117/**
118 * \brief Initialize the configuration system.
119 */
120void SCConfInit(void)
121{
122 if (root != NULL) {
123 SCLogDebug("already initialized");
124 return;
125 }
126 root = SCConfNodeNew();
127 if (root == NULL) {
128 FatalError("ERROR: Failed to allocate memory for root configuration node, "
129 "aborting.");
130 }
131 SCLogDebug("configuration module initialized");
132}
133
134/**
135 * \brief Allocate a new configuration node.
136 *
137 * \retval An allocated configuration node on success, NULL on failure.
138 */
140{
141 SCConfNode *new;
142
143 new = SCCalloc(1, sizeof(*new));
144 if (unlikely(new == NULL)) {
145 return NULL;
146 }
147 TAILQ_INIT(&new->head);
148
149 return new;
150}
151
152/**
153 * \brief Free a SCConfNode and all of its children.
154 *
155 * \param node The configuration node to SCFree.
156 */
158{
159 SCConfNode *tmp;
160
161 while ((tmp = TAILQ_FIRST(&node->head))) {
162 TAILQ_REMOVE(&node->head, tmp, next);
163 SCConfNodeFree(tmp);
164 }
165
166 if (node->name != NULL)
167 SCFree(node->name);
168 if (node->val != NULL)
169 SCFree(node->val);
170 SCFree(node);
171}
172
173/**
174 * \brief Get a SCConfNode by name.
175 *
176 * \param name The full name of the configuration node to lookup.
177 *
178 * \retval A pointer to SCConfNode is found or NULL if the configuration
179 * node does not exist.
180 */
182{
183 SCConfNode *node = root;
184 char node_name[NODE_NAME_MAX];
185 char *key;
186 char *next;
187
188 if (strlcpy(node_name, name, sizeof(node_name)) >= sizeof(node_name)) {
189 SCLogError("Configuration name too long: %s", name);
190 return NULL;
191 }
192
193 key = node_name;
194 do {
195 if ((next = strchr(key, '.')) != NULL)
196 *next++ = '\0';
197 node = SCConfNodeLookupChild(node, key);
198 key = next;
199 } while (next != NULL && node != NULL);
200
201 return node;
202}
203
205{
206 return TAILQ_FIRST(&parent->head);
207}
208
210{
211 return TAILQ_NEXT(node, next);
212}
213
214const char *SCConfGetValueNode(const SCConfNode *node)
215{
216 return node->val;
217}
218
219/**
220 * \brief Get the root configuration node.
221 */
223{
224 return root;
225}
226
227/**
228 * \brief Set a configuration value.
229 *
230 * Configuration values set with this function may be overridden by
231 * subsequent calls, or if the value appears multiple times in a
232 * configuration file.
233 *
234 * \param name The name of the configuration parameter to set.
235 * \param val The value of the configuration parameter.
236 *
237 * \retval 1 if the value was set otherwise 0.
238 */
239int SCConfSet(const char *name, const char *val)
240{
241 SCConfNode *node = SCConfGetNodeOrCreate(name, 0);
242 if (node == NULL || node->final) {
243 return 0;
244 }
245 if (node->val != NULL)
246 SCFree(node->val);
247 node->val = SCStrdup(val);
248 if (unlikely(node->val == NULL)) {
249 return 0;
250 }
251 return 1;
252}
253
254/**
255 * \brief Set a configuration parameter from a string.
256 *
257 * Where the input string is something like:
258 * stream.midstream=true
259 *
260 * \param input the input string to be parsed.
261 *
262 * \retval 1 if the value of set, otherwise 0.
263 */
264int SCConfSetFromString(const char *input, int final)
265{
266 int retval = 0;
267 char *name = SCStrdup(input), *val = NULL;
268 if (unlikely(name == NULL)) {
269 goto done;
270 }
271 val = strchr(name, '=');
272 if (val == NULL) {
273 goto done;
274 }
275 *val++ = '\0';
276
277 while (isspace((int)name[strlen(name) - 1])) {
278 name[strlen(name) - 1] = '\0';
279 }
280
281 while (isspace((int)*val)) {
282 val++;
283 }
284
285 if (final) {
286 if (!SCConfSetFinal(name, val)) {
287 goto done;
288 }
289 }
290 else {
291 if (!SCConfSet(name, val)) {
292 goto done;
293 }
294 }
295
296 retval = 1;
297done:
298 if (name != NULL) {
299 SCFree(name);
300 }
301 return retval;
302}
303
304/**
305 * \brief Set a final configuration value.
306 *
307 * A final configuration value is a value that cannot be overridden by
308 * the configuration file. Its mainly useful for setting values that
309 * are supplied on the command line prior to the configuration file
310 * being loaded. However, a subsequent call to this function can
311 * override a previously set value.
312 *
313 * \param name The name of the configuration parameter to set.
314 * \param val The value of the configuration parameter.
315 *
316 * \retval 1 if the value was set otherwise 0.
317 */
318int SCConfSetFinal(const char *name, const char *val)
319{
320 SCConfNode *node = SCConfGetNodeOrCreate(name, 1);
321 if (node == NULL) {
322 return 0;
323 }
324 if (node->val != NULL)
325 SCFree(node->val);
326 node->val = SCStrdup(val);
327 if (unlikely(node->val == NULL)) {
328 return 0;
329 }
330 node->final = 1;
331 return 1;
332}
333
334/**
335 * \brief Retrieve the value of a configuration node.
336 *
337 * This function will return the value for a configuration node based
338 * on the full name of the node. It is possible that the value
339 * returned could be NULL, this could happen if the requested node
340 * does exist but is not a node that contains a value, but contains
341 * children SCConfNodes instead.
342 *
343 * \param name Name of configuration parameter to get.
344 * \param vptr Pointer that will be set to the configuration value parameter.
345 * Note that this is just a reference to the actual value, not a copy.
346 *
347 * \retval 1 will be returned if the name is found, otherwise 0 will
348 * be returned.
349 */
350int SCConfGet(const char *name, const char **vptr)
351{
353 if (node == NULL) {
354 SCLogDebug("failed to lookup configuration parameter '%s'", name);
355 return 0;
356 }
357 else {
358 *vptr = node->val;
359 return 1;
360 }
361}
362
363int SCConfGetChildValue(const SCConfNode *base, const char *name, const char **vptr)
364{
366
367 if (node == NULL) {
368 SCLogDebug("failed to lookup configuration parameter '%s'", name);
369 return 0;
370 }
371 else {
372 if (node->val == NULL)
373 return 0;
374 *vptr = node->val;
375 return 1;
376 }
377}
378
380 const SCConfNode *base, const SCConfNode *dflt, const char *name)
381{
383 if (node != NULL)
384 return node;
385
386 /* Get 'default' value */
387 if (dflt) {
388 return SCConfNodeLookupChild(dflt, name);
389 }
390 return NULL;
391}
392
394 const SCConfNode *base, const SCConfNode *dflt, const char *name, const char **vptr)
395{
396 int ret = SCConfGetChildValue(base, name, vptr);
397 /* Get 'default' value */
398 if (ret == 0 && dflt) {
399 return SCConfGetChildValue(dflt, name, vptr);
400 }
401 return ret;
402}
403
404/**
405 * \brief Retrieve a configuration value as an integer.
406 *
407 * \param name Name of configuration parameter to get.
408 * \param val Pointer to an intmax_t that will be set the
409 * configuration value.
410 *
411 * \retval 1 will be returned if the name is found and was properly
412 * converted to an integer, otherwise 0 will be returned.
413 */
414int SCConfGetInt(const char *name, intmax_t *val)
415{
416 const char *strval = NULL;
417 intmax_t tmpint;
418 char *endptr;
419
420 if (SCConfGet(name, &strval) == 0)
421 return 0;
422
423 if (strval == NULL) {
424 SCLogError("malformed integer value "
425 "for %s: NULL",
426 name);
427 return 0;
428 }
429
430 errno = 0;
431 tmpint = strtoimax(strval, &endptr, 0);
432 if (strval[0] == '\0' || *endptr != '\0') {
433 SCLogError("malformed integer value "
434 "for %s: '%s'",
435 name, strval);
436 return 0;
437 }
438 if (errno == ERANGE && (tmpint == INTMAX_MAX || tmpint == INTMAX_MIN)) {
439 SCLogError("integer value for %s out "
440 "of range: '%s'",
441 name, strval);
442 return 0;
443 }
444
445 *val = tmpint;
446 return 1;
447}
448
449int SCConfGetChildValueInt(const SCConfNode *base, const char *name, intmax_t *val)
450{
451 const char *strval = NULL;
452 intmax_t tmpint;
453 char *endptr;
454
455 if (SCConfGetChildValue(base, name, &strval) == 0)
456 return 0;
457 errno = 0;
458 tmpint = strtoimax(strval, &endptr, 0);
459 if (strval[0] == '\0' || *endptr != '\0') {
460 SCLogError("malformed integer value "
461 "for %s with base %s: '%s'",
462 name, base->name, strval);
463 return 0;
464 }
465 if (errno == ERANGE && (tmpint == INTMAX_MAX || tmpint == INTMAX_MIN)) {
466 SCLogError("integer value for %s with "
467 " base %s out of range: '%s'",
468 name, base->name, strval);
469 return 0;
470 }
471
472 *val = tmpint;
473 return 1;
474}
475
477 const SCConfNode *base, const SCConfNode *dflt, const char *name, intmax_t *val)
478{
479 int ret = SCConfGetChildValueInt(base, name, val);
480 /* Get 'default' value */
481 if (ret == 0 && dflt) {
482 return SCConfGetChildValueInt(dflt, name, val);
483 }
484 return ret;
485}
486
487/**
488 * \brief Retrieve a configuration value as a boolean.
489 *
490 * \param name Name of configuration parameter to get.
491 * \param val Pointer to an int that will be set to 1 for true, or 0
492 * for false.
493 *
494 * \retval 1 will be returned if the name is found and was properly
495 * converted to a boolean, otherwise 0 will be returned.
496 */
497int SCConfGetBool(const char *name, int *val)
498{
499 const char *strval = NULL;
500
501 *val = 0;
502 if (SCConfGet(name, &strval) != 1)
503 return 0;
504
505 *val = SCConfValIsTrue(strval);
506
507 return 1;
508}
509
510/**
511 * Get a boolean value from the provided SCConfNode.
512 *
513 * \retval 1 If the value exists, 0 if not.
514 */
515int SCConfGetChildValueBool(const SCConfNode *base, const char *name, int *val)
516{
517 const char *strval = NULL;
518
519 *val = 0;
520 if (SCConfGetChildValue(base, name, &strval) == 0)
521 return 0;
522
523 *val = SCConfValIsTrue(strval);
524
525 return 1;
526}
527
529 const SCConfNode *base, const SCConfNode *dflt, const char *name, int *val)
530{
531 int ret = SCConfGetChildValueBool(base, name, val);
532 /* Get 'default' value */
533 if (ret == 0 && dflt) {
534 return SCConfGetChildValueBool(dflt, name, val);
535 }
536 return ret;
537}
538
539
540/**
541 * \brief Check if a value is true.
542 *
543 * The value is considered true if it is a string with the value of 1,
544 * yes, true or on. The test is not case sensitive, any other value
545 * is false.
546 *
547 * \param val The string to test for a true value.
548 *
549 * \retval 1 If the value is true, 0 if not.
550 */
551int SCConfValIsTrue(const char *val)
552{
553 const char *trues[] = {"1", "yes", "true", "on"};
554 size_t u;
555
556 for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) {
557 if (strcasecmp(val, trues[u]) == 0) {
558 return 1;
559 }
560 }
561
562 return 0;
563}
564
565/**
566 * \brief Check if a value is false.
567 *
568 * The value is considered false if it is a string with the value of 0,
569 * no, false or off. The test is not case sensitive, any other value
570 * is not false.
571 *
572 * \param val The string to test for a false value.
573 *
574 * \retval 1 If the value is false, 0 if not.
575 */
576int SCConfValIsFalse(const char *val)
577{
578 const char *falses[] = {"0", "no", "false", "off"};
579 size_t u;
580
581 for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) {
582 if (strcasecmp(val, falses[u]) == 0) {
583 return 1;
584 }
585 }
586
587 return 0;
588}
589
590/**
591 * \brief Retrieve a configuration value as a double
592 *
593 * \param name Name of configuration parameter to get.
594 * \param val Pointer to an double that will be set the
595 * configuration value.
596 *
597 * \retval 1 will be returned if the name is found and was properly
598 * converted to a double, otherwise 0 will be returned.
599 */
600int SCConfGetDouble(const char *name, double *val)
601{
602 const char *strval = NULL;
603 double tmpdo;
604 char *endptr;
605
606 if (SCConfGet(name, &strval) == 0)
607 return 0;
608
609 errno = 0;
610 tmpdo = strtod(strval, &endptr);
611 if (strval[0] == '\0' || *endptr != '\0')
612 return 0;
613 if (errno == ERANGE)
614 return 0;
615
616 *val = tmpdo;
617 return 1;
618}
619
620/**
621 * \brief Retrieve a configuration value as a float
622 *
623 * \param name Name of configuration parameter to get.
624 * \param val Pointer to an float that will be set the
625 * configuration value.
626 *
627 * \retval 1 will be returned if the name is found and was properly
628 * converted to a double, otherwise 0 will be returned.
629 */
630int SCConfGetFloat(const char *name, float *val)
631{
632 const char *strval = NULL;
633 double tmpfl;
634 char *endptr;
635
636 if (SCConfGet(name, &strval) == 0)
637 return 0;
638
639 errno = 0;
640 tmpfl = strtof(strval, &endptr);
641 if (strval[0] == '\0' || *endptr != '\0')
642 return 0;
643 if (errno == ERANGE)
644 return 0;
645
646 *val = tmpfl;
647 return 1;
648}
649
650/**
651 * \brief Remove (and SCFree) the provided configuration node.
652 */
654{
655 if (node->parent != NULL)
656 TAILQ_REMOVE(&node->parent->head, node, next);
657 SCConfNodeFree(node);
658}
659
660/**
661 * \brief Remove a configuration parameter from the configuration db.
662 *
663 * \param name The name of the configuration parameter to remove.
664 *
665 * \retval Returns 1 if the parameter was removed, otherwise 0 is returned
666 * most likely indicating the parameter was not set.
667 */
668int SCConfRemove(const char *name)
669{
670 SCConfNode *node;
671
672 node = SCConfGetNode(name);
673 if (node == NULL)
674 return 0;
675 else {
676 SCConfNodeRemove(node);
677 return 1;
678 }
679}
680
681/**
682 * \brief Creates a backup of the conf_hash hash_table used by the conf API.
683 */
685{
686 root_backup = root;
687 root = NULL;
688}
689
690/**
691 * \brief Restores the backup of the hash_table present in backup_conf_hash
692 * back to conf_hash.
693 */
695{
696 root = root_backup;
697 root_backup = NULL;
698}
699
700/**
701 * \brief De-initializes the configuration system.
702 */
703void SCConfDeInit(void)
704{
705 if (root != NULL) {
706 SCConfNodeFree(root);
707 root = NULL;
708 }
709
710 SCLogDebug("configuration module de-initialized");
711}
712
713static char *ConfPrintNameArray(char **name_arr, int level)
714{
715 static char name[128*128];
716 int i;
717
718 name[0] = '\0';
719 for (i = 0; i <= level; i++) {
720 strlcat(name, name_arr[i], sizeof(name));
721 if (i < level)
722 strlcat(name, ".", sizeof(name));
723 }
724
725 return name;
726}
727
728/**
729 * \brief Dump a configuration node and all its children.
730 */
731void SCConfNodeDump(const SCConfNode *node, const char *prefix)
732{
733 SCConfNode *child;
734
735 static char *name[128];
736 static int level = -1;
737
738 level++;
739 TAILQ_FOREACH(child, &node->head, next) {
740 name[level] = SCStrdup(child->name);
741 if (unlikely(name[level] == NULL)) {
742 continue;
743 }
744 if (prefix == NULL) {
745 printf("%s = %s\n", ConfPrintNameArray(name, level),
746 child->val);
747 }
748 else {
749 printf("%s.%s = %s\n", prefix,
750 ConfPrintNameArray(name, level), child->val);
751 }
752 SCConfNodeDump(child, prefix);
753 SCFree(name[level]);
754 }
755 level--;
756}
757
758/**
759 * \brief Dump configuration to stdout.
760 */
761void SCConfDump(void)
762{
763 SCConfNodeDump(root, NULL);
764}
765
766/**
767 * \brief Check if a node has any children.
768 *
769 * Checks if the provided node has any children. Any node that is a
770 * YAML map or array will have children.
771 *
772 * \param node The node to check.
773 *
774 * \retval true if node has children
775 * \retval false if node does not have children
776 */
778{
779 if (TAILQ_EMPTY(&node->head)) {
780 return false;
781 }
782 return true;
783}
784
785/**
786 * \brief Lookup a child configuration node by name.
787 *
788 * Given a SCConfNode this function will lookup an immediate child
789 * SCConfNode by name and return the child ConfNode.
790 *
791 * \param node The parent configuration node.
792 * \param name The name of the child node to lookup.
793 *
794 * \retval A pointer the child SCConfNode if found otherwise NULL.
795 */
797{
798 SCConfNode *child;
799
800 if (node == NULL || name == NULL) {
801 return NULL;
802 }
803
804 TAILQ_FOREACH(child, &node->head, next) {
805 if (child->name != NULL && strcmp(child->name, name) == 0)
806 return child;
807 }
808
809 return NULL;
810}
811
812/**
813 * \brief Lookup the value of a child configuration node by name.
814 *
815 * Given a parent SCConfNode this function will return the value of a
816 * child configuration node by name returning a reference to that
817 * value.
818 *
819 * \param node The parent configuration node.
820 * \param name The name of the child node to lookup.
821 *
822 * \retval A pointer the child SCConfNodes value if found otherwise NULL.
823 */
824const char *SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
825{
826 SCConfNode *child;
827
828 child = SCConfNodeLookupChild(node, name);
829 if (child != NULL)
830 return child->val;
831
832 return NULL;
833}
834
835/**
836 * \brief Lookup for a key value under a specific node
837 *
838 * \return the SCConfNode matching or NULL
839 */
840
841SCConfNode *SCConfNodeLookupKeyValue(const SCConfNode *base, const char *key, const char *value)
842{
843 SCConfNode *child;
844
845 TAILQ_FOREACH(child, &base->head, next) {
846 if (!strncmp(child->val, key, strlen(child->val))) {
847 SCConfNode *subchild;
848 TAILQ_FOREACH(subchild, &child->head, next) {
849 if ((!strcmp(subchild->name, key)) && (!strcmp(subchild->val, value))) {
850 return child;
851 }
852 }
853 }
854 }
855
856 return NULL;
857}
858
859/**
860 * \brief Test if a configuration node has a true value.
861 *
862 * \param node The parent configuration node.
863 * \param name The name of the child node to test.
864 *
865 * \retval 1 if the child node has a true value, otherwise 0 is
866 * returned, even if the child node does not exist.
867 */
868int SCConfNodeChildValueIsTrue(const SCConfNode *node, const char *key)
869{
870 const char *val;
871
872 val = SCConfNodeLookupChildValue(node, key);
873
874 return val != NULL ? SCConfValIsTrue(val) : 0;
875}
876
877/**
878 * \brief Create the path for an include entry
879 * \param file The name of the file
880 * \retval str Pointer to the string path + sig_file
881 */
882
883/**
884 * \brief Prune a configuration node.
885 *
886 * Pruning a configuration is similar to freeing, but only fields that
887 * may be overridden are, leaving final type parameters. Additional
888 * the value of the provided node is also free'd, but the node itself
889 * is left.
890 *
891 * \param node The configuration node to prune.
892 */
894{
895 SCConfNode *item, *it;
896
897 for (item = TAILQ_FIRST(&node->head); item != NULL; item = it) {
898 it = TAILQ_NEXT(item, next);
899 if (!item->final) {
900 SCConfNodePrune(item);
901 if (TAILQ_EMPTY(&item->head)) {
902 TAILQ_REMOVE(&node->head, item, next);
903 if (item->name != NULL)
904 SCFree(item->name);
905 if (item->val != NULL)
906 SCFree(item->val);
907 SCFree(item);
908 }
909 }
910 }
911
912 if (node->val != NULL) {
913 SCFree(node->val);
914 node->val = NULL;
915 }
916}
917
918/**
919 * \brief Check if a node is a sequence or node.
920 *
921 * \param node the node to check.
922 *
923 * \return 1 if node is a sequence, otherwise 0.
924 */
926{
927 return node->is_seq == 0 ? 0 : 1;
928}
929
930/**
931 * @brief Finds an interface from the list of interfaces.
932 * @param ifaces_node_name - name of the node which holds a list of interfaces
933 * @param iface - interfaces name
934 * @return NULL on failure otherwise a valid pointer
935 */
936SCConfNode *SCConfSetIfaceNode(const char *ifaces_node_name, const char *iface)
937{
938 SCConfNode *if_node;
939 SCConfNode *ifaces_list_node;
940 /* Find initial node which holds all interfaces */
941 ifaces_list_node = SCConfGetNode(ifaces_node_name);
942 if (ifaces_list_node == NULL) {
943 SCLogError("unable to find %s config", ifaces_node_name);
944 return NULL;
945 }
946
947 if_node = ConfFindDeviceConfig(ifaces_list_node, iface);
948 if (if_node == NULL)
949 SCLogNotice("unable to find interface %s in DPDK config", iface);
950
951 return if_node;
952}
953
954/**
955 * @brief Finds and sets root and default node of the interface.
956 * @param ifaces_node_name Node which holds list of interfaces
957 * @param iface Name of the interface e.g. eth3
958 * @param if_root Node which will hold the interface configuration
959 * @param if_default Node which is the default configuration in the given list of interfaces
960 * @return 0 on success, -ENODEV when neither the root interface nor the default interface was found
961 */
962int SCConfSetRootAndDefaultNodes(const char *ifaces_node_name, const char *iface,
963 SCConfNode **if_root, SCConfNode **if_default)
964{
965 const char *default_iface = "default";
966 *if_root = SCConfSetIfaceNode(ifaces_node_name, iface);
967 *if_default = SCConfSetIfaceNode(ifaces_node_name, default_iface);
968
969 if (*if_root == NULL && *if_default == NULL) {
970 SCLogError("unable to find configuration for the interface \"%s\" or the default "
971 "configuration (\"%s\")",
972 iface, default_iface);
973 return (-ENODEV);
974 }
975
976 /* If there is no setting for current interface use default one as main iface */
977 if (*if_root == NULL) {
978 *if_root = *if_default;
979 *if_default = NULL;
980 }
981 return 0;
982}
983
984#ifdef UNITTESTS
985
986/**
987 * Lookup a non-existant value.
988 */
989static int ConfTestGetNonExistant(void)
990{
991 char name[] = "non-existant-value";
992 const char *value;
993
994 FAIL_IF(SCConfGet(name, &value));
995 PASS;
996}
997
998/**
999 * Set then lookup a value.
1000 */
1001static int ConfTestSetAndGet(void)
1002{
1003 char name[] = "some-name";
1004 char value[] = "some-value";
1005 const char *value0 = NULL;
1006
1007 FAIL_IF(SCConfSet(name, value) != 1);
1008 FAIL_IF(SCConfGet(name, &value0) != 1);
1009 FAIL_IF(value0 == NULL);
1010 FAIL_IF(strcmp(value, value0) != 0);
1011
1012 /* Cleanup. */
1014
1015 PASS;
1016}
1017
1018/**
1019 * Test that overriding a value is allowed provided allow_override is
1020 * true and that the config parameter gets the new value.
1021 */
1022static int ConfTestOverrideValue1(void)
1023{
1024 char name[] = "some-name";
1025 char value0[] = "some-value";
1026 char value1[] = "new-value";
1027 const char *val = NULL;
1028
1029 FAIL_IF(SCConfSet(name, value0) != 1);
1030 FAIL_IF(SCConfSet(name, value1) != 1);
1031 FAIL_IF(SCConfGet(name, &val) != 1);
1032 FAIL_IF(val == NULL);
1033 FAIL_IF(strcmp(val, value1) != 0);
1034
1035 /* Cleanup. */
1037
1038 PASS;
1039}
1040
1041/**
1042 * Test that a final value will not be overridden by a ConfSet.
1043 */
1044static int ConfTestOverrideValue2(void)
1045{
1046 char name[] = "some-name";
1047 char value0[] = "some-value";
1048 char value1[] = "new-value";
1049 const char *val = NULL;
1050
1051 FAIL_IF(SCConfSetFinal(name, value0) != 1);
1052 FAIL_IF(SCConfSet(name, value1) != 0);
1053 FAIL_IF(SCConfGet(name, &val) != 1);
1054 FAIL_IF(val == NULL);
1055 FAIL_IF(strcmp(val, value0) != 0);
1056
1057 /* Cleanup. */
1059
1060 PASS;
1061}
1062
1063/**
1064 * Test retrieving an integer value from the configuration db.
1065 */
1066static int ConfTestGetInt(void)
1067{
1068 char name[] = "some-int.x";
1069 intmax_t val;
1070
1071 FAIL_IF(SCConfSet(name, "0") != 1);
1072 FAIL_IF(SCConfGetInt(name, &val) != 1);
1073 FAIL_IF(val != 0);
1074
1075 FAIL_IF(SCConfSet(name, "-1") != 1);
1076 FAIL_IF(SCConfGetInt(name, &val) != 1);
1077 FAIL_IF(val != -1);
1078
1079 FAIL_IF(SCConfSet(name, "0xffff") != 1);
1080 FAIL_IF(SCConfGetInt(name, &val) != 1);
1081 FAIL_IF(val != 0xffff);
1082
1083 FAIL_IF(SCConfSet(name, "not-an-int") != 1);
1084 FAIL_IF(SCConfGetInt(name, &val) != 0);
1085
1086 PASS;
1087}
1088
1089/**
1090 * Test retrieving a boolean value from the configuration db.
1091 */
1092static int ConfTestGetBool(void)
1093{
1094 char name[] = "some-bool";
1095 const char *trues[] = {
1096 "1",
1097 "on", "ON",
1098 "yes", "YeS",
1099 "true", "TRUE",
1100 };
1101 const char *falses[] = {
1102 "0",
1103 "something",
1104 "off", "OFF",
1105 "false", "FalSE",
1106 "no", "NO",
1107 };
1108 int val;
1109 size_t u;
1110
1111 for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) {
1112 FAIL_IF(SCConfSet(name, trues[u]) != 1);
1113 FAIL_IF(SCConfGetBool(name, &val) != 1);
1114 FAIL_IF(val != 1);
1115 }
1116
1117 for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) {
1118 FAIL_IF(SCConfSet(name, falses[u]) != 1);
1119 FAIL_IF(SCConfGetBool(name, &val) != 1);
1120 FAIL_IF(val != 0);
1121 }
1122
1123 PASS;
1124}
1125
1126static int ConfNodeLookupChildTest(void)
1127{
1128 const char *test_vals[] = { "one", "two", "three" };
1129 size_t u;
1130
1131 SCConfNode *parent = SCConfNodeNew();
1132 SCConfNode *child;
1133
1134 for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1135 child = SCConfNodeNew();
1136 child->name = SCStrdup(test_vals[u]);
1137 child->val = SCStrdup(test_vals[u]);
1138 TAILQ_INSERT_TAIL(&parent->head, child, next);
1139 }
1140
1141 child = SCConfNodeLookupChild(parent, "one");
1142 FAIL_IF(child == NULL);
1143 FAIL_IF(strcmp(child->name, "one") != 0);
1144 FAIL_IF(strcmp(child->val, "one") != 0);
1145
1146 child = SCConfNodeLookupChild(parent, "two");
1147 FAIL_IF(child == NULL);
1148 FAIL_IF(strcmp(child->name, "two") != 0);
1149 FAIL_IF(strcmp(child->val, "two") != 0);
1150
1151 child = SCConfNodeLookupChild(parent, "three");
1152 FAIL_IF(child == NULL);
1153 FAIL_IF(strcmp(child->name, "three") != 0);
1154 FAIL_IF(strcmp(child->val, "three") != 0);
1155
1156 child = SCConfNodeLookupChild(parent, "four");
1157 FAIL_IF(child != NULL);
1158
1159 FAIL_IF(SCConfNodeLookupChild(NULL, NULL) != NULL);
1160
1161 if (parent != NULL) {
1162 SCConfNodeFree(parent);
1163 }
1164
1165 PASS;
1166}
1167
1168static int ConfNodeLookupChildValueTest(void)
1169{
1170 const char *test_vals[] = { "one", "two", "three" };
1171 size_t u;
1172
1173 SCConfNode *parent = SCConfNodeNew();
1174 SCConfNode *child;
1175 const char *value;
1176
1177 for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1178 child = SCConfNodeNew();
1179 child->name = SCStrdup(test_vals[u]);
1180 child->val = SCStrdup(test_vals[u]);
1181 TAILQ_INSERT_TAIL(&parent->head, child, next);
1182 }
1183
1184 value = (char *)SCConfNodeLookupChildValue(parent, "one");
1185 FAIL_IF(value == NULL);
1186 FAIL_IF(strcmp(value, "one") != 0);
1187
1188 value = (char *)SCConfNodeLookupChildValue(parent, "two");
1189 FAIL_IF(value == NULL);
1190 FAIL_IF(strcmp(value, "two") != 0);
1191
1192 value = (char *)SCConfNodeLookupChildValue(parent, "three");
1193 FAIL_IF(value == NULL);
1194 FAIL_IF(strcmp(value, "three") != 0);
1195
1196 value = (char *)SCConfNodeLookupChildValue(parent, "four");
1197 FAIL_IF(value != NULL);
1198
1199 SCConfNodeFree(parent);
1200
1201 PASS;
1202}
1203
1204static int ConfGetChildValueWithDefaultTest(void)
1205{
1206 const char *val = "";
1208 SCConfInit();
1209 SCConfSet("af-packet.0.interface", "eth0");
1210 SCConfSet("af-packet.1.interface", "default");
1211 SCConfSet("af-packet.1.cluster-type", "cluster_cpu");
1212
1213 SCConfNode *myroot = SCConfGetNode("af-packet.0");
1214 SCConfNode *dflt = SCConfGetNode("af-packet.1");
1215 SCConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1216 FAIL_IF(strcmp(val, "cluster_cpu"));
1217
1218 SCConfSet("af-packet.0.cluster-type", "cluster_flow");
1219 SCConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1220
1221 FAIL_IF(strcmp(val, "cluster_flow"));
1222
1223 SCConfDeInit();
1225 PASS;
1226}
1227
1228static int ConfGetChildValueIntWithDefaultTest(void)
1229{
1230 intmax_t val = 0;
1232 SCConfInit();
1233 SCConfSet("af-packet.0.interface", "eth0");
1234 SCConfSet("af-packet.1.interface", "default");
1235 SCConfSet("af-packet.1.threads", "2");
1236
1237 SCConfNode *myroot = SCConfGetNode("af-packet.0");
1238 SCConfNode *dflt = SCConfGetNode("af-packet.1");
1239 SCConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1240 FAIL_IF(val != 2);
1241
1242 SCConfSet("af-packet.0.threads", "1");
1243 SCConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1244 FAIL_IF(val != 1);
1245
1246 SCConfDeInit();
1248
1249 PASS;
1250}
1251
1252static int ConfGetChildValueBoolWithDefaultTest(void)
1253{
1254 int val;
1256 SCConfInit();
1257 SCConfSet("af-packet.0.interface", "eth0");
1258 SCConfSet("af-packet.1.interface", "default");
1259 SCConfSet("af-packet.1.use-mmap", "yes");
1260
1261 SCConfNode *myroot = SCConfGetNode("af-packet.0");
1262 SCConfNode *dflt = SCConfGetNode("af-packet.1");
1263 SCConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1264 FAIL_IF(val == 0);
1265
1266 SCConfSet("af-packet.0.use-mmap", "no");
1267 SCConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1268 FAIL_IF(val);
1269
1270 SCConfDeInit();
1272
1273 PASS;
1274}
1275
1276/**
1277 * Test the removal of a configuration node.
1278 */
1279static int ConfNodeRemoveTest(void)
1280{
1282 SCConfInit();
1283
1284 FAIL_IF(SCConfSet("some.nested.parameter", "blah") != 1);
1285
1286 SCConfNode *node = SCConfGetNode("some.nested.parameter");
1287 FAIL_IF(node == NULL);
1288 SCConfNodeRemove(node);
1289
1290 node = SCConfGetNode("some.nested.parameter");
1291 FAIL_IF(node != NULL);
1292
1293 SCConfDeInit();
1295
1296 PASS;
1297}
1298
1299static int ConfSetTest(void)
1300{
1302 SCConfInit();
1303
1304 /* Set some value with 2 levels. */
1305 FAIL_IF(SCConfSet("one.two", "three") != 1);
1306 SCConfNode *n = SCConfGetNode("one.two");
1307 FAIL_IF(n == NULL);
1308
1309 /* Set another 2 level parameter with the same first level, this
1310 * used to trigger a bug that caused the second level of the name
1311 * to become a first level node. */
1312 FAIL_IF(SCConfSet("one.three", "four") != 1);
1313
1314 n = SCConfGetNode("one.three");
1315 FAIL_IF(n == NULL);
1316
1317 /* A top level node of "three" should not exist. */
1318 n = SCConfGetNode("three");
1319 FAIL_IF(n != NULL);
1320
1321 SCConfDeInit();
1323
1324 PASS;
1325}
1326
1327static int ConfGetNodeOrCreateTest(void)
1328{
1329 SCConfNode *node;
1330
1332 SCConfInit();
1333
1334 /* Get a node that should not exist, give it a value, re-get it
1335 * and make sure the second time it returns the existing node. */
1336 node = SCConfGetNodeOrCreate("node0", 0);
1337 FAIL_IF(node == NULL);
1338 FAIL_IF(node->parent == NULL || node->parent != root);
1339 FAIL_IF(node->val != NULL);
1340 node->val = SCStrdup("node0");
1341 node = SCConfGetNodeOrCreate("node0", 0);
1342 FAIL_IF(node == NULL);
1343 FAIL_IF(node->val == NULL);
1344 FAIL_IF(strcmp(node->val, "node0") != 0);
1345
1346 /* Do the same, but for something deeply nested. */
1347 node = SCConfGetNodeOrCreate("parent.child.grandchild", 0);
1348 FAIL_IF(node == NULL);
1349 FAIL_IF(node->parent == NULL || node->parent == root);
1350 FAIL_IF(node->val != NULL);
1351 node->val = SCStrdup("parent.child.grandchild");
1352 node = SCConfGetNodeOrCreate("parent.child.grandchild", 0);
1353 FAIL_IF(node == NULL);
1354 FAIL_IF(node->val == NULL);
1355 FAIL_IF(strcmp(node->val, "parent.child.grandchild") != 0);
1356
1357 /* Test that 2 child nodes have the same root. */
1358 SCConfNode *child1 = SCConfGetNodeOrCreate("parent.kids.child1", 0);
1359 SCConfNode *child2 = SCConfGetNodeOrCreate("parent.kids.child2", 0);
1360 FAIL_IF(child1 == NULL || child2 == NULL);
1361 FAIL_IF(child1->parent != child2->parent);
1362 FAIL_IF(strcmp(child1->parent->name, "kids") != 0);
1363
1364 SCConfDeInit();
1366
1367 PASS;
1368}
1369
1370static int ConfNodePruneTest(void)
1371{
1372 SCConfNode *node;
1373
1375 SCConfInit();
1376
1377 /* Test that final nodes exist after a prune. */
1378 FAIL_IF(SCConfSet("node.notfinal", "notfinal") != 1);
1379 FAIL_IF(SCConfSetFinal("node.final", "final") != 1);
1380 FAIL_IF(SCConfGetNode("node.notfinal") == NULL);
1381 FAIL_IF(SCConfGetNode("node.final") == NULL);
1382 FAIL_IF((node = SCConfGetNode("node")) == NULL);
1383 SCConfNodePrune(node);
1384 FAIL_IF(SCConfGetNode("node.notfinal") != NULL);
1385 FAIL_IF(SCConfGetNode("node.final") == NULL);
1386
1387 /* Test that everything under a final node exists after a prune. */
1388 FAIL_IF(SCConfSet("node.final.one", "one") != 1);
1389 FAIL_IF(SCConfSet("node.final.two", "two") != 1);
1390 SCConfNodePrune(node);
1391 FAIL_IF(SCConfNodeLookupChild(node, "final") == NULL);
1392 FAIL_IF(SCConfGetNode("node.final.one") == NULL);
1393 FAIL_IF(SCConfGetNode("node.final.two") == NULL);
1394
1395 SCConfDeInit();
1397
1398 PASS;
1399}
1400
1401static int ConfNodeIsSequenceTest(void)
1402{
1403 SCConfNode *node = SCConfNodeNew();
1404 FAIL_IF(node == NULL);
1406 node->is_seq = 1;
1408
1409 if (node != NULL) {
1410 SCConfNodeFree(node);
1411 }
1412 PASS;
1413}
1414
1415static int ConfSetFromStringTest(void)
1416{
1417 SCConfNode *n;
1418
1420 SCConfInit();
1421
1422 FAIL_IF_NOT(SCConfSetFromString("stream.midstream=true", 0));
1423 n = SCConfGetNode("stream.midstream");
1424 FAIL_IF_NULL(n);
1425 FAIL_IF_NULL(n->val);
1426 FAIL_IF(strcmp("true", n->val));
1427
1428 FAIL_IF_NOT(SCConfSetFromString("stream.midstream =false", 0));
1429 n = SCConfGetNode("stream.midstream");
1430 FAIL_IF_NULL(n);
1431 FAIL_IF(n->val == NULL || strcmp("false", n->val));
1432
1433 FAIL_IF_NOT(SCConfSetFromString("stream.midstream= true", 0));
1434 n = SCConfGetNode("stream.midstream");
1435 FAIL_IF_NULL(n);
1436 FAIL_IF(n->val == NULL || strcmp("true", n->val));
1437
1438 FAIL_IF_NOT(SCConfSetFromString("stream.midstream = false", 0));
1439 n = SCConfGetNode("stream.midstream");
1440 FAIL_IF_NULL(n);
1441 FAIL_IF(n->val == NULL || strcmp("false", n->val));
1442
1443 SCConfDeInit();
1445 PASS;
1446}
1447
1448static int ConfNodeHasChildrenTest(void)
1449{
1451 SCConfInit();
1452
1453 /* Set a plain key with value. */
1454 SCConfSet("no-children", "value");
1455 SCConfNode *n = SCConfGetNode("no-children");
1456 FAIL_IF_NULL(n);
1458
1459 /* Set a key with a sub key to a value. This makes the first key a
1460 * map. */
1461 SCConfSet("parent.child", "value");
1462 n = SCConfGetNode("parent");
1463 FAIL_IF_NULL(n);
1465
1466 SCConfDeInit();
1468 PASS;
1469}
1470
1472{
1473 UtRegisterTest("ConfTestGetNonExistant", ConfTestGetNonExistant);
1474 UtRegisterTest("ConfSetTest", ConfSetTest);
1475 UtRegisterTest("ConfTestSetAndGet", ConfTestSetAndGet);
1476 UtRegisterTest("ConfTestOverrideValue1", ConfTestOverrideValue1);
1477 UtRegisterTest("ConfTestOverrideValue2", ConfTestOverrideValue2);
1478 UtRegisterTest("ConfTestGetInt", ConfTestGetInt);
1479 UtRegisterTest("ConfTestGetBool", ConfTestGetBool);
1480 UtRegisterTest("ConfNodeLookupChildTest", ConfNodeLookupChildTest);
1481 UtRegisterTest("ConfNodeLookupChildValueTest",
1482 ConfNodeLookupChildValueTest);
1483 UtRegisterTest("ConfNodeRemoveTest", ConfNodeRemoveTest);
1484 UtRegisterTest("ConfGetChildValueWithDefaultTest",
1485 ConfGetChildValueWithDefaultTest);
1486 UtRegisterTest("ConfGetChildValueIntWithDefaultTest",
1487 ConfGetChildValueIntWithDefaultTest);
1488 UtRegisterTest("ConfGetChildValueBoolWithDefaultTest",
1489 ConfGetChildValueBoolWithDefaultTest);
1490 UtRegisterTest("ConfGetNodeOrCreateTest", ConfGetNodeOrCreateTest);
1491 UtRegisterTest("ConfNodePruneTest", ConfNodePruneTest);
1492 UtRegisterTest("ConfNodeIsSequenceTest", ConfNodeIsSequenceTest);
1493 UtRegisterTest("ConfSetFromStringTest", ConfSetFromStringTest);
1494 UtRegisterTest("ConfNodeHasChildrenTest", ConfNodeHasChildrenTest);
1495}
1496
1497#endif /* UNITTESTS */
struct HtpBodyChunk_ * next
SCConfNode * SCConfNodeLookupChild(const SCConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition conf.c:796
void SCConfInit(void)
Initialize the configuration system.
Definition conf.c:120
bool SCConfNodeHasChildren(const SCConfNode *node)
Check if a node has any children.
Definition conf.c:777
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
Definition conf.c:181
int SCConfNodeChildValueIsTrue(const SCConfNode *node, const char *key)
Test if a configuration node has a true value.
Definition conf.c:868
int SCConfSetRootAndDefaultNodes(const char *ifaces_node_name, const char *iface, SCConfNode **if_root, SCConfNode **if_default)
Finds and sets root and default node of the interface.
Definition conf.c:962
void SCConfRegisterTests(void)
Definition conf.c:1471
SCConfNode * SCConfGetChildWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name)
Definition conf.c:379
SCConfNode * SCConfGetFirstNode(const SCConfNode *parent)
Definition conf.c:204
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition conf.c:551
void SCConfDeInit(void)
De-initializes the configuration system.
Definition conf.c:703
SCConfNode * SCConfGetNextNode(const SCConfNode *node)
Definition conf.c:209
void SCConfDump(void)
Dump configuration to stdout.
Definition conf.c:761
int SCConfGetChildValueWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, const char **vptr)
Definition conf.c:393
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition conf.c:414
int SCConfNodeIsSequence(const SCConfNode *node)
Check if a node is a sequence or node.
Definition conf.c:925
int SCConfRemove(const char *name)
Remove a configuration parameter from the configuration db.
Definition conf.c:668
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition conf.c:318
int SCConfGetFloat(const char *name, float *val)
Retrieve a configuration value as a float.
Definition conf.c:630
int SCConfGetChildValueInt(const SCConfNode *base, const char *name, intmax_t *val)
Definition conf.c:449
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition conf.c:497
int SCConfGetChildValueBool(const SCConfNode *base, const char *name, int *val)
Definition conf.c:515
SCConfNode * SCConfSetIfaceNode(const char *ifaces_node_name, const char *iface)
Finds an interface from the list of interfaces.
Definition conf.c:936
#define NODE_NAME_MAX
Definition conf.c:47
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition conf.c:824
int SCConfSet(const char *name, const char *val)
Set a configuration value.
Definition conf.c:239
void SCConfNodeRemove(SCConfNode *node)
Remove (and SCFree) the provided configuration node.
Definition conf.c:653
SCConfNode * SCConfGetRootNode(void)
Get the root configuration node.
Definition conf.c:222
SCConfNode * SCConfNodeLookupKeyValue(const SCConfNode *base, const char *key, const char *value)
Lookup for a key value under a specific node.
Definition conf.c:841
int SCConfSetFromString(const char *input, int final)
Set a configuration parameter from a string.
Definition conf.c:264
int SCConfValIsFalse(const char *val)
Check if a value is false.
Definition conf.c:576
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition conf.c:350
int SCConfGetChildValueBoolWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, int *val)
Definition conf.c:528
const char * SCConfGetValueNode(const SCConfNode *node)
Definition conf.c:214
void SCConfNodeDump(const SCConfNode *node, const char *prefix)
Dump a configuration node and all its children.
Definition conf.c:731
SCConfNode * SCConfNodeGetNodeOrCreate(SCConfNode *parent, const char *name, int final)
Helper function to get a node, creating it if it does not exist.
Definition conf.c:66
void SCConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition conf.c:684
int SCConfGetChildValueIntWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, intmax_t *val)
Definition conf.c:476
int SCConfGetDouble(const char *name, double *val)
Retrieve a configuration value as a double.
Definition conf.c:600
SCConfNode * SCConfNodeNew(void)
Allocate a new configuration node.
Definition conf.c:139
void SCConfNodePrune(SCConfNode *node)
Create the path for an include entry.
Definition conf.c:893
void SCConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition conf.c:694
void SCConfNodeFree(SCConfNode *node)
Free a SCConfNode and all of its children.
Definition conf.c:157
int SCConfGetChildValue(const SCConfNode *base, const char *name, const char **vptr)
Definition conf.c:363
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:252
#define TAILQ_INIT(head)
Definition queue.h:262
#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_NEXT(elm, field)
Definition queue.h:307
#define TAILQ_EMPTY(head)
Definition queue.h:248
int final
Definition conf.h:44
int is_seq
Definition conf.h:41
char * name
Definition conf.h:38
char * val
Definition conf.h:39
struct SCConfNode_ * parent
Definition conf.h:46
size_t strlcat(char *, const char *src, size_t siz)
size_t strlcpy(char *dst, const char *src, size_t siz)
const char * name
SCConfNode * ConfFindDeviceConfig(SCConfNode *node, const char *iface)
Find the configuration node for a specific device.
Definition util-conf.c:121
#define FatalError(...)
Definition util-debug.h:510
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition util-debug.h:243
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#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
#define unlikely(expr)