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