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 char *ConfLoadCompleteIncludePath(const char *file)
874 {
875  const char *defaultpath = NULL;
876  char *path = NULL;
877 
878  /* Path not specified */
879  if (PathIsRelative(file)) {
880  if (ConfGet("include-path", &defaultpath) == 1) {
881  SCLogDebug("Default path: %s", defaultpath);
882  size_t path_len = sizeof(char) * (strlen(defaultpath) +
883  strlen(file) + 2);
884  path = SCMalloc(path_len);
885  if (unlikely(path == NULL))
886  return NULL;
887  strlcpy(path, defaultpath, path_len);
888  if (path[strlen(path) - 1] != '/')
889  strlcat(path, "/", path_len);
890  strlcat(path, file, path_len);
891  } else {
892  path = SCStrdup(file);
893  if (unlikely(path == NULL))
894  return NULL;
895  }
896  } else {
897  path = SCStrdup(file);
898  if (unlikely(path == NULL))
899  return NULL;
900  }
901  return path;
902 }
903 
904 /**
905  * \brief Prune a configuration node.
906  *
907  * Pruning a configuration is similar to freeing, but only fields that
908  * may be overridden are, leaving final type parameters. Additional
909  * the value of the provided node is also free'd, but the node itself
910  * is left.
911  *
912  * \param node The configuration node to prune.
913  */
915 {
916  ConfNode *item, *it;
917 
918  for (item = TAILQ_FIRST(&node->head); item != NULL; item = it) {
919  it = TAILQ_NEXT(item, next);
920  if (!item->final) {
921  ConfNodePrune(item);
922  if (TAILQ_EMPTY(&item->head)) {
923  TAILQ_REMOVE(&node->head, item, next);
924  if (item->name != NULL)
925  SCFree(item->name);
926  if (item->val != NULL)
927  SCFree(item->val);
928  SCFree(item);
929  }
930  }
931  }
932 
933  if (node->val != NULL) {
934  SCFree(node->val);
935  node->val = NULL;
936  }
937 }
938 
939 /**
940  * \brief Check if a node is a sequence or node.
941  *
942  * \param node the node to check.
943  *
944  * \return 1 if node is a sequence, otherwise 0.
945  */
946 int ConfNodeIsSequence(const ConfNode *node)
947 {
948  return node->is_seq == 0 ? 0 : 1;
949 }
950 
951 /**
952  * @brief Finds an interface from the list of interfaces.
953  * @param ifaces_node_name - name of the node which holds a list of interfaces
954  * @param iface - interfaces name
955  * @return NULL on failure otherwise a valid pointer
956  */
957 ConfNode *ConfSetIfaceNode(const char *ifaces_node_name, const char *iface)
958 {
959  ConfNode *if_node;
960  ConfNode *ifaces_list_node;
961  /* Find initial node which holds all interfaces */
962  ifaces_list_node = ConfGetNode(ifaces_node_name);
963  if (ifaces_list_node == NULL) {
964  SCLogError("unable to find %s config", ifaces_node_name);
965  return NULL;
966  }
967 
968  if_node = ConfFindDeviceConfig(ifaces_list_node, iface);
969  if (if_node == NULL)
970  SCLogNotice("unable to find interface %s in DPDK config", iface);
971 
972  return if_node;
973 }
974 
975 /**
976  * @brief Finds and sets root and default node of the interface.
977  * @param ifaces_node_name Node which holds list of interfaces
978  * @param iface Name of the interface e.g. eth3
979  * @param if_root Node which will hold the interface configuration
980  * @param if_default Node which is the default configuration in the given list of interfaces
981  * @return 0 on success, -ENODEV when neither the root interface nor the default interface was found
982  */
984  const char *ifaces_node_name, const char *iface, ConfNode **if_root, ConfNode **if_default)
985 {
986  const char *default_iface = "default";
987  *if_root = ConfSetIfaceNode(ifaces_node_name, iface);
988  *if_default = ConfSetIfaceNode(ifaces_node_name, default_iface);
989 
990  if (*if_root == NULL && *if_default == NULL) {
991  SCLogError("unable to find configuration for the interface \"%s\" or the default "
992  "configuration (\"%s\")",
993  iface, default_iface);
994  return (-ENODEV);
995  }
996 
997  /* If there is no setting for current interface use default one as main iface */
998  if (*if_root == NULL) {
999  *if_root = *if_default;
1000  *if_default = NULL;
1001  }
1002  return 0;
1003 }
1004 
1005 #ifdef UNITTESTS
1006 
1007 /**
1008  * Lookup a non-existant value.
1009  */
1010 static int ConfTestGetNonExistant(void)
1011 {
1012  char name[] = "non-existant-value";
1013  const char *value;
1014 
1015  FAIL_IF(ConfGet(name, &value));
1016  PASS;
1017 }
1018 
1019 /**
1020  * Set then lookup a value.
1021  */
1022 static int ConfTestSetAndGet(void)
1023 {
1024  char name[] = "some-name";
1025  char value[] = "some-value";
1026  const char *value0 = NULL;
1027 
1028  FAIL_IF(ConfSet(name, value) != 1);
1029  FAIL_IF(ConfGet(name, &value0) != 1);
1030  FAIL_IF(value0 == NULL);
1031  FAIL_IF(strcmp(value, value0) != 0);
1032 
1033  /* Cleanup. */
1034  ConfRemove(name);
1035 
1036  PASS;
1037 }
1038 
1039 /**
1040  * Test that overriding a value is allowed provided allow_override is
1041  * true and that the config parameter gets the new value.
1042  */
1043 static int ConfTestOverrideValue1(void)
1044 {
1045  char name[] = "some-name";
1046  char value0[] = "some-value";
1047  char value1[] = "new-value";
1048  const char *val = NULL;
1049 
1050  FAIL_IF(ConfSet(name, value0) != 1);
1051  FAIL_IF(ConfSet(name, value1) != 1);
1052  FAIL_IF(ConfGet(name, &val) != 1);
1053  FAIL_IF(val == NULL);
1054  FAIL_IF(strcmp(val, value1) != 0);
1055 
1056  /* Cleanup. */
1057  ConfRemove(name);
1058 
1059  PASS;
1060 }
1061 
1062 /**
1063  * Test that a final value will not be overridden by a ConfSet.
1064  */
1065 static int ConfTestOverrideValue2(void)
1066 {
1067  char name[] = "some-name";
1068  char value0[] = "some-value";
1069  char value1[] = "new-value";
1070  const char *val = NULL;
1071 
1072  FAIL_IF(ConfSetFinal(name, value0) != 1);
1073  FAIL_IF(ConfSet(name, value1) != 0);
1074  FAIL_IF(ConfGet(name, &val) != 1);
1075  FAIL_IF(val == NULL);
1076  FAIL_IF(strcmp(val, value0) != 0);
1077 
1078  /* Cleanup. */
1079  ConfRemove(name);
1080 
1081  PASS;
1082 }
1083 
1084 /**
1085  * Test retrieving an integer value from the configuration db.
1086  */
1087 static int ConfTestGetInt(void)
1088 {
1089  char name[] = "some-int.x";
1090  intmax_t val;
1091 
1092  FAIL_IF(ConfSet(name, "0") != 1);
1093  FAIL_IF(ConfGetInt(name, &val) != 1);
1094  FAIL_IF(val != 0);
1095 
1096  FAIL_IF(ConfSet(name, "-1") != 1);
1097  FAIL_IF(ConfGetInt(name, &val) != 1);
1098  FAIL_IF(val != -1);
1099 
1100  FAIL_IF(ConfSet(name, "0xffff") != 1);
1101  FAIL_IF(ConfGetInt(name, &val) != 1);
1102  FAIL_IF(val != 0xffff);
1103 
1104  FAIL_IF(ConfSet(name, "not-an-int") != 1);
1105  FAIL_IF(ConfGetInt(name, &val) != 0);
1106 
1107  PASS;
1108 }
1109 
1110 /**
1111  * Test retrieving a boolean value from the configuration db.
1112  */
1113 static int ConfTestGetBool(void)
1114 {
1115  char name[] = "some-bool";
1116  const char *trues[] = {
1117  "1",
1118  "on", "ON",
1119  "yes", "YeS",
1120  "true", "TRUE",
1121  };
1122  const char *falses[] = {
1123  "0",
1124  "something",
1125  "off", "OFF",
1126  "false", "FalSE",
1127  "no", "NO",
1128  };
1129  int val;
1130  size_t u;
1131 
1132  for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) {
1133  FAIL_IF(ConfSet(name, trues[u]) != 1);
1134  FAIL_IF(ConfGetBool(name, &val) != 1);
1135  FAIL_IF(val != 1);
1136  }
1137 
1138  for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) {
1139  FAIL_IF(ConfSet(name, falses[u]) != 1);
1140  FAIL_IF(ConfGetBool(name, &val) != 1);
1141  FAIL_IF(val != 0);
1142  }
1143 
1144  PASS;
1145 }
1146 
1147 static int ConfNodeLookupChildTest(void)
1148 {
1149  const char *test_vals[] = { "one", "two", "three" };
1150  size_t u;
1151 
1152  ConfNode *parent = ConfNodeNew();
1153  ConfNode *child;
1154 
1155  for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1156  child = ConfNodeNew();
1157  child->name = SCStrdup(test_vals[u]);
1158  child->val = SCStrdup(test_vals[u]);
1159  TAILQ_INSERT_TAIL(&parent->head, child, next);
1160  }
1161 
1162  child = ConfNodeLookupChild(parent, "one");
1163  FAIL_IF(child == NULL);
1164  FAIL_IF(strcmp(child->name, "one") != 0);
1165  FAIL_IF(strcmp(child->val, "one") != 0);
1166 
1167  child = ConfNodeLookupChild(parent, "two");
1168  FAIL_IF(child == NULL);
1169  FAIL_IF(strcmp(child->name, "two") != 0);
1170  FAIL_IF(strcmp(child->val, "two") != 0);
1171 
1172  child = ConfNodeLookupChild(parent, "three");
1173  FAIL_IF(child == NULL);
1174  FAIL_IF(strcmp(child->name, "three") != 0);
1175  FAIL_IF(strcmp(child->val, "three") != 0);
1176 
1177  child = ConfNodeLookupChild(parent, "four");
1178  FAIL_IF(child != NULL);
1179 
1180  FAIL_IF(ConfNodeLookupChild(NULL, NULL) != NULL);
1181 
1182  if (parent != NULL) {
1183  ConfNodeFree(parent);
1184  }
1185 
1186  PASS;
1187 }
1188 
1189 static int ConfNodeLookupChildValueTest(void)
1190 {
1191  const char *test_vals[] = { "one", "two", "three" };
1192  size_t u;
1193 
1194  ConfNode *parent = ConfNodeNew();
1195  ConfNode *child;
1196  const char *value;
1197 
1198  for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1199  child = ConfNodeNew();
1200  child->name = SCStrdup(test_vals[u]);
1201  child->val = SCStrdup(test_vals[u]);
1202  TAILQ_INSERT_TAIL(&parent->head, child, next);
1203  }
1204 
1205  value = (char *)ConfNodeLookupChildValue(parent, "one");
1206  FAIL_IF(value == NULL);
1207  FAIL_IF(strcmp(value, "one") != 0);
1208 
1209  value = (char *)ConfNodeLookupChildValue(parent, "two");
1210  FAIL_IF(value == NULL);
1211  FAIL_IF(strcmp(value, "two") != 0);
1212 
1213  value = (char *)ConfNodeLookupChildValue(parent, "three");
1214  FAIL_IF(value == NULL);
1215  FAIL_IF(strcmp(value, "three") != 0);
1216 
1217  value = (char *)ConfNodeLookupChildValue(parent, "four");
1218  FAIL_IF(value != NULL);
1219 
1220  ConfNodeFree(parent);
1221 
1222  PASS;
1223 }
1224 
1225 static int ConfGetChildValueWithDefaultTest(void)
1226 {
1227  const char *val = "";
1229  ConfInit();
1230  ConfSet("af-packet.0.interface", "eth0");
1231  ConfSet("af-packet.1.interface", "default");
1232  ConfSet("af-packet.1.cluster-type", "cluster_cpu");
1233 
1234  ConfNode *myroot = ConfGetNode("af-packet.0");
1235  ConfNode *dflt = ConfGetNode("af-packet.1");
1236  ConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1237  FAIL_IF(strcmp(val, "cluster_cpu"));
1238 
1239  ConfSet("af-packet.0.cluster-type", "cluster_flow");
1240  ConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1241 
1242  FAIL_IF(strcmp(val, "cluster_flow"));
1243 
1244  ConfDeInit();
1246  PASS;
1247 }
1248 
1249 static int ConfGetChildValueIntWithDefaultTest(void)
1250 {
1251  intmax_t val = 0;
1253  ConfInit();
1254  ConfSet("af-packet.0.interface", "eth0");
1255  ConfSet("af-packet.1.interface", "default");
1256  ConfSet("af-packet.1.threads", "2");
1257 
1258  ConfNode *myroot = ConfGetNode("af-packet.0");
1259  ConfNode *dflt = ConfGetNode("af-packet.1");
1260  ConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1261  FAIL_IF(val != 2);
1262 
1263  ConfSet("af-packet.0.threads", "1");
1264  ConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1265  FAIL_IF(val != 1);
1266 
1267  ConfDeInit();
1269 
1270  PASS;
1271 }
1272 
1273 static int ConfGetChildValueBoolWithDefaultTest(void)
1274 {
1275  int val;
1277  ConfInit();
1278  ConfSet("af-packet.0.interface", "eth0");
1279  ConfSet("af-packet.1.interface", "default");
1280  ConfSet("af-packet.1.use-mmap", "yes");
1281 
1282  ConfNode *myroot = ConfGetNode("af-packet.0");
1283  ConfNode *dflt = ConfGetNode("af-packet.1");
1284  ConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1285  FAIL_IF(val == 0);
1286 
1287  ConfSet("af-packet.0.use-mmap", "no");
1288  ConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1289  FAIL_IF(val);
1290 
1291  ConfDeInit();
1293 
1294  PASS;
1295 }
1296 
1297 /**
1298  * Test the removal of a configuration node.
1299  */
1300 static int ConfNodeRemoveTest(void)
1301 {
1303  ConfInit();
1304 
1305  FAIL_IF(ConfSet("some.nested.parameter", "blah") != 1);
1306 
1307  ConfNode *node = ConfGetNode("some.nested.parameter");
1308  FAIL_IF(node == NULL);
1309  ConfNodeRemove(node);
1310 
1311  node = ConfGetNode("some.nested.parameter");
1312  FAIL_IF(node != NULL);
1313 
1314  ConfDeInit();
1316 
1317  PASS;
1318 }
1319 
1320 static int ConfSetTest(void)
1321 {
1323  ConfInit();
1324 
1325  /* Set some value with 2 levels. */
1326  FAIL_IF(ConfSet("one.two", "three") != 1);
1327  ConfNode *n = ConfGetNode("one.two");
1328  FAIL_IF(n == NULL);
1329 
1330  /* Set another 2 level parameter with the same first level, this
1331  * used to trigger a bug that caused the second level of the name
1332  * to become a first level node. */
1333  FAIL_IF(ConfSet("one.three", "four") != 1);
1334 
1335  n = ConfGetNode("one.three");
1336  FAIL_IF(n == NULL);
1337 
1338  /* A top level node of "three" should not exist. */
1339  n = ConfGetNode("three");
1340  FAIL_IF(n != NULL);
1341 
1342  ConfDeInit();
1344 
1345  PASS;
1346 }
1347 
1348 static int ConfGetNodeOrCreateTest(void)
1349 {
1350  ConfNode *node;
1351 
1353  ConfInit();
1354 
1355  /* Get a node that should not exist, give it a value, re-get it
1356  * and make sure the second time it returns the existing node. */
1357  node = ConfGetNodeOrCreate("node0", 0);
1358  FAIL_IF(node == NULL);
1359  FAIL_IF(node->parent == NULL || node->parent != root);
1360  FAIL_IF(node->val != NULL);
1361  node->val = SCStrdup("node0");
1362  node = ConfGetNodeOrCreate("node0", 0);
1363  FAIL_IF(node == NULL);
1364  FAIL_IF(node->val == NULL);
1365  FAIL_IF(strcmp(node->val, "node0") != 0);
1366 
1367  /* Do the same, but for something deeply nested. */
1368  node = ConfGetNodeOrCreate("parent.child.grandchild", 0);
1369  FAIL_IF(node == NULL);
1370  FAIL_IF(node->parent == NULL || node->parent == root);
1371  FAIL_IF(node->val != NULL);
1372  node->val = SCStrdup("parent.child.grandchild");
1373  node = ConfGetNodeOrCreate("parent.child.grandchild", 0);
1374  FAIL_IF(node == NULL);
1375  FAIL_IF(node->val == NULL);
1376  FAIL_IF(strcmp(node->val, "parent.child.grandchild") != 0);
1377 
1378  /* Test that 2 child nodes have the same root. */
1379  ConfNode *child1 = ConfGetNodeOrCreate("parent.kids.child1", 0);
1380  ConfNode *child2 = ConfGetNodeOrCreate("parent.kids.child2", 0);
1381  FAIL_IF(child1 == NULL || child2 == NULL);
1382  FAIL_IF(child1->parent != child2->parent);
1383  FAIL_IF(strcmp(child1->parent->name, "kids") != 0);
1384 
1385  ConfDeInit();
1387 
1388  PASS;
1389 }
1390 
1391 static int ConfNodePruneTest(void)
1392 {
1393  ConfNode *node;
1394 
1396  ConfInit();
1397 
1398  /* Test that final nodes exist after a prune. */
1399  FAIL_IF(ConfSet("node.notfinal", "notfinal") != 1);
1400  FAIL_IF(ConfSetFinal("node.final", "final") != 1);
1401  FAIL_IF(ConfGetNode("node.notfinal") == NULL);
1402  FAIL_IF(ConfGetNode("node.final") == NULL);
1403  FAIL_IF((node = ConfGetNode("node")) == NULL);
1404  ConfNodePrune(node);
1405  FAIL_IF(ConfGetNode("node.notfinal") != NULL);
1406  FAIL_IF(ConfGetNode("node.final") == NULL);
1407 
1408  /* Test that everything under a final node exists after a prune. */
1409  FAIL_IF(ConfSet("node.final.one", "one") != 1);
1410  FAIL_IF(ConfSet("node.final.two", "two") != 1);
1411  ConfNodePrune(node);
1412  FAIL_IF(ConfNodeLookupChild(node, "final") == NULL);
1413  FAIL_IF(ConfGetNode("node.final.one") == NULL);
1414  FAIL_IF(ConfGetNode("node.final.two") == NULL);
1415 
1416  ConfDeInit();
1418 
1419  PASS;
1420 }
1421 
1422 static int ConfNodeIsSequenceTest(void)
1423 {
1424  ConfNode *node = ConfNodeNew();
1425  FAIL_IF(node == NULL);
1426  FAIL_IF(ConfNodeIsSequence(node));
1427  node->is_seq = 1;
1428  FAIL_IF(!ConfNodeIsSequence(node));
1429 
1430  if (node != NULL) {
1431  ConfNodeFree(node);
1432  }
1433  PASS;
1434 }
1435 
1436 static int ConfSetFromStringTest(void)
1437 {
1438  ConfNode *n;
1439 
1441  ConfInit();
1442 
1443  FAIL_IF_NOT(ConfSetFromString("stream.midstream=true", 0));
1444  n = ConfGetNode("stream.midstream");
1445  FAIL_IF_NULL(n);
1446  FAIL_IF_NULL(n->val);
1447  FAIL_IF(strcmp("true", n->val));
1448 
1449  FAIL_IF_NOT(ConfSetFromString("stream.midstream =false", 0));
1450  n = ConfGetNode("stream.midstream");
1451  FAIL_IF_NULL(n);
1452  FAIL_IF(n->val == NULL || strcmp("false", n->val));
1453 
1454  FAIL_IF_NOT(ConfSetFromString("stream.midstream= true", 0));
1455  n = ConfGetNode("stream.midstream");
1456  FAIL_IF_NULL(n);
1457  FAIL_IF(n->val == NULL || strcmp("true", n->val));
1458 
1459  FAIL_IF_NOT(ConfSetFromString("stream.midstream = false", 0));
1460  n = ConfGetNode("stream.midstream");
1461  FAIL_IF_NULL(n);
1462  FAIL_IF(n->val == NULL || strcmp("false", n->val));
1463 
1464  ConfDeInit();
1466  PASS;
1467 }
1468 
1469 static int ConfNodeHasChildrenTest(void)
1470 {
1472  ConfInit();
1473 
1474  /* Set a plain key with value. */
1475  ConfSet("no-children", "value");
1476  ConfNode *n = ConfGetNode("no-children");
1477  FAIL_IF_NULL(n);
1479 
1480  /* Set a key with a sub key to a value. This makes the first key a
1481  * map. */
1482  ConfSet("parent.child", "value");
1483  n = ConfGetNode("parent");
1484  FAIL_IF_NULL(n);
1486 
1487  ConfDeInit();
1489  PASS;
1490 }
1491 
1493 {
1494  UtRegisterTest("ConfTestGetNonExistant", ConfTestGetNonExistant);
1495  UtRegisterTest("ConfSetTest", ConfSetTest);
1496  UtRegisterTest("ConfTestSetAndGet", ConfTestSetAndGet);
1497  UtRegisterTest("ConfTestOverrideValue1", ConfTestOverrideValue1);
1498  UtRegisterTest("ConfTestOverrideValue2", ConfTestOverrideValue2);
1499  UtRegisterTest("ConfTestGetInt", ConfTestGetInt);
1500  UtRegisterTest("ConfTestGetBool", ConfTestGetBool);
1501  UtRegisterTest("ConfNodeLookupChildTest", ConfNodeLookupChildTest);
1502  UtRegisterTest("ConfNodeLookupChildValueTest",
1503  ConfNodeLookupChildValueTest);
1504  UtRegisterTest("ConfNodeRemoveTest", ConfNodeRemoveTest);
1505  UtRegisterTest("ConfGetChildValueWithDefaultTest",
1506  ConfGetChildValueWithDefaultTest);
1507  UtRegisterTest("ConfGetChildValueIntWithDefaultTest",
1508  ConfGetChildValueIntWithDefaultTest);
1509  UtRegisterTest("ConfGetChildValueBoolWithDefaultTest",
1510  ConfGetChildValueBoolWithDefaultTest);
1511  UtRegisterTest("ConfGetNodeOrCreateTest", ConfGetNodeOrCreateTest);
1512  UtRegisterTest("ConfNodePruneTest", ConfNodePruneTest);
1513  UtRegisterTest("ConfNodeIsSequenceTest", ConfNodeIsSequenceTest);
1514  UtRegisterTest("ConfSetFromStringTest", ConfSetFromStringTest);
1515  UtRegisterTest("ConfNodeHasChildrenTest", ConfNodeHasChildrenTest);
1516 }
1517 
1518 #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)
Prune a configuration node.
Definition: conf.c:914
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:1492
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:946
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
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
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
PathIsRelative
int PathIsRelative(const char *path)
Check if a path is relative.
Definition: util-path.c:69
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:983
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:957
ConfLoadCompleteIncludePath
char * ConfLoadCompleteIncludePath(const char *file)
Create the path for an include entry.
Definition: conf.c:873
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