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