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