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