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