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