]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#899,!513] Scripts Hook implemented.
authorTomek Mrugalski <tomasz@isc.org>
Thu, 19 Sep 2019 14:27:10 +0000 (16:27 +0200)
committerTomek Mrugalski <tomasz@isc.org>
Thu, 19 Sep 2019 14:37:22 +0000 (16:37 +0200)
16 files changed:
configure.ac
src/hooks/dhcp/Makefile.am
src/hooks/dhcp/scripts/Makefile.am [new file with mode: 0644]
src/hooks/dhcp/scripts/lease_expire_co.cc [new file with mode: 0644]
src/hooks/dhcp/scripts/load_unload.cc [new file with mode: 0644]
src/hooks/dhcp/scripts/pkt_send_co.cc [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts.cc [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts.h [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts_cfg.cc [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts_cfg.h [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts_log.cc [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts_log.h [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts_messages.cc [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts_messages.h [new file with mode: 0644]
src/hooks/dhcp/scripts/scripts_messages.mes [new file with mode: 0644]
src/hooks/dhcp/scripts/version.cc [new file with mode: 0644]

index 8f78ac2426f1eb399679efde676ffd1759b5b1fd..84701efe508eea6e08ad5d6559e848b9f9e0ab0e 100755 (executable)
@@ -1703,6 +1703,8 @@ AC_CONFIG_FILES([Makefile
                  src/hooks/dhcp/user_chk/Makefile
                  src/hooks/dhcp/user_chk/tests/Makefile
                  src/hooks/dhcp/user_chk/tests/test_data_files_config.h
+                 src/hooks/dhcp/scripts/Makefile
+                 src/hooks/dhcp/scripts/tests/Makefile
                  src/hooks/dhcp/stat_cmds/Makefile
                  src/hooks/dhcp/stat_cmds/tests/Makefile
                  src/lib/Makefile
index 0bb9b878e379bd8f9e83b35ec3ee00e1d8810154..05db00239f919eeeaadbc33663d6faa4942bc554 100644 (file)
@@ -4,4 +4,4 @@ if HAVE_MYSQL
 SUBDIRS += mysql_cb
 endif
 
-SUBDIRS += stat_cmds user_chk
+SUBDIRS += scripts stat_cmds user_chk
diff --git a/src/hooks/dhcp/scripts/Makefile.am b/src/hooks/dhcp/scripts/Makefile.am
new file mode 100644 (file)
index 0000000..ea54429
--- /dev/null
@@ -0,0 +1,77 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS  = $(KEA_CXXFLAGS)
+
+EXTRA_DIST = libdhcp_scripts.dox
+# Ensure that the message file is included in the distribution
+EXTRA_DIST += scripts_messages.mes
+
+CLEANFILES = *.gcno *.gcda
+
+# convenience archive
+
+noinst_LTLIBRARIES = libscripts.la
+
+libscripts_la_SOURCES  =
+libscripts_la_SOURCES += load_unload.cc
+libscripts_la_SOURCES += pkt_send_co.cc
+libscripts_la_SOURCES += lease_expire_co.cc
+libscripts_la_SOURCES += scripts_cfg.cc scripts_cfg.h
+libscripts_la_SOURCES += scripts_log.cc scripts_log.h
+libscripts_la_SOURCES += scripts_messages.cc scripts_messages.h
+libscripts_la_SOURCES += version.cc
+
+libscripts_la_CXXFLAGS = $(AM_CXXFLAGS)
+libscripts_la_CPPFLAGS = $(AM_CPPFLAGS)
+
+noinst_LTLIBRARIES += libdhcp_scripts.la
+
+libdhcp_scripts_la_SOURCES  =
+libdhcp_scripts_la_LDFLAGS  = $(AM_LDFLAGS)
+libdhcp_scripts_la_LDFLAGS  += -avoid-version -export-dynamic -module
+# -rpath /nowhere is a hack to trigger libtool to not create a
+# convenience archive, resulting in shared modules
+libdhcp_scripts_la_LDFLAGS  += -rpath /nowhere
+libdhcp_scripts_la_LIBADD  = libscripts.la
+libdhcp_scripts_la_LIBADD  += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+libdhcp_scripts_la_LIBADD  += $(top_builddir)/src/lib/log/libkea-log.la
+libdhcp_scripts_la_LIBADD  += $(top_builddir)/src/lib/util/threads/libkea-threads.la
+libdhcp_scripts_la_LIBADD  += $(top_builddir)/src/lib/util/libkea-util.la
+libdhcp_scripts_la_LIBADD  += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libdhcp_scripts_la_LIBADD  += $(LOG4CPLUS_LIBS)
+
+# If we want to get rid of all generated messages files, we need to use
+# make maintainer-clean. The proper way to introduce custom commands for
+# that operation is to define maintainer-clean-local target. However,
+# make maintainer-clean also removes Makefile, so running configure script
+# is required.  To make it easy to rebuild messages without going through
+# reconfigure, a new target messages-clean has been added.
+maintainer-clean-local:
+       rm -f scripts_messages.h scripts_messages.cc
+
+# To regenerate messages files, one can do:
+#
+# make messages-clean
+# make messages
+#
+# This is needed only when a .mes file is modified.
+messages-clean: maintainer-clean-local
+
+if GENERATE_MESSAGES
+
+# Define rule to build logging source files from message file
+messages: scripts_messages.h scripts_messages.cc
+       @echo Message files regenerated
+
+scripts_messages.h scripts_messages.cc: scripts_messages.mes
+       $(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/hooks/dhcp/scripts/scripts_messages.mes
+
+else
+
+messages scripts_messages.h scripts_messages.cc:
+       @echo Messages generation disabled. Configure with --enable-generate-messages to enable it.
+
+endif
+
diff --git a/src/hooks/dhcp/scripts/lease_expire_co.cc b/src/hooks/dhcp/scripts/lease_expire_co.cc
new file mode 100644 (file)
index 0000000..e56f7b6
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+/// @file lease_expire_co.cc Defines the lease4_send and lease6_send callout functions.
+
+#include <config.h>
+#include <asiolink/io_address.h>
+#include <hooks/hooks.h>
+#include <dhcp/dhcp4.h>
+#include <dhcp/dhcp6.h>
+#include <dhcp/option_string.h>
+#include <dhcp/option_custom.h>
+#include <dhcp/option6_ia.h>
+#include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
+#include <dhcp/docsis3_option_defs.h>
+#include <dhcpsrv/lease.h>
+#include <dhcp/pkt4.h>
+#include <dhcp/pkt6.h>
+#include <scripts_cfg.h>
+#include <scripts.h>
+
+using namespace isc::dhcp;
+using namespace isc::hooks;
+using namespace hooks::scripts;
+using namespace std;
+
+// Functions accessed by the hooks framework use C linkage to avoid the name
+// mangling that accompanies use of the C++ compiler as well as to avoid
+// issues related to namespaces.
+extern "C" {
+
+/// @brief  This callout is called at the "lease6_expire" hook.
+///
+/// @return 0 upon success, non-zero otherwise.
+int lease6_expire(CalloutHandle& handle) {
+    try {
+        Lease6Ptr lease;
+        handle.getArgument("lease6", lease);
+
+        if (!lease) {
+            // Something is very wrong here.
+            return (1);
+        }
+        
+        Variables vars;
+
+        stringstream tmp;
+        switch (lease->type_) {
+        case Lease::TYPE_NA:
+        case Lease::TYPE_TA:
+        case Lease::TYPE_V4:
+            tmp << "ADDRESS1=" << lease->addr_.toText();
+            break;
+        case Lease::TYPE_PD:
+            tmp << "PREFIX1=" << lease->addr_.toText() << "/" << static_cast<int>(lease->prefixlen_);
+            break;
+        default:
+            // Unknown lease type.
+            return (1);
+        }
+        vars.push_back(tmp.str());
+
+        if (lease->duid_) {
+            tmp.str("");
+            tmp << "DUID=" << lease->duid_->toText();
+            vars.push_back(tmp.str());
+        }
+
+        tmp.str("");
+        tmp << "HOSTNAME=" << lease->hostname_;
+        vars.push_back(tmp.str());
+
+        callScript(vars);
+        
+    } catch (const std::exception& ex) {
+        std::cout << "DHCP Scripts Hook : lease6_expire unexpected error: "
+                  << ex.what() << std::endl;
+        return (1);
+    }
+
+    return (0);
+}
+
+} // extern C
+
+
diff --git a/src/hooks/dhcp/scripts/load_unload.cc b/src/hooks/dhcp/scripts/load_unload.cc
new file mode 100644 (file)
index 0000000..1bd0a56
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+/// @file load_unload.cc Defines the load and unload hooks library functions.
+
+#include <config.h>
+
+#include <hooks/hooks.h>
+#include <cc/data.h>
+#include <scripts_log.h>
+#include <scripts_cfg.h>
+
+#include <sstream>
+#include <vector>
+#include <errno.h>
+
+using namespace std;
+using namespace isc::data;
+using namespace isc::hooks;
+using namespace isc::log;
+using namespace hooks::scripts;
+
+// Functions accessed by the hooks framework use C linkage to avoid the name
+// mangling that accompanies use of the C++ compiler as well as to avoid
+// issues related to namespaces.
+extern "C" {
+
+/// @brief Called by the Hooks library manager when the library is loaded.
+///
+/// Instantiates the UserRegistry and opens the outcome file. Failure in
+/// either results in a failed return code.
+///
+/// @return Returns 0 upon success, non-zero upon failure.
+int load(LibraryHandle& handle) {
+    // non-zero indicates an error.
+    int ret_val = 0;
+
+    ScriptsConfigPtr cfg = getScriptsConfig();
+    cfg->clear();
+
+    try {
+        // zero out the errno to be safe
+        errno = 0;
+
+        ConstElementPtr scripts = handle.getParameter("scripts");
+        if (!scripts) {
+            LOG_ERROR(scripts_logger, SCRIPTS_HOOK_LOAD_ERROR)
+                .arg("Mandatory parameter 'scripts' missing");
+            return (1);
+        }
+        if (scripts->getType() != Element::list) {
+            LOG_ERROR(scripts_logger, SCRIPTS_HOOK_LOAD_ERROR)
+                .arg("Parameter 'scripts' specified, but it's not a list");
+            return (1);
+        }
+
+        if (scripts->size() == 0) {
+            LOG_ERROR(scripts_logger, SCRIPTS_HOOK_LOAD_ERROR)
+                .arg("Parameter 'scripts' list specified, but it is empty.");
+            return (1);
+        }
+        
+        for (int i = 0; i < scripts->size(); i++) {
+            auto s = scripts->get(i);
+            if (!s || s->getType() != Element::string) {
+                stringstream tmp;
+                tmp << "Element " << i << " of the 'scripts' list is either empty or is not a string";
+                LOG_ERROR(scripts_logger, SCRIPTS_HOOK_LOAD_ERROR)
+                    .arg(tmp.str());
+            }
+            // Store the script name in our config.
+            cfg->scripts_.push_back(s->stringValue());
+            LOG_DEBUG(scripts_logger, DBGLVL_START_SHUT, SCRIPTS_HOOK_SCRIPT_ENTRY)
+                .arg(s->stringValue());
+        }
+    }
+    catch (const std::exception& ex) {
+        // Log the error and return failure.
+        LOG_ERROR(scripts_logger, SCRIPTS_HOOK_LOAD_ERROR).arg(ex.what());
+        ret_val = 1;
+    }
+
+    try {
+        ConstElementPtr async = handle.getParameter("async");
+        if (async && async->getType() != Element::boolean) {
+            LOG_ERROR(scripts_logger, SCRIPTS_HOOK_LOAD_ERROR)
+                .arg("Parameter 'async' specified, but it's not a boolean");
+            return (1);
+        }
+        cfg->async_ = async->boolValue();
+    } catch (...) {
+        // We don't care. The async parameter is optional.
+    }
+
+    return (ret_val);
+}
+
+/// @brief Called by the Hooks library manager when the library is unloaded.
+///
+/// Destroys the UserRegistry and closes the outcome file.
+///
+/// @return Always returns 0.
+int unload() {
+    try {
+        // We only clean the configuration. There's nothing else to clean up.
+        ScriptsConfigPtr cfg = getScriptsConfig();
+        cfg->clear();
+    } catch (const std::exception& ex) {
+        // On the off chance something goes awry, catch it and log it.
+        // @todo Not sure if we should return a non-zero result or not.
+        LOG_ERROR(scripts_logger, SCRIPTS_HOOK_UNLOAD_ERROR).arg(ex.what());
+    }
+
+    return (0);
+}
+
+}
diff --git a/src/hooks/dhcp/scripts/pkt_send_co.cc b/src/hooks/dhcp/scripts/pkt_send_co.cc
new file mode 100644 (file)
index 0000000..343be19
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+/// @file pkt_send_co.cc Defines the pkt4_send and pkt6_send callout functions.
+
+#include <config.h>
+#include <asiolink/io_address.h>
+#include <hooks/hooks.h>
+#include <dhcp/dhcp4.h>
+#include <dhcp/dhcp6.h>
+#include <dhcp/option6_ia.h>
+#include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
+#include <dhcp/pkt4.h>
+#include <dhcp/pkt6.h>
+#include <dhcp/dhcp6.h>
+#include <scripts_cfg.h>
+#include <scripts.h>
+
+using namespace isc::dhcp;
+using namespace isc::hooks;
+using namespace hooks::scripts;
+using namespace std;
+
+// Functions accessed by the hooks framework use C linkage to avoid the name
+// mangling that accompanies use of the C++ compiler as well as to avoid
+// issues related to namespaces.
+extern "C" {
+
+/// @brief  This callout is called at the "pkt6_send" hook.
+///
+/// This function generates environment variables based on the Pkt6 content.
+/// It then calls the external script.
+///
+/// @return 0 upon success, non-zero otherwise.
+int pkt6_send(CalloutHandle& handle) {
+
+
+    try {
+        Pkt6Ptr query;
+        handle.getArgument("query6", query);
+
+        Pkt6Ptr response;
+        handle.getArgument("response6", response);
+
+        Variables vars;
+
+        if (!query || !response) {
+            // Something is very wrong.
+            return (1);
+        }
+
+        stringstream tmp;
+        tmp << "ACTION=" << Pkt6::getName(query->getType());
+        vars.push_back(tmp.str());
+
+        auto ia_list = response->getOptions(D6O_IA_NA);
+        int addr_cnt = 1;
+        for (auto ia : ia_list) {
+            auto opts = ia.second->getOptions();
+
+            for (auto opt : opts) {
+                if (opt.second->getType() != D6O_IAADDR) {
+                    continue;
+                }
+
+                Option6IAAddrPtr addr = boost::dynamic_pointer_cast<Option6IAAddr>(opt.second);
+                if (!addr) {
+                    // something is wrong. But let's ignore it and move forward.
+                    continue;
+                }
+
+                tmp.str("");
+                tmp << "ADDRESS" << (addr_cnt) << "=" << addr->getAddress();
+                vars.push_back(tmp.str());
+
+
+                tmp.str("");
+                tmp << "ADDRESS" << (addr_cnt) << "_PREFERRED=" << addr->getPreferred();
+                vars.push_back(tmp.str());
+
+                tmp.str("");
+                tmp << "ADDRESS" << (addr_cnt++) << "_VALID=" << addr->getValid();
+                vars.push_back(tmp.str());
+            }
+        }
+
+        auto pd_list = response->getOptions(D6O_IA_PD);
+        int prefix_cnt = 1;
+
+        for (auto pd: pd_list) {
+            auto opts = pd.second->getOptions();
+
+            for (auto opt : opts) {
+                if (opt.second->getType() != D6O_IAPREFIX) {
+                    continue;
+                }
+
+                Option6IAPrefixPtr prefix = boost::dynamic_pointer_cast<Option6IAPrefix>(opt.second);
+                if (!prefix) {
+                    // something is wrong. But let's ignore it and move forward.
+                    continue;
+                }
+
+                stringstream tmp;
+                tmp << "PREFIX" << (prefix_cnt) << "=" << prefix->getAddress() << "/"
+                    << prefix->getLength();
+                vars.push_back(tmp.str());
+
+                tmp.str("");
+                tmp << "PREFIX" << (prefix_cnt) << "_PREFERRED=" << prefix->getPreferred();
+                vars.push_back(tmp.str());
+
+                tmp.str("");
+                tmp << "PREFIX" << (prefix_cnt++) << "_VALID=" << prefix->getValid();
+                vars.push_back(tmp.str());
+            }
+
+        }
+
+        // Ok, all variables are set, call the scripts!
+        callScript(vars);
+
+    } catch (const std::exception& ex) {
+        std::cout << "DHCP Scripts Hook : pkt6_send unexpected error: "
+                  << ex.what() << std::endl;
+        return (1);
+    }
+
+
+    return (0);
+}
+
+} // extern C
diff --git a/src/hooks/dhcp/scripts/scripts.cc b/src/hooks/dhcp/scripts/scripts.cc
new file mode 100644 (file)
index 0000000..c3c7f81
--- /dev/null
@@ -0,0 +1,23 @@
+
+#include <scripts.h>
+#include <scripts_cfg.h>
+
+namespace hooks {
+namespace scripts {
+
+bool callScript(const Variables& vars) {
+    
+    ScriptsConfigPtr cfg = getScriptsConfig();
+    try {
+
+
+    } catch (const std::exception& e) {
+
+        return (false);
+    }
+
+    return (true);
+}
+
+};
+};
diff --git a/src/hooks/dhcp/scripts/scripts.h b/src/hooks/dhcp/scripts/scripts.h
new file mode 100644 (file)
index 0000000..f2823d2
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+#ifndef VARIABLES_H
+#define VARIABLES_H
+
+#include <string>
+#include <vector>
+
+namespace hooks {
+namespace scripts {
+
+    /// @brief keeps a list of variables.
+    ///
+    /// Each entry is supposed to have a string containing VARIABLE=VALUE
+    typedef std::vector<std::string> Variables;
+
+    /// @brief calls the actual scripts
+    ///
+    /// @param vars environment variables to be passed to the script.
+    /// @return true if successful, false otherwise
+    bool callScript(const Variables& vars);
+};
+};
+
+#endif
diff --git a/src/hooks/dhcp/scripts/scripts_cfg.cc b/src/hooks/dhcp/scripts/scripts_cfg.cc
new file mode 100644 (file)
index 0000000..d1f1eae
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+
+#include <scripts_cfg.h>
+
+namespace {
+hooks::scripts::ScriptsConfigPtr config;
+};
+
+namespace hooks {
+namespace scripts {
+
+ScriptsConfig::ScriptsConfig() {
+    clear();
+}
+
+void
+ScriptsConfig::clear() {
+    async_ = true;
+    scripts_.clear();
+}
+
+ScriptsConfigPtr getScriptsConfig() {
+    if (!config) {
+        config.reset(new ScriptsConfig());
+    }
+    return (config);
+}
+
+
+
+};
+};
diff --git a/src/hooks/dhcp/scripts/scripts_cfg.h b/src/hooks/dhcp/scripts/scripts_cfg.h
new file mode 100644 (file)
index 0000000..3c45ff9
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+#ifndef SCRIPTS_HOOK_H
+#define SCRIPTS_HOOK_H
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string>
+
+namespace hooks {
+namespace scripts {
+
+/// @brief Represents scripts hook configuration
+class ScriptsConfig {
+ public:
+    /// @brief default constructor
+    ScriptsConfig();
+
+    /// @brief Clears configuration.
+    void clear();
+    
+    /// @brief scripts to be called.
+    std::vector<std::string> scripts_;
+
+    /// @brief define whether scripts should be called async (true) or sync (false)
+    bool async_;
+};
+
+/// @brief pointer to ScriptsConfig
+typedef boost::shared_ptr<ScriptsConfig> ScriptsConfigPtr;
+
+/// @brief returns current Scripts hook configuration
+ScriptsConfigPtr getScriptsConfig();
+
+};
+};
+
+#endif
diff --git a/src/hooks/dhcp/scripts/scripts_log.cc b/src/hooks/dhcp/scripts/scripts_log.cc
new file mode 100644 (file)
index 0000000..532fc73
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+/// Defines the logger used by the user check hooks library.
+#include <config.h>
+
+#include <scripts_log.h>
+
+namespace hooks {
+namespace scripts {
+
+isc::log::Logger scripts_logger("scripts");
+
+} // namespace hooks::scripts
+} // namespace hooks
diff --git a/src/hooks/dhcp/scripts/scripts_log.h b/src/hooks/dhcp/scripts/scripts_log.h
new file mode 100644 (file)
index 0000000..ff67d6e
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+
+#ifndef SCRIPTS_LOG_H
+#define SCRIPTS_LOG_H
+
+#include <log/message_initializer.h>
+#include <log/macros.h>
+#include <scripts_messages.h>
+
+namespace hooks {
+namespace scripts {
+
+/// @brief Scripts Logger
+///
+/// Define the logger used to log messages.
+extern isc::log::Logger scripts_logger;
+
+} // end of namespace scripts
+} // end of namespace hooks
+
+#endif // SCRIPTS_LOG_H
diff --git a/src/hooks/dhcp/scripts/scripts_messages.cc b/src/hooks/dhcp/scripts/scripts_messages.cc
new file mode 100644 (file)
index 0000000..95ec188
--- /dev/null
@@ -0,0 +1,23 @@
+// File created from ../../../../src/hooks/dhcp/scripts/scripts_messages.mes on Thu Sep 19 2019 12:34
+
+#include <cstddef>
+#include <log/message_types.h>
+#include <log/message_initializer.h>
+
+extern const isc::log::MessageID SCRIPTS_HOOK_LOAD_ERROR = "SCRIPTS_HOOK_LOAD_ERROR";
+extern const isc::log::MessageID SCRIPTS_HOOK_SCRIPT_ENTRY = "SCRIPTS_HOOK_SCRIPT_ENTRY";
+extern const isc::log::MessageID SCRIPTS_HOOK_UNLOAD_ERROR = "SCRIPTS_HOOK_UNLOAD_ERROR";
+
+namespace {
+
+const char* values[] = {
+    "SCRIPTS_HOOK_LOAD_ERROR", "DHCP ScriptsHook could not be loaded: %1",
+    "SCRIPTS_HOOK_SCRIPT_ENTRY", "DHCP Scripts Hook will use the following script: %1",
+    "SCRIPTS_HOOK_UNLOAD_ERROR", "DHCP Scripts Hook an error occurred unloading the library: %1",
+    NULL
+};
+
+const isc::log::MessageInitializer initializer(values);
+
+} // Anonymous namespace
+
diff --git a/src/hooks/dhcp/scripts/scripts_messages.h b/src/hooks/dhcp/scripts/scripts_messages.h
new file mode 100644 (file)
index 0000000..47ede1f
--- /dev/null
@@ -0,0 +1,12 @@
+// File created from ../../../../src/hooks/dhcp/scripts/scripts_messages.mes on Thu Sep 19 2019 12:34
+
+#ifndef SCRIPTS_MESSAGES_H
+#define SCRIPTS_MESSAGES_H
+
+#include <log/message_types.h>
+
+extern const isc::log::MessageID SCRIPTS_HOOK_LOAD_ERROR;
+extern const isc::log::MessageID SCRIPTS_HOOK_SCRIPT_ENTRY;
+extern const isc::log::MessageID SCRIPTS_HOOK_UNLOAD_ERROR;
+
+#endif // SCRIPTS_MESSAGES_H
diff --git a/src/hooks/dhcp/scripts/scripts_messages.mes b/src/hooks/dhcp/scripts/scripts_messages.mes
new file mode 100644 (file)
index 0000000..05fa8ae
--- /dev/null
@@ -0,0 +1,19 @@
+# Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+#
+# 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 http://mozilla.org/MPL/2.0/.
+
+% SCRIPTS_HOOK_LOAD_ERROR DHCP ScriptsHook could not be loaded: %1
+This is an error message issued when the DHCP Scripts Hook could not be loaded.
+The exact cause should be explained in the log message.  User subnet selection
+will revert to default processing.
+
+% SCRIPTS_HOOK_UNLOAD_ERROR DHCP Scripts Hook an error occurred unloading the library: %1
+This is an error message issued when an error occurs while unloading the
+Scripts Hook library.  This is unlikely to occur and normal operations of the
+library will likely resume when it is next loaded.
+
+% SCRIPTS_HOOK_SCRIPT_ENTRY DHCP Scripts Hook will use the following script: %1
+This debug message is printed when Scripts hook library is loaded and it parses
+a script name.
\ No newline at end of file
diff --git a/src/hooks/dhcp/scripts/version.cc b/src/hooks/dhcp/scripts/version.cc
new file mode 100644 (file)
index 0000000..1cc6ba0
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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 http://mozilla.org/MPL/2.0/.
+// version.cc
+
+#include <config.h>
+
+#include <hooks/hooks.h>
+
+extern "C" {
+
+/// @brief Version function required by Hooks API for compatibility checks.
+int version() {
+    return (KEA_HOOKS_VERSION);
+}
+
+}