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