summaryrefslogtreecommitdiffstats
path: root/lib/isccfg/include
diff options
context:
space:
mode:
Diffstat (limited to 'lib/isccfg/include')
-rw-r--r--lib/isccfg/include/isccfg/aclconf.h91
-rw-r--r--lib/isccfg/include/isccfg/cfg.h609
-rw-r--r--lib/isccfg/include/isccfg/duration.h87
-rw-r--r--lib/isccfg/include/isccfg/grammar.h590
-rw-r--r--lib/isccfg/include/isccfg/kaspconf.h56
-rw-r--r--lib/isccfg/include/isccfg/log.h46
-rw-r--r--lib/isccfg/include/isccfg/namedconf.h54
7 files changed, 1533 insertions, 0 deletions
diff --git a/lib/isccfg/include/isccfg/aclconf.h b/lib/isccfg/include/isccfg/aclconf.h
new file mode 100644
index 0000000..eb1b9ab
--- /dev/null
+++ b/lib/isccfg/include/isccfg/aclconf.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <inttypes.h>
+
+#include <isc/lang.h>
+
+#include <dns/geoip.h>
+#include <dns/types.h>
+
+#include <isccfg/cfg.h>
+
+typedef struct cfg_aclconfctx {
+ ISC_LIST(dns_acl_t) named_acl_cache;
+ isc_mem_t *mctx;
+#if defined(HAVE_GEOIP2)
+ dns_geoip_databases_t *geoip;
+#endif /* if defined(HAVE_GEOIP2) */
+ isc_refcount_t references;
+} cfg_aclconfctx_t;
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret);
+/*
+ * Creates and initializes an ACL configuration context.
+ */
+
+void
+cfg_aclconfctx_detach(cfg_aclconfctx_t **actxp);
+/*
+ * Removes a reference to an ACL configuration context; when references
+ * reaches zero, clears the contents and deallocate the structure.
+ */
+
+void
+cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest);
+/*
+ * Attaches a pointer to an existing ACL configuration context.
+ */
+
+isc_result_t
+cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx,
+ isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx,
+ unsigned int nest_level, dns_acl_t **target);
+
+isc_result_t
+cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx,
+ isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx,
+ unsigned int nest_level, uint16_t family,
+ dns_acl_t **target);
+/*
+ * Construct a new dns_acl_t from configuration data in 'caml' and
+ * 'cctx'. Memory is allocated through 'mctx'.
+ *
+ * Any named ACLs referred to within 'caml' will be be converted
+ * into nested dns_acl_t objects. Multiple references to the same
+ * named ACLs will be converted into shared references to a single
+ * nested dns_acl_t object when the referring objects were created
+ * passing the same ACL configuration context 'ctx'.
+ *
+ * cfg_acl_fromconfig() is a backward-compatible version of
+ * cfg_acl_fromconfig2(), which allows an address family to be
+ * specified. If 'family' is not zero, then only addresses/prefixes
+ * of a matching family (AF_INET or AF_INET6) may be configured.
+ *
+ * On success, attach '*target' to the new dns_acl_t object.
+ *
+ * Require:
+ * 'ctx' to be non NULL.
+ * '*target' to be NULL or a valid dns_acl_t.
+ */
+
+ISC_LANG_ENDDECLS
diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h
new file mode 100644
index 0000000..c4f2d86
--- /dev/null
+++ b/lib/isccfg/include/isccfg/cfg.h
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+/*****
+***** Module Info
+*****/
+
+/*! \file isccfg/cfg.h
+ * \brief
+ * This is the new, table-driven, YACC-free configuration file parser.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <time.h>
+
+#include <isc/formatcheck.h>
+#include <isc/lang.h>
+#include <isc/list.h>
+#include <isc/refcount.h>
+#include <isc/types.h>
+
+/***
+ *** Types
+ ***/
+
+/*%
+ * A configuration parser.
+ */
+typedef struct cfg_parser cfg_parser_t;
+
+/*%
+ * A configuration type definition object. There is a single
+ * static cfg_type_t object for each data type supported by
+ * the configuration parser.
+ */
+typedef struct cfg_type cfg_type_t;
+
+/*%
+ * A configuration object. This is the basic building block of the
+ * configuration parse tree. It contains a value (which may be
+ * of one of several types) and information identifying the file
+ * and line number the value came from, for printing error
+ * messages.
+ */
+typedef struct cfg_obj cfg_obj_t;
+
+/*%
+ * A configuration object list element.
+ */
+typedef struct cfg_listelt cfg_listelt_t;
+
+/*%
+ * A callback function to be called when parsing an option
+ * that needs to be interpreted at parsing time, like
+ * "directory".
+ */
+typedef isc_result_t (*cfg_parsecallback_t)(const char *clausename,
+ const cfg_obj_t *obj, void *arg);
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+void
+cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest);
+/*%<
+ * Reference a parser object.
+ */
+
+isc_result_t
+cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret);
+/*%<
+ * Create a configuration file parser. Any warning and error
+ * messages will be logged to 'lctx'.
+ *
+ * The parser object returned can be used for a single call
+ * to cfg_parse_file() or cfg_parse_buffer(). It must not
+ * be reused for parsing multiple files or buffers.
+ */
+
+void
+cfg_parser_setflags(cfg_parser_t *pctx, unsigned int flags, bool turn_on);
+/*%<
+ * Set parser context flags. The flags are not checked for sensibility.
+ * If 'turn_on' is 'true' the flags will be set, otherwise the flags will
+ * be cleared.
+ *
+ * Requires:
+ *\li "pctx" is not NULL.
+ */
+
+void
+cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback,
+ void *arg);
+/*%<
+ * Make the parser call 'callback' whenever it encounters
+ * a configuration clause with the callback attribute,
+ * passing it the clause name, the clause value,
+ * and 'arg' as arguments.
+ *
+ * To restore the default of not invoking callbacks, pass
+ * callback==NULL and arg==NULL.
+ */
+
+isc_result_t
+cfg_parse_file(cfg_parser_t *pctx, const char *file, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
+ unsigned int line, const cfg_type_t *type, unsigned int flags,
+ cfg_obj_t **ret);
+/*%<
+ * Read a configuration containing data of type 'type'
+ * and make '*ret' point to its parse tree.
+ *
+ * The configuration is read from the file 'filename'
+ * (isc_parse_file()) or the buffer 'buffer'
+ * (isc_parse_buffer()).
+ *
+ * If 'file' is not NULL, it is the name of the file, or a name to use
+ * for the buffer in place of the filename, when logging errors.
+ *
+ * If 'line' is not 0, then it is the beginning line number to report
+ * when logging errors. This is useful when passing text that has been
+ * read from the middle of a file.
+ *
+ * Returns an error if the file or buffer does not parse correctly.
+ *
+ * Requires:
+ *\li "filename" is valid.
+ *\li "mem" is valid.
+ *\li "type" is valid.
+ *\li "cfg" is non-NULL and "*cfg" is NULL.
+ *\li "flags" be one or more of CFG_PCTX_NODEPRECATED or zero.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS - success
+ *\li #ISC_R_NOMEMORY - no memory available
+ *\li #ISC_R_INVALIDFILE - file doesn't exist or is unreadable
+ *\li others - file contains errors
+ */
+
+isc_result_t
+cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj,
+ const char *clause);
+/*%<
+ * Add the object 'obj' to the specified clause in mapbody 'mapobj'.
+ * Used for adding new zones.
+ *
+ * Require:
+ * \li 'obj' is a valid cfg_obj_t.
+ * \li 'mapobj' is a valid cfg_obj_t of type map.
+ * \li 'pctx' is a valid cfg_parser_t.
+ */
+
+void
+cfg_parser_reset(cfg_parser_t *pctx);
+/*%<
+ * Reset an existing parser so it can be re-used for a new file or
+ * buffer.
+ */
+
+void
+cfg_parser_destroy(cfg_parser_t **pctxp);
+/*%<
+ * Remove a reference to a configuration parser; destroy it if there are no
+ * more references.
+ */
+
+bool
+cfg_obj_isvoid(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of void type (e.g., an optional
+ * value not specified).
+ */
+
+bool
+cfg_obj_ismap(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of a map type.
+ */
+
+bool
+cfg_obj_isfixedpoint(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of a fixedpoint type.
+ */
+
+bool
+cfg_obj_ispercentage(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of a percentage type.
+ */
+
+isc_result_t
+cfg_map_get(const cfg_obj_t *mapobj, const char *name, const cfg_obj_t **obj);
+/*%<
+ * Extract an element from a configuration object, which
+ * must be of a map type.
+ *
+ * Requires:
+ * \li 'mapobj' points to a valid configuration object of a map type.
+ * \li 'name' points to a null-terminated string.
+ * \li 'obj' is non-NULL and '*obj' is NULL.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS - success
+ * \li #ISC_R_NOTFOUND - name not found in map
+ */
+
+const cfg_obj_t *
+cfg_map_getname(const cfg_obj_t *mapobj);
+/*%<
+ * Get the name of a named map object, like a server "key" clause.
+ *
+ * Requires:
+ * \li 'mapobj' points to a valid configuration object of a map type.
+ *
+ * Returns:
+ * \li A pointer to a configuration object naming the map object,
+ * or NULL if the map object does not have a name.
+ */
+
+unsigned int
+cfg_map_count(const cfg_obj_t *mapobj);
+/*%<
+ * Get the number of elements defined in the symbol table of a map object.
+ *
+ * Requires:
+ * \li 'mapobj' points to a valid configuration object of a map type.
+ *
+ * Returns:
+ * \li The number of elements in the map object.
+ */
+
+bool
+cfg_obj_istuple(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of a map type.
+ */
+
+const cfg_obj_t *
+cfg_tuple_get(const cfg_obj_t *tupleobj, const char *name);
+/*%<
+ * Extract an element from a configuration object, which
+ * must be of a tuple type.
+ *
+ * Requires:
+ * \li 'tupleobj' points to a valid configuration object of a tuple type.
+ * \li 'name' points to a null-terminated string naming one of the
+ *\li fields of said tuple type.
+ */
+
+bool
+cfg_obj_isuint32(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of integer type.
+ */
+
+uint32_t
+cfg_obj_asuint32(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of 32-bit integer type.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of 32-bit integer type.
+ *
+ * Returns:
+ * \li A 32-bit unsigned integer.
+ */
+
+bool
+cfg_obj_isuint64(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of integer type.
+ */
+
+uint64_t
+cfg_obj_asuint64(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of 64-bit integer type.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of 64-bit integer type.
+ *
+ * Returns:
+ * \li A 64-bit unsigned integer.
+ */
+
+uint32_t
+cfg_obj_asfixedpoint(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of fixed point number.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of fixed point type.
+ *
+ * Returns:
+ * \li A 32-bit unsigned integer.
+ */
+
+uint32_t
+cfg_obj_aspercentage(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of percentage
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of percentage type.
+ *
+ * Returns:
+ * \li A 32-bit unsigned integer.
+ */
+
+bool
+cfg_obj_isduration(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of duration type.
+ */
+
+uint32_t
+cfg_obj_asduration(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of duration
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of duration type.
+ *
+ * Returns:
+ * \li A duration in seconds.
+ */
+
+bool
+cfg_obj_isstring(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of string type.
+ */
+
+const char *
+cfg_obj_asstring(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of a string type
+ * as a null-terminated string.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of a string type.
+ *
+ * Returns:
+ * \li A pointer to a null terminated string.
+ */
+
+bool
+cfg_obj_isboolean(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of a boolean type.
+ */
+
+bool
+cfg_obj_asboolean(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of a boolean type.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of a boolean type.
+ *
+ * Returns:
+ * \li A boolean value.
+ */
+
+bool
+cfg_obj_issockaddr(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is a socket address.
+ */
+
+const isc_sockaddr_t *
+cfg_obj_assockaddr(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object representing a socket address.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of a socket address
+ * type.
+ *
+ * Returns:
+ * \li A pointer to a sockaddr. The sockaddr must be copied by the caller
+ * if necessary.
+ */
+
+bool
+cfg_obj_isnetprefix(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is a network prefix.
+ */
+
+void
+cfg_obj_asnetprefix(const cfg_obj_t *obj, isc_netaddr_t *netaddr,
+ unsigned int *prefixlen);
+/*%<
+ * Gets the value of a configuration object representing a network
+ * prefix. The network address is returned through 'netaddr' and the
+ * prefix length in bits through 'prefixlen'.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of network prefix type.
+ *\li 'netaddr' and 'prefixlen' are non-NULL.
+ */
+
+bool
+cfg_obj_islist(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of list type.
+ */
+
+const cfg_listelt_t *
+cfg_list_first(const cfg_obj_t *obj);
+/*%<
+ * Returns the first list element in a configuration object of a list type.
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of a list type or NULL.
+ *
+ * Returns:
+ * \li A pointer to a cfg_listelt_t representing the first list element,
+ * or NULL if the list is empty or nonexistent.
+ */
+
+const cfg_listelt_t *
+cfg_list_next(const cfg_listelt_t *elt);
+/*%<
+ * Returns the next element of a list of configuration objects.
+ *
+ * Requires:
+ * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or
+ * a previous call to cfg_list_next().
+ *
+ * Returns:
+ * \li A pointer to a cfg_listelt_t representing the next element,
+ * or NULL if there are no more elements.
+ */
+
+unsigned int
+cfg_list_length(const cfg_obj_t *obj, bool recurse);
+/*%<
+ * Returns the length of a list of configure objects. If obj is
+ * not a list, returns 0. If recurse is true, add in the length of
+ * all contained lists.
+ */
+
+cfg_obj_t *
+cfg_listelt_value(const cfg_listelt_t *elt);
+/*%<
+ * Returns the configuration object associated with cfg_listelt_t.
+ *
+ * Requires:
+ * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or
+ * cfg_list_next().
+ *
+ * Returns:
+ * \li A non-NULL pointer to a configuration object.
+ */
+
+void
+cfg_print(const cfg_obj_t *obj,
+ void (*f)(void *closure, const char *text, int textlen),
+ void *closure);
+void
+cfg_printx(const cfg_obj_t *obj, unsigned int flags,
+ void (*f)(void *closure, const char *text, int textlen),
+ void *closure);
+
+#define CFG_PRINTER_XKEY 0x1 /* '?' out shared keys. */
+#define CFG_PRINTER_ONELINE 0x2 /* print config as a single line */
+#define CFG_PRINTER_ACTIVEONLY \
+ 0x4 /* print only active configuration \
+ * options, omitting ancient, \
+ * obsolete, nonimplemented, \
+ * and test-only options. */
+
+/*%<
+ * Print the configuration object 'obj' by repeatedly calling the
+ * function 'f', passing 'closure' and a region of text starting
+ * at 'text' and comprising 'textlen' characters.
+ *
+ * If CFG_PRINTER_XKEY the contents of shared keys will be obscured
+ * by replacing them with question marks ('?')
+ */
+
+void
+cfg_print_grammar(const cfg_type_t *type, unsigned int flags,
+ void (*f)(void *closure, const char *text, int textlen),
+ void *closure);
+/*%<
+ * Print a summary of the grammar of the configuration type 'type'.
+ */
+
+bool
+cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type);
+/*%<
+ * Return true iff 'obj' is of type 'type'.
+ */
+
+void
+cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest);
+/*%<
+ * Reference a configuration object.
+ */
+
+void
+cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj);
+/*%<
+ * Delete a reference to a configuration object; destroy the object if
+ * there are no more references.
+ *
+ * Require:
+ * \li '*obj' is a valid cfg_obj_t.
+ * \li 'pctx' is a valid cfg_parser_t.
+ */
+
+void
+cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, const char *fmt,
+ ...) ISC_FORMAT_PRINTF(4, 5);
+/*%<
+ * Log a message concerning configuration object 'obj' to the logging
+ * channel of 'pctx', at log level 'level'. The message will be prefixed
+ * with the file name(s) and line number where 'obj' was defined.
+ */
+
+const char *
+cfg_obj_file(const cfg_obj_t *obj);
+/*%<
+ * Return the file that defined this object.
+ */
+
+unsigned int
+cfg_obj_line(const cfg_obj_t *obj);
+/*%<
+ * Return the line in file where this object was defined.
+ */
+
+const char *
+cfg_map_firstclause(const cfg_type_t *map, const void **clauses,
+ unsigned int *idx);
+const char *
+cfg_map_nextclause(const cfg_type_t *map, const void **clauses,
+ unsigned int *idx);
+
+typedef isc_result_t(pluginlist_cb_t)(const cfg_obj_t *config,
+ const cfg_obj_t *obj,
+ const char *plugin_path,
+ const char *parameters,
+ void *callback_data);
+/*%<
+ * Function prototype for the callback used with cfg_pluginlist_foreach().
+ * Called once for each element of the list passed to cfg_pluginlist_foreach().
+ * If this callback returns anything else than #ISC_R_SUCCESS, no further list
+ * elements will be processed.
+ *
+ * \li 'config' - the 'config' object passed to cfg_pluginlist_foreach()
+ * \li 'obj' - object representing the specific "plugin" stanza to be processed
+ * \li 'plugin_path' - path to the shared object with plugin code
+ * \li 'parameters' - configuration text for the plugin
+ * \li 'callback_data' - the pointer passed to cfg_pluginlist_foreach()
+ */
+
+isc_result_t
+cfg_pluginlist_foreach(const cfg_obj_t *config, const cfg_obj_t *list,
+ isc_log_t *lctx, pluginlist_cb_t *callback,
+ void *callback_data);
+/*%<
+ * For every "plugin" stanza present in 'list' (which in turn is a part of
+ * 'config'), invoke the given 'callback', passing 'callback_data' to it along
+ * with a fixed set of arguments (see the definition of the #pluginlist_cb_t
+ * type). Use logging context 'lctx' for logging error messages. Interrupt
+ * processing if 'callback' returns something else than #ISC_R_SUCCESS for any
+ * element of 'list'.
+ *
+ * Requires:
+ *
+ * \li 'config' is not NULL
+ * \li 'callback' is not NULL
+ *
+ * Returns:
+ *
+ * \li #ISC_R_SUCCESS if 'callback' returned #ISC_R_SUCCESS for all elements of
+ * 'list'
+ * \li first 'callback' return value which was not #ISC_R_SUCCESS otherwise
+ */
+
+ISC_LANG_ENDDECLS
diff --git a/lib/isccfg/include/isccfg/duration.h b/lib/isccfg/include/isccfg/duration.h
new file mode 100644
index 0000000..bd0c35b
--- /dev/null
+++ b/lib/isccfg/include/isccfg/duration.h
@@ -0,0 +1,87 @@
+
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+/*! \file */
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+#define CFG_DURATION_MAXLEN 80
+
+/*%
+ * A configuration object to store ISO 8601 durations.
+ */
+typedef struct isccfg_duration {
+ /*
+ * The duration is stored in multiple parts:
+ * [0] Years
+ * [1] Months
+ * [2] Weeks
+ * [3] Days
+ * [4] Hours
+ * [5] Minutes
+ * [6] Seconds
+ */
+ uint32_t parts[7];
+ bool iso8601;
+ bool unlimited;
+} isccfg_duration_t;
+
+isc_result_t
+isccfg_duration_fromtext(isc_textregion_t *source, isccfg_duration_t *duration);
+/*%<
+ * Converts an ISO 8601 duration style value.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li DNS_R_BADNUMBER
+ */
+
+isc_result_t
+isccfg_parse_duration(isc_textregion_t *source, isccfg_duration_t *duration);
+/*%<
+ * Converts a duration string to a ISO 8601 duration.
+ * If the string does not start with a P (or p), fall back to TTL-style value.
+ * In that case the duration will be treated in seconds only.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li DNS_R_BADNUMBER
+ *\li DNS_R_BADTTL
+ */
+
+uint32_t
+isccfg_duration_toseconds(const isccfg_duration_t *duration);
+/*%<
+ * Converts an ISO 8601 duration to seconds.
+ * The conversion is approximate:
+ * - Months will be treated as 31 days.
+ * - Years will be treated as 365 days.
+ *
+ * Notes:
+ *\li If the duration in seconds is greater than UINT32_MAX, the return value
+ * will be UINT32_MAX.
+ *
+ * Returns:
+ *\li The duration in seconds.
+ */
+
+ISC_LANG_ENDDECLS
diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h
new file mode 100644
index 0000000..83482d9
--- /dev/null
+++ b/lib/isccfg/include/isccfg/grammar.h
@@ -0,0 +1,590 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+/*! \file isccfg/grammar.h */
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <isc/lex.h>
+#include <isc/netaddr.h>
+#include <isc/region.h>
+#include <isc/sockaddr.h>
+#include <isc/types.h>
+
+#include <isccfg/cfg.h>
+#include <isccfg/duration.h>
+
+/*
+ * Definitions shared between the configuration parser
+ * and the grammars; not visible to users of the parser.
+ */
+
+/*% Clause may occur multiple times (e.g., "zone") */
+#define CFG_CLAUSEFLAG_MULTI 0x00000001
+/*% Clause is obsolete (logs a warning, but is not a fatal error) */
+#define CFG_CLAUSEFLAG_OBSOLETE 0x00000002
+/* obsolete: #define CFG_CLAUSEFLAG_NOTIMP 0x00000004 */
+/* obsolete: #define CFG_CLAUSEFLAG_NYI 0x00000008 */
+/* obsolete: #define CFG_CLAUSEFLAG_NEWDEFAULT 0x00000010 */
+/*%
+ * Clause needs to be interpreted during parsing
+ * by calling a callback function, like the
+ * "directory" option.
+ */
+#define CFG_CLAUSEFLAG_CALLBACK 0x00000020
+/*% An option that is only used in testing. */
+#define CFG_CLAUSEFLAG_TESTONLY 0x00000040
+/*% A configuration option that was not configured at compile time. */
+#define CFG_CLAUSEFLAG_NOTCONFIGURED 0x00000080
+/*% An option for an experimental feature. */
+#define CFG_CLAUSEFLAG_EXPERIMENTAL 0x00000100
+/*% An option that should be omited from the documentation */
+#define CFG_CLAUSEFLAG_NODOC 0x00000200
+/*% Clause will be obsolete in a future release (logs a warning) */
+#define CFG_CLAUSEFLAG_DEPRECATED 0x00000400
+/*% Clause has been obsolete so long that it's now a fatal error */
+#define CFG_CLAUSEFLAG_ANCIENT 0x00000800
+
+/*%
+ * Zone types for which a clause is valid:
+ * These share space with CFG_CLAUSEFLAG values, but count
+ * down from the top.
+ */
+#define CFG_ZONE_PRIMARY 0x80000000
+#define CFG_ZONE_SECONDARY 0x40000000
+#define CFG_ZONE_STUB 0x20000000
+#define CFG_ZONE_HINT 0x10000000
+#define CFG_ZONE_FORWARD 0x08000000
+#define CFG_ZONE_STATICSTUB 0x04000000
+#define CFG_ZONE_REDIRECT 0x02000000
+#define CFG_ZONE_DELEGATION 0x01000000
+#define CFG_ZONE_INVIEW 0x00800000
+#define CFG_ZONE_MIRROR 0x00400000
+
+typedef struct cfg_clausedef cfg_clausedef_t;
+typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
+typedef struct cfg_printer cfg_printer_t;
+typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
+typedef struct cfg_map cfg_map_t;
+typedef struct cfg_rep cfg_rep_t;
+
+/*
+ * Function types for configuration object methods
+ */
+
+typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
+ cfg_obj_t **);
+typedef void (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
+typedef void (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
+typedef void (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);
+
+/*
+ * Structure definitions
+ */
+
+/*%
+ * A configuration printer object. This is an abstract
+ * interface to a destination to which text can be printed
+ * by calling the function 'f'.
+ */
+struct cfg_printer {
+ void (*f)(void *closure, const char *text, int textlen);
+ void *closure;
+ int indent;
+ int flags;
+};
+
+/*% A clause definition. */
+struct cfg_clausedef {
+ const char *name;
+ cfg_type_t *type;
+ unsigned int flags;
+};
+
+/*% A tuple field definition. */
+struct cfg_tuplefielddef {
+ const char *name;
+ cfg_type_t *type;
+ unsigned int flags;
+};
+
+/*% A configuration object type definition. */
+struct cfg_type {
+ const char *name; /*%< For debugging purposes only */
+ cfg_parsefunc_t parse;
+ cfg_printfunc_t print;
+ cfg_docfunc_t doc; /*%< Print grammar description */
+ cfg_rep_t *rep; /*%< Data representation */
+ const void *of; /*%< Additional data for meta-types */
+};
+
+/*% A keyword-type definition, for things like "port <integer>". */
+typedef struct {
+ const char *name;
+ const cfg_type_t *type;
+} keyword_type_t;
+
+struct cfg_map {
+ cfg_obj_t *id; /*%< Used for 'named maps' like
+ * keys, zones, &c */
+ const cfg_clausedef_t *const *clausesets; /*%< The clauses that
+ * can occur in this map;
+ * used for printing */
+ isc_symtab_t *symtab;
+};
+
+typedef struct cfg_netprefix cfg_netprefix_t;
+
+struct cfg_netprefix {
+ isc_netaddr_t address; /* IP4/IP6 */
+ unsigned int prefixlen;
+};
+
+/*%
+ * A configuration data representation.
+ */
+struct cfg_rep {
+ const char *name; /*%< For debugging only */
+ cfg_freefunc_t free; /*%< How to free this kind of data. */
+};
+
+/*%
+ * A configuration object. This is the main building block
+ * of the configuration parse tree.
+ */
+
+struct cfg_obj {
+ const cfg_type_t *type;
+ union {
+ uint32_t uint32;
+ uint64_t uint64;
+ isc_textregion_t string; /*%< null terminated, too */
+ bool boolean;
+ cfg_map_t map;
+ cfg_list_t list;
+ cfg_obj_t **tuple;
+ isc_sockaddr_t sockaddr;
+ struct {
+ isc_sockaddr_t sockaddr;
+ int32_t dscp;
+ } sockaddrdscp;
+ cfg_netprefix_t netprefix;
+ isccfg_duration_t duration;
+ } value;
+ isc_refcount_t references; /*%< reference counter */
+ const char *file;
+ unsigned int line;
+ cfg_parser_t *pctx;
+};
+
+/*% A list element. */
+struct cfg_listelt {
+ cfg_obj_t *obj;
+ ISC_LINK(cfg_listelt_t) link;
+};
+
+/*% The parser object. */
+struct cfg_parser {
+ isc_mem_t *mctx;
+ isc_log_t *lctx;
+ isc_lex_t *lexer;
+ unsigned int errors;
+ unsigned int warnings;
+ isc_token_t token;
+
+ /*% We are at the end of all input. */
+ bool seen_eof;
+
+ /*% The current token has been pushed back. */
+ bool ungotten;
+
+ /*%
+ * The stack of currently active files, represented
+ * as a configuration list of configuration strings.
+ * The head is the top-level file, subsequent elements
+ * (if any) are the nested include files, and the
+ * last element is the file currently being parsed.
+ */
+ cfg_obj_t *open_files;
+
+ /*%
+ * Names of files that we have parsed and closed
+ * and were previously on the open_file list.
+ * We keep these objects around after closing
+ * the files because the file names may still be
+ * referenced from other configuration objects
+ * for use in reporting semantic errors after
+ * parsing is complete.
+ */
+ cfg_obj_t *closed_files;
+
+ /*%
+ * Name of a buffer being parsed; used only for
+ * logging.
+ */
+ char const *buf_name;
+
+ /*%
+ * Current line number. We maintain our own
+ * copy of this so that it is available even
+ * when a file has just been closed.
+ */
+ unsigned int line;
+
+ /*%
+ * Parser context flags, used for maintaining state
+ * from one token to the next.
+ */
+ unsigned int flags;
+
+ /*%< Reference counter */
+ isc_refcount_t references;
+
+ cfg_parsecallback_t callback;
+ void *callbackarg;
+};
+
+/* Parser context flags */
+#define CFG_PCTX_SKIP 0x1
+#define CFG_PCTX_NODEPRECATED 0x2
+
+/*@{*/
+/*%
+ * Flags defining whether to accept certain types of network addresses.
+ */
+#define CFG_ADDR_V4OK 0x00000001
+#define CFG_ADDR_V4PREFIXOK 0x00000002
+#define CFG_ADDR_V6OK 0x00000004
+#define CFG_ADDR_WILDOK 0x00000008
+#define CFG_ADDR_DSCPOK 0x00000010
+#define CFG_ADDR_PORTOK 0x00000020
+#define CFG_ADDR_MASK (CFG_ADDR_V6OK | CFG_ADDR_V4OK)
+/*@}*/
+
+/*@{*/
+/*%
+ * Predefined data representation types.
+ */
+extern cfg_rep_t cfg_rep_uint32;
+extern cfg_rep_t cfg_rep_uint64;
+extern cfg_rep_t cfg_rep_string;
+extern cfg_rep_t cfg_rep_boolean;
+extern cfg_rep_t cfg_rep_map;
+extern cfg_rep_t cfg_rep_list;
+extern cfg_rep_t cfg_rep_tuple;
+extern cfg_rep_t cfg_rep_sockaddr;
+extern cfg_rep_t cfg_rep_netprefix;
+extern cfg_rep_t cfg_rep_void;
+extern cfg_rep_t cfg_rep_fixedpoint;
+extern cfg_rep_t cfg_rep_percentage;
+extern cfg_rep_t cfg_rep_duration;
+/*@}*/
+
+/*@{*/
+/*%
+ * Predefined configuration object types.
+ */
+extern cfg_type_t cfg_type_boolean;
+extern cfg_type_t cfg_type_uint32;
+extern cfg_type_t cfg_type_uint64;
+extern cfg_type_t cfg_type_qstring;
+extern cfg_type_t cfg_type_astring;
+extern cfg_type_t cfg_type_ustring;
+extern cfg_type_t cfg_type_sstring;
+extern cfg_type_t cfg_type_bracketed_aml;
+extern cfg_type_t cfg_type_bracketed_text;
+extern cfg_type_t cfg_type_optional_bracketed_text;
+extern cfg_type_t cfg_type_keyref;
+extern cfg_type_t cfg_type_sockaddr;
+extern cfg_type_t cfg_type_sockaddrdscp;
+extern cfg_type_t cfg_type_netaddr;
+extern cfg_type_t cfg_type_netaddr4;
+extern cfg_type_t cfg_type_netaddr4wild;
+extern cfg_type_t cfg_type_netaddr6;
+extern cfg_type_t cfg_type_netaddr6wild;
+extern cfg_type_t cfg_type_netprefix;
+extern cfg_type_t cfg_type_void;
+extern cfg_type_t cfg_type_token;
+extern cfg_type_t cfg_type_unsupported;
+extern cfg_type_t cfg_type_fixedpoint;
+extern cfg_type_t cfg_type_percentage;
+extern cfg_type_t cfg_type_duration;
+extern cfg_type_t cfg_type_duration_or_unlimited;
+/*@}*/
+
+isc_result_t
+cfg_gettoken(cfg_parser_t *pctx, int options);
+
+isc_result_t
+cfg_peektoken(cfg_parser_t *pctx, int options);
+
+void
+cfg_ungettoken(cfg_parser_t *pctx);
+
+#define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
+
+isc_result_t
+cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
+
+void
+cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
+
+isc_result_t
+cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+isc_result_t
+cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+isc_result_t
+cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);
+
+void
+cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
+
+bool
+cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
+
+isc_result_t
+cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
+
+isc_result_t
+cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
+
+isc_result_t
+cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_special(cfg_parser_t *pctx, int special);
+/*%< Parse a required special character 'special'. */
+
+isc_result_t
+cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
+
+isc_result_t
+cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
+
+isc_result_t
+cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
+
+isc_result_t
+cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
+ cfg_listelt_t **ret);
+
+isc_result_t
+cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+void
+cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);
+
+isc_result_t
+cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+void
+cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+isc_result_t
+cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
+
+isc_result_t
+cfg_parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
+ const cfg_type_t *othertype, cfg_obj_t **ret);
+
+void
+cfg_doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *enumtype,
+ const cfg_type_t *othertype);
+
+void
+cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
+/*%< Print 'len' characters at 'text' */
+
+void
+cfg_print_cstr(cfg_printer_t *pctx, const char *s);
+/*%< Print the null-terminated string 's' */
+
+isc_result_t
+cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+isc_result_t
+cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+void
+cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);
+
+isc_result_t
+cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);
+
+isc_result_t
+cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
+
+isc_result_t
+cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+void
+cfg_print_fixedpoint(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+isc_result_t
+cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+void
+cfg_print_percentage(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+isc_result_t
+cfg_parse_duration(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_duration(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+isc_result_t
+cfg_parse_duration_or_unlimited(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+void
+cfg_print_duration_or_unlimited(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+isc_result_t
+cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
+void
+cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
+cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
+/*%<
+ * Print a description of the grammar of an arbitrary configuration
+ * type 'type'
+ */
+
+void
+cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
+/*%<
+ * Document the type 'type' as a terminal by printing its
+ * name in angle brackets, e.g., &lt;uint32>.
+ */
+
+void
+cfg_parser_error(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+/*!
+ * Pass one of these flags to cfg_parser_error() to include the
+ * token text in log message.
+ */
+#define CFG_LOG_NEAR 0x00000001 /*%< Say "near <token>" */
+#define CFG_LOG_BEFORE 0x00000002 /*%< Say "before <token>" */
+#define CFG_LOG_NOPREP 0x00000004 /*%< Say just "<token>" */
+
+void
+cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+
+bool
+cfg_is_enum(const char *s, const char *const *enums);
+/*%< Return true iff the string 's' is one of the strings in 'enums' */
+
+bool
+cfg_clause_validforzone(const char *name, unsigned int ztype);
+/*%<
+ * Check whether an option is legal for the specified zone type.
+ */
+
+void
+cfg_print_zonegrammar(const unsigned int zonetype, unsigned int flags,
+ void (*f)(void *closure, const char *text, int textlen),
+ void *closure);
+/*%<
+ * Print a summary of the grammar of the zone type represented by
+ * 'zonetype'.
+ */
+
+void
+cfg_print_clauseflags(cfg_printer_t *pctx, unsigned int flags);
+/*%<
+ * Print clause flags (e.g. "obsolete", "not implemented", etc) in
+ * human readable form
+ */
+
+void
+cfg_print_indent(cfg_printer_t *pctx);
+/*%<
+ * Print the necessary indent required by the current settings of 'pctx'.
+ */
diff --git a/lib/isccfg/include/isccfg/kaspconf.h b/lib/isccfg/include/isccfg/kaspconf.h
new file mode 100644
index 0000000..7b1e075
--- /dev/null
+++ b/lib/isccfg/include/isccfg/kaspconf.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <isc/lang.h>
+
+#include <isccfg/cfg.h>
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
+ isc_mem_t *mctx, isc_log_t *logctx,
+ dns_kasplist_t *kasplist, dns_kasp_t **kaspp);
+/*%<
+ * Create and configure a KASP. If 'default_kasp' is not NULL, the built-in
+ * default configuration is used to set values that are not explicitly set in
+ * the policy. If a 'kasplist' is provided, a lookup happens and if a KASP
+ * already exists with the same name, no new KASP is created, and no attach to
+ * 'kaspp' happens.
+ *
+ * Requires:
+ *
+ *\li 'name' is either NULL, or a valid C string.
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'logctx' is a valid logging context.
+ *
+ *\li kaspp != NULL && *kaspp == NULL
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS If creating and configuring the KASP succeeds.
+ *\li #ISC_R_EXISTS If 'kasplist' already has a kasp structure with 'name'.
+ *\li #ISC_R_NOMEMORY
+ *
+ *\li Other errors are possible.
+ */
+
+ISC_LANG_ENDDECLS
diff --git a/lib/isccfg/include/isccfg/log.h b/lib/isccfg/include/isccfg/log.h
new file mode 100644
index 0000000..8af3095
--- /dev/null
+++ b/lib/isccfg/include/isccfg/log.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+/*! \file isccfg/log.h */
+
+#include <isc/lang.h>
+#include <isc/log.h>
+
+extern isc_logcategory_t cfg_categories[];
+extern isc_logmodule_t cfg_modules[];
+
+#define CFG_LOGCATEGORY_CONFIG (&cfg_categories[0])
+
+#define CFG_LOGMODULE_PARSER (&cfg_modules[0])
+
+ISC_LANG_BEGINDECLS
+
+void
+cfg_log_init(isc_log_t *lctx);
+/*%<
+ * Make the libisccfg categories and modules available for use with the
+ * ISC logging library.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ *\li cfg_log_init() is called only once.
+ *
+ * Ensures:
+ * \li The categories and modules defined above are available for
+ * use by isc_log_usechannnel() and isc_log_write().
+ */
+
+ISC_LANG_ENDDECLS
diff --git a/lib/isccfg/include/isccfg/namedconf.h b/lib/isccfg/include/isccfg/namedconf.h
new file mode 100644
index 0000000..f2d0145
--- /dev/null
+++ b/lib/isccfg/include/isccfg/namedconf.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+/*! \file isccfg/namedconf.h
+ * \brief
+ * This module defines the named.conf, rndc.conf, and rndc.key grammars.
+ */
+
+#include <isccfg/cfg.h>
+
+/*
+ * Configuration object types.
+ */
+extern cfg_type_t cfg_type_namedconf;
+/*%< A complete named.conf file. */
+
+extern cfg_type_t cfg_type_bindkeys;
+/*%< A bind.keys file. */
+
+extern cfg_type_t cfg_type_newzones;
+/*%< A new-zones file (for zones added by 'rndc addzone'). */
+
+extern cfg_type_t cfg_type_addzoneconf;
+/*%< A single zone passed via the addzone rndc command. */
+
+extern cfg_type_t cfg_type_rndcconf;
+/*%< A complete rndc.conf file. */
+
+extern cfg_type_t cfg_type_rndckey;
+/*%< A complete rndc.key file. */
+
+extern cfg_type_t cfg_type_sessionkey;
+/*%< A complete session.key file. */
+
+extern cfg_type_t cfg_type_keyref;
+/*%< A key reference, used as an ACL element */
+
+/*%< Zone options */
+extern cfg_type_t cfg_type_zoneopts;
+
+/*%< DNSSEC Key and Signing Policy options */
+extern cfg_type_t cfg_type_dnssecpolicyopts;