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 int ConfGetChildValueIntWithDefault(const ConfNode *base, const ConfNode *dflt,
462  const char *name, intmax_t *val)
463 {
464  int ret = ConfGetChildValueInt(base, name, val);
465  /* Get 'default' value */
466  if (ret == 0 && dflt) {
467  return ConfGetChildValueInt(dflt, name, val);
468  }
469  return ret;
470 }
471 
472 /**
473  * \brief Retrieve a configuration value as a boolean.
474  *
475  * \param name Name of configuration parameter to get.
476  * \param val Pointer to an int that will be set to 1 for true, or 0
477  * for false.
478  *
479  * \retval 1 will be returned if the name is found and was properly
480  * converted to a boolean, otherwise 0 will be returned.
481  */
482 int ConfGetBool(const char *name, int *val)
483 {
484  const char *strval = NULL;
485 
486  *val = 0;
487  if (ConfGet(name, &strval) != 1)
488  return 0;
489 
490  *val = ConfValIsTrue(strval);
491 
492  return 1;
493 }
494 
495 /**
496  * Get a boolean value from the provided ConfNode.
497  *
498  * \retval 1 If the value exists, 0 if not.
499  */
500 int ConfGetChildValueBool(const ConfNode *base, const char *name, int *val)
501 {
502  const char *strval = NULL;
503 
504  *val = 0;
505  if (ConfGetChildValue(base, name, &strval) == 0)
506  return 0;
507 
508  *val = ConfValIsTrue(strval);
509 
510  return 1;
511 }
512 
514  const char *name, int *val)
515 {
516  int ret = ConfGetChildValueBool(base, name, val);
517  /* Get 'default' value */
518  if (ret == 0 && dflt) {
519  return ConfGetChildValueBool(dflt, name, val);
520  }
521  return ret;
522 }
523 
524 
525 /**
526  * \brief Check if a value is true.
527  *
528  * The value is considered true if it is a string with the value of 1,
529  * yes, true or on. The test is not case sensitive, any other value
530  * is false.
531  *
532  * \param val The string to test for a true value.
533  *
534  * \retval 1 If the value is true, 0 if not.
535  */
536 int ConfValIsTrue(const char *val)
537 {
538  const char *trues[] = {"1", "yes", "true", "on"};
539  size_t u;
540 
541  for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) {
542  if (strcasecmp(val, trues[u]) == 0) {
543  return 1;
544  }
545  }
546 
547  return 0;
548 }
549 
550 /**
551  * \brief Check if a value is false.
552  *
553  * The value is considered false if it is a string with the value of 0,
554  * no, false or off. The test is not case sensitive, any other value
555  * is not false.
556  *
557  * \param val The string to test for a false value.
558  *
559  * \retval 1 If the value is false, 0 if not.
560  */
561 int ConfValIsFalse(const char *val)
562 {
563  const char *falses[] = {"0", "no", "false", "off"};
564  size_t u;
565 
566  for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) {
567  if (strcasecmp(val, falses[u]) == 0) {
568  return 1;
569  }
570  }
571 
572  return 0;
573 }
574 
575 /**
576  * \brief Retrieve a configuration value as a double
577  *
578  * \param name Name of configuration parameter to get.
579  * \param val Pointer to an double that will be set the
580  * configuration value.
581  *
582  * \retval 1 will be returned if the name is found and was properly
583  * converted to a double, otherwise 0 will be returned.
584  */
585 int ConfGetDouble(const char *name, double *val)
586 {
587  const char *strval = NULL;
588  double tmpdo;
589  char *endptr;
590 
591  if (ConfGet(name, &strval) == 0)
592  return 0;
593 
594  errno = 0;
595  tmpdo = strtod(strval, &endptr);
596  if (strval[0] == '\0' || *endptr != '\0')
597  return 0;
598  if (errno == ERANGE)
599  return 0;
600 
601  *val = tmpdo;
602  return 1;
603 }
604 
605 /**
606  * \brief Retrieve a configuration value as a float
607  *
608  * \param name Name of configuration parameter to get.
609  * \param val Pointer to an float that will be set the
610  * configuration value.
611  *
612  * \retval 1 will be returned if the name is found and was properly
613  * converted to a double, otherwise 0 will be returned.
614  */
615 int ConfGetFloat(const char *name, float *val)
616 {
617  const char *strval = NULL;
618  double tmpfl;
619  char *endptr;
620 
621  if (ConfGet(name, &strval) == 0)
622  return 0;
623 
624  errno = 0;
625  tmpfl = strtof(strval, &endptr);
626  if (strval[0] == '\0' || *endptr != '\0')
627  return 0;
628  if (errno == ERANGE)
629  return 0;
630 
631  *val = tmpfl;
632  return 1;
633 }
634 
635 /**
636  * \brief Remove (and SCFree) the provided configuration node.
637  */
639 {
640  if (node->parent != NULL)
641  TAILQ_REMOVE(&node->parent->head, node, next);
642  ConfNodeFree(node);
643 }
644 
645 /**
646  * \brief Remove a configuration parameter from the configuration db.
647  *
648  * \param name The name of the configuration parameter to remove.
649  *
650  * \retval Returns 1 if the parameter was removed, otherwise 0 is returned
651  * most likely indicating the parameter was not set.
652  */
653 int ConfRemove(const char *name)
654 {
655  ConfNode *node;
656 
657  node = ConfGetNode(name);
658  if (node == NULL)
659  return 0;
660  else {
661  ConfNodeRemove(node);
662  return 1;
663  }
664 }
665 
666 /**
667  * \brief Creates a backup of the conf_hash hash_table used by the conf API.
668  */
670 {
671  root_backup = root;
672  root = NULL;
673 }
674 
675 /**
676  * \brief Restores the backup of the hash_table present in backup_conf_hash
677  * back to conf_hash.
678  */
680 {
681  root = root_backup;
682  root_backup = NULL;
683 }
684 
685 /**
686  * \brief De-initializes the configuration system.
687  */
688 void ConfDeInit(void)
689 {
690  if (root != NULL) {
691  ConfNodeFree(root);
692  root = NULL;
693  }
694 
695  SCLogDebug("configuration module de-initialized");
696 }
697 
698 static char *ConfPrintNameArray(char **name_arr, int level)
699 {
700  static char name[128*128];
701  int i;
702 
703  name[0] = '\0';
704  for (i = 0; i <= level; i++) {
705  strlcat(name, name_arr[i], sizeof(name));
706  if (i < level)
707  strlcat(name, ".", sizeof(name));
708  }
709 
710  return name;
711 }
712 
713 /**
714  * \brief Dump a configuration node and all its children.
715  */
716 void ConfNodeDump(const ConfNode *node, const char *prefix)
717 {
718  ConfNode *child;
719 
720  static char *name[128];
721  static int level = -1;
722 
723  level++;
724  TAILQ_FOREACH(child, &node->head, next) {
725  name[level] = SCStrdup(child->name);
726  if (unlikely(name[level] == NULL)) {
727  continue;
728  }
729  if (prefix == NULL) {
730  printf("%s = %s\n", ConfPrintNameArray(name, level),
731  child->val);
732  }
733  else {
734  printf("%s.%s = %s\n", prefix,
735  ConfPrintNameArray(name, level), child->val);
736  }
737  ConfNodeDump(child, prefix);
738  SCFree(name[level]);
739  }
740  level--;
741 }
742 
743 /**
744  * \brief Dump configuration to stdout.
745  */
746 void ConfDump(void)
747 {
748  ConfNodeDump(root, NULL);
749 }
750 
751 /**
752  * \brief Check if a node has any children.
753  *
754  * Checks if the provided node has any children. Any node that is a
755  * YAML map or array will have children.
756  *
757  * \param node The node to check.
758  *
759  * \retval true if node has children
760  * \retval false if node does not have children
761  */
762 bool ConfNodeHasChildren(const ConfNode *node)
763 {
764  if (TAILQ_EMPTY(&node->head)) {
765  return false;
766  }
767  return true;
768 }
769 
770 /**
771  * \brief Lookup a child configuration node by name.
772  *
773  * Given a ConfNode this function will lookup an immediate child
774  * ConfNode by name and return the child ConfNode.
775  *
776  * \param node The parent configuration node.
777  * \param name The name of the child node to lookup.
778  *
779  * \retval A pointer the child ConfNode if found otherwise NULL.
780  */
781 ConfNode *ConfNodeLookupChild(const ConfNode *node, const char *name)
782 {
783  ConfNode *child;
784 
785  if (node == NULL || name == NULL) {
786  return NULL;
787  }
788 
789  TAILQ_FOREACH(child, &node->head, next) {
790  if (child->name != NULL && strcmp(child->name, name) == 0)
791  return child;
792  }
793 
794  return NULL;
795 }
796 
797 /**
798  * \brief Lookup the value of a child configuration node by name.
799  *
800  * Given a parent ConfNode this function will return the value of a
801  * child configuration node by name returning a reference to that
802  * value.
803  *
804  * \param node The parent configuration node.
805  * \param name The name of the child node to lookup.
806  *
807  * \retval A pointer the child ConfNodes value if found otherwise NULL.
808  */
809 const char *ConfNodeLookupChildValue(const ConfNode *node, const char *name)
810 {
811  ConfNode *child;
812 
813  child = ConfNodeLookupChild(node, name);
814  if (child != NULL)
815  return child->val;
816 
817  return NULL;
818 }
819 
820 /**
821  * \brief Lookup for a key value under a specific node
822  *
823  * \return the ConfNode matching or NULL
824  */
825 
826 ConfNode *ConfNodeLookupKeyValue(const ConfNode *base, const char *key,
827  const char *value)
828 {
829  ConfNode *child;
830 
831  TAILQ_FOREACH(child, &base->head, next) {
832  if (!strncmp(child->val, key, strlen(child->val))) {
833  ConfNode *subchild;
834  TAILQ_FOREACH(subchild, &child->head, next) {
835  if ((!strcmp(subchild->name, key)) && (!strcmp(subchild->val, value))) {
836  return child;
837  }
838  }
839  }
840  }
841 
842  return NULL;
843 }
844 
845 /**
846  * \brief Test if a configuration node has a true value.
847  *
848  * \param node The parent configuration node.
849  * \param name The name of the child node to test.
850  *
851  * \retval 1 if the child node has a true value, otherwise 0 is
852  * returned, even if the child node does not exist.
853  */
854 int ConfNodeChildValueIsTrue(const ConfNode *node, const char *key)
855 {
856  const char *val;
857 
858  val = ConfNodeLookupChildValue(node, key);
859 
860  return val != NULL ? ConfValIsTrue(val) : 0;
861 }
862 
863 /**
864  * \brief Create the path for an include entry
865  * \param file The name of the file
866  * \retval str Pointer to the string path + sig_file
867  */
868 
869 /**
870  * \brief Prune a configuration node.
871  *
872  * Pruning a configuration is similar to freeing, but only fields that
873  * may be overridden are, leaving final type parameters. Additional
874  * the value of the provided node is also free'd, but the node itself
875  * is left.
876  *
877  * \param node The configuration node to prune.
878  */
880 {
881  ConfNode *item, *it;
882 
883  for (item = TAILQ_FIRST(&node->head); item != NULL; item = it) {
884  it = TAILQ_NEXT(item, next);
885  if (!item->final) {
886  ConfNodePrune(item);
887  if (TAILQ_EMPTY(&item->head)) {
888  TAILQ_REMOVE(&node->head, item, next);
889  if (item->name != NULL)
890  SCFree(item->name);
891  if (item->val != NULL)
892  SCFree(item->val);
893  SCFree(item);
894  }
895  }
896  }
897 
898  if (node->val != NULL) {
899  SCFree(node->val);
900  node->val = NULL;
901  }
902 }
903 
904 /**
905  * \brief Check if a node is a sequence or node.
906  *
907  * \param node the node to check.
908  *
909  * \return 1 if node is a sequence, otherwise 0.
910  */
911 int ConfNodeIsSequence(const ConfNode *node)
912 {
913  return node->is_seq == 0 ? 0 : 1;
914 }
915 
916 /**
917  * @brief Finds an interface from the list of interfaces.
918  * @param ifaces_node_name - name of the node which holds a list of interfaces
919  * @param iface - interfaces name
920  * @return NULL on failure otherwise a valid pointer
921  */
922 ConfNode *ConfSetIfaceNode(const char *ifaces_node_name, const char *iface)
923 {
924  ConfNode *if_node;
925  ConfNode *ifaces_list_node;
926  /* Find initial node which holds all interfaces */
927  ifaces_list_node = ConfGetNode(ifaces_node_name);
928  if (ifaces_list_node == NULL) {
929  SCLogError("unable to find %s config", ifaces_node_name);
930  return NULL;
931  }
932 
933  if_node = ConfFindDeviceConfig(ifaces_list_node, iface);
934  if (if_node == NULL)
935  SCLogNotice("unable to find interface %s in DPDK config", iface);
936 
937  return if_node;
938 }
939 
940 /**
941  * @brief Finds and sets root and default node of the interface.
942  * @param ifaces_node_name Node which holds list of interfaces
943  * @param iface Name of the interface e.g. eth3
944  * @param if_root Node which will hold the interface configuration
945  * @param if_default Node which is the default configuration in the given list of interfaces
946  * @return 0 on success, -ENODEV when neither the root interface nor the default interface was found
947  */
949  const char *ifaces_node_name, const char *iface, ConfNode **if_root, ConfNode **if_default)
950 {
951  const char *default_iface = "default";
952  *if_root = ConfSetIfaceNode(ifaces_node_name, iface);
953  *if_default = ConfSetIfaceNode(ifaces_node_name, default_iface);
954 
955  if (*if_root == NULL && *if_default == NULL) {
956  SCLogError("unable to find configuration for the interface \"%s\" or the default "
957  "configuration (\"%s\")",
958  iface, default_iface);
959  return (-ENODEV);
960  }
961 
962  /* If there is no setting for current interface use default one as main iface */
963  if (*if_root == NULL) {
964  *if_root = *if_default;
965  *if_default = NULL;
966  }
967  return 0;
968 }
969 
970 #ifdef UNITTESTS
971 
972 /**
973  * Lookup a non-existant value.
974  */
975 static int ConfTestGetNonExistant(void)
976 {
977  char name[] = "non-existant-value";
978  const char *value;
979 
980  FAIL_IF(ConfGet(name, &value));
981  PASS;
982 }
983 
984 /**
985  * Set then lookup a value.
986  */
987 static int ConfTestSetAndGet(void)
988 {
989  char name[] = "some-name";
990  char value[] = "some-value";
991  const char *value0 = NULL;
992 
993  FAIL_IF(ConfSet(name, value) != 1);
994  FAIL_IF(ConfGet(name, &value0) != 1);
995  FAIL_IF(value0 == NULL);
996  FAIL_IF(strcmp(value, value0) != 0);
997 
998  /* Cleanup. */
999  ConfRemove(name);
1000 
1001  PASS;
1002 }
1003 
1004 /**
1005  * Test that overriding a value is allowed provided allow_override is
1006  * true and that the config parameter gets the new value.
1007  */
1008 static int ConfTestOverrideValue1(void)
1009 {
1010  char name[] = "some-name";
1011  char value0[] = "some-value";
1012  char value1[] = "new-value";
1013  const char *val = NULL;
1014 
1015  FAIL_IF(ConfSet(name, value0) != 1);
1016  FAIL_IF(ConfSet(name, value1) != 1);
1017  FAIL_IF(ConfGet(name, &val) != 1);
1018  FAIL_IF(val == NULL);
1019  FAIL_IF(strcmp(val, value1) != 0);
1020 
1021  /* Cleanup. */
1022  ConfRemove(name);
1023 
1024  PASS;
1025 }
1026 
1027 /**
1028  * Test that a final value will not be overridden by a ConfSet.
1029  */
1030 static int ConfTestOverrideValue2(void)
1031 {
1032  char name[] = "some-name";
1033  char value0[] = "some-value";
1034  char value1[] = "new-value";
1035  const char *val = NULL;
1036 
1037  FAIL_IF(ConfSetFinal(name, value0) != 1);
1038  FAIL_IF(ConfSet(name, value1) != 0);
1039  FAIL_IF(ConfGet(name, &val) != 1);
1040  FAIL_IF(val == NULL);
1041  FAIL_IF(strcmp(val, value0) != 0);
1042 
1043  /* Cleanup. */
1044  ConfRemove(name);
1045 
1046  PASS;
1047 }
1048 
1049 /**
1050  * Test retrieving an integer value from the configuration db.
1051  */
1052 static int ConfTestGetInt(void)
1053 {
1054  char name[] = "some-int.x";
1055  intmax_t val;
1056 
1057  FAIL_IF(ConfSet(name, "0") != 1);
1058  FAIL_IF(ConfGetInt(name, &val) != 1);
1059  FAIL_IF(val != 0);
1060 
1061  FAIL_IF(ConfSet(name, "-1") != 1);
1062  FAIL_IF(ConfGetInt(name, &val) != 1);
1063  FAIL_IF(val != -1);
1064 
1065  FAIL_IF(ConfSet(name, "0xffff") != 1);
1066  FAIL_IF(ConfGetInt(name, &val) != 1);
1067  FAIL_IF(val != 0xffff);
1068 
1069  FAIL_IF(ConfSet(name, "not-an-int") != 1);
1070  FAIL_IF(ConfGetInt(name, &val) != 0);
1071 
1072  PASS;
1073 }
1074 
1075 /**
1076  * Test retrieving a boolean value from the configuration db.
1077  */
1078 static int ConfTestGetBool(void)
1079 {
1080  char name[] = "some-bool";
1081  const char *trues[] = {
1082  "1",
1083  "on", "ON",
1084  "yes", "YeS",
1085  "true", "TRUE",
1086  };
1087  const char *falses[] = {
1088  "0",
1089  "something",
1090  "off", "OFF",
1091  "false", "FalSE",
1092  "no", "NO",
1093  };
1094  int val;
1095  size_t u;
1096 
1097  for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) {
1098  FAIL_IF(ConfSet(name, trues[u]) != 1);
1099  FAIL_IF(ConfGetBool(name, &val) != 1);
1100  FAIL_IF(val != 1);
1101  }
1102 
1103  for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) {
1104  FAIL_IF(ConfSet(name, falses[u]) != 1);
1105  FAIL_IF(ConfGetBool(name, &val) != 1);
1106  FAIL_IF(val != 0);
1107  }
1108 
1109  PASS;
1110 }
1111 
1112 static int ConfNodeLookupChildTest(void)
1113 {
1114  const char *test_vals[] = { "one", "two", "three" };
1115  size_t u;
1116 
1117  ConfNode *parent = ConfNodeNew();
1118  ConfNode *child;
1119 
1120  for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1121  child = ConfNodeNew();
1122  child->name = SCStrdup(test_vals[u]);
1123  child->val = SCStrdup(test_vals[u]);
1124  TAILQ_INSERT_TAIL(&parent->head, child, next);
1125  }
1126 
1127  child = ConfNodeLookupChild(parent, "one");
1128  FAIL_IF(child == NULL);
1129  FAIL_IF(strcmp(child->name, "one") != 0);
1130  FAIL_IF(strcmp(child->val, "one") != 0);
1131 
1132  child = ConfNodeLookupChild(parent, "two");
1133  FAIL_IF(child == NULL);
1134  FAIL_IF(strcmp(child->name, "two") != 0);
1135  FAIL_IF(strcmp(child->val, "two") != 0);
1136 
1137  child = ConfNodeLookupChild(parent, "three");
1138  FAIL_IF(child == NULL);
1139  FAIL_IF(strcmp(child->name, "three") != 0);
1140  FAIL_IF(strcmp(child->val, "three") != 0);
1141 
1142  child = ConfNodeLookupChild(parent, "four");
1143  FAIL_IF(child != NULL);
1144 
1145  FAIL_IF(ConfNodeLookupChild(NULL, NULL) != NULL);
1146 
1147  if (parent != NULL) {
1148  ConfNodeFree(parent);
1149  }
1150 
1151  PASS;
1152 }
1153 
1154 static int ConfNodeLookupChildValueTest(void)
1155 {
1156  const char *test_vals[] = { "one", "two", "three" };
1157  size_t u;
1158 
1159  ConfNode *parent = ConfNodeNew();
1160  ConfNode *child;
1161  const char *value;
1162 
1163  for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1164  child = ConfNodeNew();
1165  child->name = SCStrdup(test_vals[u]);
1166  child->val = SCStrdup(test_vals[u]);
1167  TAILQ_INSERT_TAIL(&parent->head, child, next);
1168  }
1169 
1170  value = (char *)ConfNodeLookupChildValue(parent, "one");
1171  FAIL_IF(value == NULL);
1172  FAIL_IF(strcmp(value, "one") != 0);
1173 
1174  value = (char *)ConfNodeLookupChildValue(parent, "two");
1175  FAIL_IF(value == NULL);
1176  FAIL_IF(strcmp(value, "two") != 0);
1177 
1178  value = (char *)ConfNodeLookupChildValue(parent, "three");
1179  FAIL_IF(value == NULL);
1180  FAIL_IF(strcmp(value, "three") != 0);
1181 
1182  value = (char *)ConfNodeLookupChildValue(parent, "four");
1183  FAIL_IF(value != NULL);
1184 
1185  ConfNodeFree(parent);
1186 
1187  PASS;
1188 }
1189 
1190 static int ConfGetChildValueWithDefaultTest(void)
1191 {
1192  const char *val = "";
1194  ConfInit();
1195  ConfSet("af-packet.0.interface", "eth0");
1196  ConfSet("af-packet.1.interface", "default");
1197  ConfSet("af-packet.1.cluster-type", "cluster_cpu");
1198 
1199  ConfNode *myroot = ConfGetNode("af-packet.0");
1200  ConfNode *dflt = ConfGetNode("af-packet.1");
1201  ConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1202  FAIL_IF(strcmp(val, "cluster_cpu"));
1203 
1204  ConfSet("af-packet.0.cluster-type", "cluster_flow");
1205  ConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1206 
1207  FAIL_IF(strcmp(val, "cluster_flow"));
1208 
1209  ConfDeInit();
1211  PASS;
1212 }
1213 
1214 static int ConfGetChildValueIntWithDefaultTest(void)
1215 {
1216  intmax_t val = 0;
1218  ConfInit();
1219  ConfSet("af-packet.0.interface", "eth0");
1220  ConfSet("af-packet.1.interface", "default");
1221  ConfSet("af-packet.1.threads", "2");
1222 
1223  ConfNode *myroot = ConfGetNode("af-packet.0");
1224  ConfNode *dflt = ConfGetNode("af-packet.1");
1225  ConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1226  FAIL_IF(val != 2);
1227 
1228  ConfSet("af-packet.0.threads", "1");
1229  ConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1230  FAIL_IF(val != 1);
1231 
1232  ConfDeInit();
1234 
1235  PASS;
1236 }
1237 
1238 static int ConfGetChildValueBoolWithDefaultTest(void)
1239 {
1240  int val;
1242  ConfInit();
1243  ConfSet("af-packet.0.interface", "eth0");
1244  ConfSet("af-packet.1.interface", "default");
1245  ConfSet("af-packet.1.use-mmap", "yes");
1246 
1247  ConfNode *myroot = ConfGetNode("af-packet.0");
1248  ConfNode *dflt = ConfGetNode("af-packet.1");
1249  ConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1250  FAIL_IF(val == 0);
1251 
1252  ConfSet("af-packet.0.use-mmap", "no");
1253  ConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1254  FAIL_IF(val);
1255 
1256  ConfDeInit();
1258 
1259  PASS;
1260 }
1261 
1262 /**
1263  * Test the removal of a configuration node.
1264  */
1265 static int ConfNodeRemoveTest(void)
1266 {
1268  ConfInit();
1269 
1270  FAIL_IF(ConfSet("some.nested.parameter", "blah") != 1);
1271 
1272  ConfNode *node = ConfGetNode("some.nested.parameter");
1273  FAIL_IF(node == NULL);
1274  ConfNodeRemove(node);
1275 
1276  node = ConfGetNode("some.nested.parameter");
1277  FAIL_IF(node != NULL);
1278 
1279  ConfDeInit();
1281 
1282  PASS;
1283 }
1284 
1285 static int ConfSetTest(void)
1286 {
1288  ConfInit();
1289 
1290  /* Set some value with 2 levels. */
1291  FAIL_IF(ConfSet("one.two", "three") != 1);
1292  ConfNode *n = ConfGetNode("one.two");
1293  FAIL_IF(n == NULL);
1294 
1295  /* Set another 2 level parameter with the same first level, this
1296  * used to trigger a bug that caused the second level of the name
1297  * to become a first level node. */
1298  FAIL_IF(ConfSet("one.three", "four") != 1);
1299 
1300  n = ConfGetNode("one.three");
1301  FAIL_IF(n == NULL);
1302 
1303  /* A top level node of "three" should not exist. */
1304  n = ConfGetNode("three");
1305  FAIL_IF(n != NULL);
1306 
1307  ConfDeInit();
1309 
1310  PASS;
1311 }
1312 
1313 static int ConfGetNodeOrCreateTest(void)
1314 {
1315  ConfNode *node;
1316 
1318  ConfInit();
1319 
1320  /* Get a node that should not exist, give it a value, re-get it
1321  * and make sure the second time it returns the existing node. */
1322  node = ConfGetNodeOrCreate("node0", 0);
1323  FAIL_IF(node == NULL);
1324  FAIL_IF(node->parent == NULL || node->parent != root);
1325  FAIL_IF(node->val != NULL);
1326  node->val = SCStrdup("node0");
1327  node = ConfGetNodeOrCreate("node0", 0);
1328  FAIL_IF(node == NULL);
1329  FAIL_IF(node->val == NULL);
1330  FAIL_IF(strcmp(node->val, "node0") != 0);
1331 
1332  /* Do the same, but for something deeply nested. */
1333  node = ConfGetNodeOrCreate("parent.child.grandchild", 0);
1334  FAIL_IF(node == NULL);
1335  FAIL_IF(node->parent == NULL || node->parent == root);
1336  FAIL_IF(node->val != NULL);
1337  node->val = SCStrdup("parent.child.grandchild");
1338  node = ConfGetNodeOrCreate("parent.child.grandchild", 0);
1339  FAIL_IF(node == NULL);
1340  FAIL_IF(node->val == NULL);
1341  FAIL_IF(strcmp(node->val, "parent.child.grandchild") != 0);
1342 
1343  /* Test that 2 child nodes have the same root. */
1344  ConfNode *child1 = ConfGetNodeOrCreate("parent.kids.child1", 0);
1345  ConfNode *child2 = ConfGetNodeOrCreate("parent.kids.child2", 0);
1346  FAIL_IF(child1 == NULL || child2 == NULL);
1347  FAIL_IF(child1->parent != child2->parent);
1348  FAIL_IF(strcmp(child1->parent->name, "kids") != 0);
1349 
1350  ConfDeInit();
1352 
1353  PASS;
1354 }
1355 
1356 static int ConfNodePruneTest(void)
1357 {
1358  ConfNode *node;
1359 
1361  ConfInit();
1362 
1363  /* Test that final nodes exist after a prune. */
1364  FAIL_IF(ConfSet("node.notfinal", "notfinal") != 1);
1365  FAIL_IF(ConfSetFinal("node.final", "final") != 1);
1366  FAIL_IF(ConfGetNode("node.notfinal") == NULL);
1367  FAIL_IF(ConfGetNode("node.final") == NULL);
1368  FAIL_IF((node = ConfGetNode("node")) == NULL);
1369  ConfNodePrune(node);
1370  FAIL_IF(ConfGetNode("node.notfinal") != NULL);
1371  FAIL_IF(ConfGetNode("node.final") == NULL);
1372 
1373  /* Test that everything under a final node exists after a prune. */
1374  FAIL_IF(ConfSet("node.final.one", "one") != 1);
1375  FAIL_IF(ConfSet("node.final.two", "two") != 1);
1376  ConfNodePrune(node);
1377  FAIL_IF(ConfNodeLookupChild(node, "final") == NULL);
1378  FAIL_IF(ConfGetNode("node.final.one") == NULL);
1379  FAIL_IF(ConfGetNode("node.final.two") == NULL);
1380 
1381  ConfDeInit();
1383 
1384  PASS;
1385 }
1386 
1387 static int ConfNodeIsSequenceTest(void)
1388 {
1389  ConfNode *node = ConfNodeNew();
1390  FAIL_IF(node == NULL);
1391  FAIL_IF(ConfNodeIsSequence(node));
1392  node->is_seq = 1;
1393  FAIL_IF(!ConfNodeIsSequence(node));
1394 
1395  if (node != NULL) {
1396  ConfNodeFree(node);
1397  }
1398  PASS;
1399 }
1400 
1401 static int ConfSetFromStringTest(void)
1402 {
1403  ConfNode *n;
1404 
1406  ConfInit();
1407 
1408  FAIL_IF_NOT(ConfSetFromString("stream.midstream=true", 0));
1409  n = ConfGetNode("stream.midstream");
1410  FAIL_IF_NULL(n);
1411  FAIL_IF_NULL(n->val);
1412  FAIL_IF(strcmp("true", n->val));
1413 
1414  FAIL_IF_NOT(ConfSetFromString("stream.midstream =false", 0));
1415  n = ConfGetNode("stream.midstream");
1416  FAIL_IF_NULL(n);
1417  FAIL_IF(n->val == NULL || strcmp("false", n->val));
1418 
1419  FAIL_IF_NOT(ConfSetFromString("stream.midstream= true", 0));
1420  n = ConfGetNode("stream.midstream");
1421  FAIL_IF_NULL(n);
1422  FAIL_IF(n->val == NULL || strcmp("true", n->val));
1423 
1424  FAIL_IF_NOT(ConfSetFromString("stream.midstream = false", 0));
1425  n = ConfGetNode("stream.midstream");
1426  FAIL_IF_NULL(n);
1427  FAIL_IF(n->val == NULL || strcmp("false", n->val));
1428 
1429  ConfDeInit();
1431  PASS;
1432 }
1433 
1434 static int ConfNodeHasChildrenTest(void)
1435 {
1437  ConfInit();
1438 
1439  /* Set a plain key with value. */
1440  ConfSet("no-children", "value");
1441  ConfNode *n = ConfGetNode("no-children");
1442  FAIL_IF_NULL(n);
1444 
1445  /* Set a key with a sub key to a value. This makes the first key a
1446  * map. */
1447  ConfSet("parent.child", "value");
1448  n = ConfGetNode("parent");
1449  FAIL_IF_NULL(n);
1451 
1452  ConfDeInit();
1454  PASS;
1455 }
1456 
1458 {
1459  UtRegisterTest("ConfTestGetNonExistant", ConfTestGetNonExistant);
1460  UtRegisterTest("ConfSetTest", ConfSetTest);
1461  UtRegisterTest("ConfTestSetAndGet", ConfTestSetAndGet);
1462  UtRegisterTest("ConfTestOverrideValue1", ConfTestOverrideValue1);
1463  UtRegisterTest("ConfTestOverrideValue2", ConfTestOverrideValue2);
1464  UtRegisterTest("ConfTestGetInt", ConfTestGetInt);
1465  UtRegisterTest("ConfTestGetBool", ConfTestGetBool);
1466  UtRegisterTest("ConfNodeLookupChildTest", ConfNodeLookupChildTest);
1467  UtRegisterTest("ConfNodeLookupChildValueTest",
1468  ConfNodeLookupChildValueTest);
1469  UtRegisterTest("ConfNodeRemoveTest", ConfNodeRemoveTest);
1470  UtRegisterTest("ConfGetChildValueWithDefaultTest",
1471  ConfGetChildValueWithDefaultTest);
1472  UtRegisterTest("ConfGetChildValueIntWithDefaultTest",
1473  ConfGetChildValueIntWithDefaultTest);
1474  UtRegisterTest("ConfGetChildValueBoolWithDefaultTest",
1475  ConfGetChildValueBoolWithDefaultTest);
1476  UtRegisterTest("ConfGetNodeOrCreateTest", ConfGetNodeOrCreateTest);
1477  UtRegisterTest("ConfNodePruneTest", ConfNodePruneTest);
1478  UtRegisterTest("ConfNodeIsSequenceTest", ConfNodeIsSequenceTest);
1479  UtRegisterTest("ConfSetFromStringTest", ConfSetFromStringTest);
1480  UtRegisterTest("ConfNodeHasChildrenTest", ConfNodeHasChildrenTest);
1481 }
1482 
1483 #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:854
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:482
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:585
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:513
ConfNodeDump
void ConfNodeDump(const ConfNode *node, const char *prefix)
Dump a configuration node and all its children.
Definition: conf.c:716
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:746
ConfNodeLookupKeyValue
ConfNode * ConfNodeLookupKeyValue(const ConfNode *base, const char *key, const char *value)
Lookup for a key value under a specific node.
Definition: conf.c:826
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:461
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:536
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:653
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:638
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:879
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:669
ConfNodeHasChildren
bool ConfNodeHasChildren(const ConfNode *node)
Check if a node has any children.
Definition: conf.c:762
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:781
ConfGetFloat
int ConfGetFloat(const char *name, float *val)
Retrieve a configuration value as a float.
Definition: conf.c:615
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:1457
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:911
ConfRestoreContextBackup
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:679
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:500
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:561
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:948
ConfDeInit
void ConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:688
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:922
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:809