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