Commit 399a9193 authored by Francis Dupont's avatar Francis Dupont
Browse files

[898-add-a-new-hook-to-support-bootp] Checkpoint: code and tests done - doc to update

parent e064013b
......@@ -1559,6 +1559,8 @@ AC_CONFIG_FILES([Makefile
src/bin/shell/tests/shell_unittest.py
src/hooks/Makefile
src/hooks/dhcp/Makefile
src/hooks/dhcp/bootp/Makefile
src/hooks/dhcp/bootp/tests/Makefile
src/hooks/dhcp/flex_option/Makefile
src/hooks/dhcp/flex_option/libloadtests/Makefile
src/hooks/dhcp/flex_option/tests/Makefile
......
SUBDIRS = high_availability lease_cmds
SUBDIRS = bootp flex_option high_availability lease_cmds
if HAVE_MYSQL
SUBDIRS += mysql_cb
endif
SUBDIRS += stat_cmds flex_option user_chk
SUBDIRS += stat_cmds user_chk
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(KEA_CXXFLAGS)
# Ensure that the message file and doxygen file is included in the distribution
EXTRA_DIST = bootp_messages.mes
EXTRA_DIST += bootp.dox
CLEANFILES = *.gcno *.gcda
# convenience archive
noinst_LTLIBRARIES = libbootp.la
libbootp_la_SOURCES = bootp_callouts.cc
libbootp_la_SOURCES += bootp_log.cc bootp_log.h
libbootp_la_SOURCES += bootp_messages.cc bootp_messages.h
libbootp_la_SOURCES += version.cc
libbootp_la_CXXFLAGS = $(AM_CXXFLAGS)
libbootp_la_CPPFLAGS = $(AM_CPPFLAGS)
# install the shared object into $(libdir)/kea/hooks
lib_hooksdir = $(libdir)/kea/hooks
lib_hooks_LTLIBRARIES = libdhcp_bootp.la
libdhcp_bootp_la_SOURCES =
libdhcp_bootp_la_LDFLAGS = $(AM_LDFLAGS)
libdhcp_bootp_la_LDFLAGS += -avoid-version -export-dynamic -module
libdhcp_bootp_la_LIBADD = libbootp.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la
libdhcp_bootp_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
libdhcp_bootp_la_LIBADD += $(LOG4CPLUS_LIBS)
libdhcp_bootp_la_LIBADD += $(CRYPTO_LIBS)
libdhcp_bootp_la_LIBADD += $(BOOST_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 bootp_messages.h bootp_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: bootp_messages.h bootp_messages.cc
@echo Message files regenerated
bootp_messages.h bootp_messages.cc: bootp_messages.mes
$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/hooks/dhcp/bootp/bootp_messages.mes
else
messages bootp_messages.h bootp_messages.cc:
@echo Messages generation disabled. Configure with --enable-generate-messages to enable it.
endif
// 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/.
/**
@page libdhcp_bootp Kea Bootp Hooks Library
@section libdhcp_bootpIntro Introduction
Welcome to Kea Bootp Hooks Library. This documentation is addressed to
developers who are interested in the internal operation of the Bootp
library. This file provides information needed to understand and
perhaps extend this library.
This documentation is stand-alone: you should have read and understood
the <a href="https://jenkins.isc.org/job/Kea_doc/doxygen/">Kea
Developer's Guide</a> and in particular its section about hooks.
@section libdhcp_bootpUser Now To Use libdhcp_bootp
## Introduction
libdhcp_bootp is a hooks library which allows the processing
of BOOTP queries following the RFC1497. Old RFC951 BOOTP queries
without vendor extensions are not supported.
## Configuring the DHCPv4 Module
It must be configured as a hook library for the desired DHCP server
modules. Note that the bootp library is installed alongside the
Kea libraries in "<install-dir>/lib" where <install-dir> is determined
by the --prefix option of the configure script. It defaults to
"/usr/local". Assuming the default value then, configuring kea-dhcp4
to load the bootp library could be done with the following Kea4
configuration:
@code
"Dhcp4": {
"hook_libraries": [
{ "library": "/usr/local/lib/libdhcp_bootp.so" },
...
]
}
@endcode
No parameter is defined.
## Internal operation
The first function called in @ref load() located in the
bootp_callouts.cc. It checks if the necessary parameter is passed and
decodes the option configurations. @ref unload() free the configuration.
Kea engine checks if the library has functions that match known hook
point names. This library has one such function: @ref pkt4_receive
located in bootp_callouts.cc.
If the receive query has to dhcp-message-type option then it is a BOOTP
one: the BOOTP client class and a DHCPREQUEST dhcp-message-type option
are added to the BOOTP query.
*/
// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the End User License
// Agreement. See COPYING file in the premium/ directory.
#include <config.h>
#include <bootp_log.h>
#include <hooks/hooks.h>
#include <dhcp/pkt4.h>
using namespace isc;
using namespace isc::bootp;
using namespace isc::dhcp;
using namespace isc::hooks;
using namespace isc::log;
// 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 "pkt4_receive" hook.
///
/// Ignore DHCP and BOOTREPLY messages.
/// Remaining packets should be BOOTP requests so add the BOOTP
/// client class and a DHCPREQUEST dhcp-message-type.
///
/// @param handle CalloutHandle.
///
/// @return 0 upon success, non-zero otherwise.
int pkt4_receive(CalloutHandle& handle) {
// Get the received unpacked message.
Pkt4Ptr query;
handle.getArgument("query4", query);
try {
if (query->getType() != DHCP_NOTYPE) {
// DHCP query.
return (0);
}
if (query->getOp() == BOOTREPLY) {
// BOOTP response.
return (0);
}
// BOOTP query.
query->addClass("BOOTP");
query->setType(DHCPREQUEST);
LOG_DEBUG(bootp_logger, DBGLVL_TRACE_BASIC, BOOTP_PROCESSED)
.arg(query->getLabel());
} catch (const std::exception& ex) {
// Got an error (should not happen). The query shall very likely
// be dropped later.
LOG_ERROR(bootp_logger, BOOTP_PROCESS_ERROR)
.arg(query->getLabel())
.arg(ex.what());
}
return (0);
}
/// @brief This function is called when the library is loaded.
///
/// @param handle library handle (unused).
/// @return always 0.
int load(LibraryHandle& /*handle*/) {
LOG_INFO(bootp_logger, BOOTP_LOAD);
return (0);
}
/// @brief This function is called when the library is unloaded.
///
/// @return always 0.
int unload() {
LOG_INFO(bootp_logger, BOOTP_UNLOAD);
return (0);
}
} // end extern "C"
// 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 <config.h>
#include <bootp_log.h>
namespace isc {
namespace bootp {
isc::log::Logger bootp_logger("bootp-hooks");
} // namespace bootp
} // namespace isc
// 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 BOOTP_LOG_H
#define BOOTP_LOG_H
#include <log/logger_support.h>
#include <log/macros.h>
#include <log/log_dbglevels.h>
#include <bootp_messages.h>
namespace isc {
namespace bootp {
extern isc::log::Logger bootp_logger;
} // end of namespace bootp
} // end of namespace isc
#endif
// File created from ../../../../src/hooks/dhcp/bootp/bootp_messages.mes on Mon Nov 18 2019 09:30
#include <cstddef>
#include <log/message_types.h>
#include <log/message_initializer.h>
extern const isc::log::MessageID BOOTP_LOAD = "BOOTP_LOAD";
extern const isc::log::MessageID BOOTP_PROCESSED = "BOOTP_PROCESSED";
extern const isc::log::MessageID BOOTP_PROCESS_ERROR = "BOOTP_PROCESS_ERROR";
extern const isc::log::MessageID BOOTP_UNLOAD = "BOOTP_UNLOAD";
namespace {
const char* values[] = {
"BOOTP_LOAD", "Bootp hooks library has been loaded",
"BOOTP_PROCESSED", "processed BOOTP query: %1",
"BOOTP_PROCESS_ERROR", "%1: failed to process packet: %2",
"BOOTP_UNLOAD", "Bootp hooks library has been unloaded",
NULL
};
const isc::log::MessageInitializer initializer(values);
} // Anonymous namespace
// File created from ../../../../src/hooks/dhcp/bootp/bootp_messages.mes on Mon Nov 18 2019 09:30
#ifndef BOOTP_MESSAGES_H
#define BOOTP_MESSAGES_H
#include <log/message_types.h>
extern const isc::log::MessageID BOOTP_LOAD;
extern const isc::log::MessageID BOOTP_PROCESSED;
extern const isc::log::MessageID BOOTP_PROCESS_ERROR;
extern const isc::log::MessageID BOOTP_UNLOAD;
#endif // BOOTP_MESSAGES_H
# Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
% BOOTP_LOAD Bootp hooks library has been loaded
This info message indicates that the Bootp hooks library has been loaded.
% BOOTP_PROCESSED processed BOOTP query: %1
This debug message is printed when a BOOTP query was processed.
The query client and transaction identification are displayed.
% BOOTP_PROCESS_ERROR %1: failed to process packet: %2
This error message indicates an error during processing of a packet.
The first argument contains the client and transaction identification
information. The second argument includes the details of the error.
% BOOTP_UNLOAD Bootp hooks library has been unloaded
This info message indicates that the Bootp hooks library has been unloaded.
/bootp_unittests
/bootp_unittests.log
/bootp_unittests.trs
/test-suite.log
SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/bootp -I$(top_srcdir)/src/hooks/dhcp/bootp
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -DBOOTP_LIB_SO=\"$(abs_top_builddir)/src/hooks/dhcp/bootp/.libs/libdhcp_bootp.so\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(KEA_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
# Unit test data files need to get installed.
EXTRA_DIST =
CLEANFILES = *.gcno *.gcda
# TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
LOG_COMPILER = $(LIBTOOL)
AM_LOG_FLAGS = --mode=execute
TESTS =
if HAVE_GTEST
TESTS += bootp_unittests
bootp_unittests_SOURCES = run_unittests.cc
bootp_unittests_SOURCES += bootp_unittests.cc
bootp_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
bootp_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
bootp_unittests_CXXFLAGS = $(AM_CXXFLAGS)
bootp_unittests_LDADD = $(top_builddir)/src/hooks/dhcp/bootp/libbootp.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
bootp_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
bootp_unittests_LDADD += $(LOG4CPLUS_LIBS)
bootp_unittests_LDADD += $(CRYPTO_LIBS)
bootp_unittests_LDADD += $(BOOST_LIBS)
bootp_unittests_LDADD += $(GTEST_LDADD)
endif
noinst_PROGRAMS = $(TESTS)
// 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 This file contains tests which verify flexible option.
#include <config.h>
#include <bootp_log.h>
#include <dhcp/pkt4.h>
#include <hooks/callout_manager.h>
#include <hooks/hooks.h>
#include <gtest/gtest.h>
#include <sstream>
using namespace std;
using namespace isc;
using namespace isc::bootp;
using namespace isc::dhcp;
using namespace isc::hooks;
extern "C" {
extern int pkt4_receive(CalloutHandle& handle);
}
namespace {
/// @brief Test fixture for exercising bootp library callout.
/// It fetches the CalloutManager and prepares stub packets that can be used in
/// tests.
class BootpTest : public ::testing::Test {
public:
/// @brief Constructor.
BootpTest() : co_manager_(new CalloutManager(1)) {
}
/// @brief Destructor.
virtual ~BootpTest() {
}
/// @brief Fetches the callout manager instance.
boost::shared_ptr<CalloutManager>getCalloutManager() {
return(co_manager_);
}
/// @brief Tests pkt4_receive callout.
///
/// @param pkt The packet to submit.
/// @param processed True if the packet must be processed, false otherwise.
void pkt4_receiveCall(Pkt4Ptr& pkt, bool processed) {
// Get callout handle.
CalloutHandle handle(getCalloutManager());
// Set query.
handle.setArgument("query4", pkt);
// Get type.
uint8_t type = pkt->getType();
// Execute pkt4_receive callout.
int ret;
ASSERT_NO_THROW(ret = pkt4_receive(handle));
EXPECT_EQ(0, ret);
// Verify processing.
if (processed) {
EXPECT_TRUE(pkt->inClass("BOOTP"));
EXPECT_EQ(DHCPREQUEST, pkt->getType());
} else {
EXPECT_FALSE(pkt->inClass("BOOTP"));
EXPECT_EQ(type, pkt->getType());
}
}
/// @brief Callout manager accessed by this CalloutHandle.
boost::shared_ptr<CalloutManager> co_manager_;
};
// Verifies that DHCPDISCOVER goes through unmodified.
TEST_F(BootpTest, dhcpDiscover) {
Pkt4Ptr pkt(new Pkt4(DHCPDISCOVER, 12345));
pkt4_receiveCall(pkt, false);
}
// Verifies that DHCPREQUEST goes through unmodified.
TEST_F(BootpTest, dhcpRequest) {
Pkt4Ptr pkt(new Pkt4(DHCPREQUEST, 12345));
pkt4_receiveCall(pkt, false);
}
// Verifies that DHCPOFFER goes through unmodified.
TEST_F(BootpTest, dhcpOffer) {
Pkt4Ptr pkt(new Pkt4(DHCPOFFER, 12345));
pkt4_receiveCall(pkt, false);
}
// Verifies that BOOTREPLY goes through unmodified.
TEST_F(BootpTest, bootReply) {
// The constructor does not allow to directly create a BOOTREPLY packet.
Pkt4Ptr pkt(new Pkt4(DHCPOFFER, 12345));
pkt->setType(DHCP_NOTYPE);
pkt->delOption(DHO_DHCP_MESSAGE_TYPE);
ASSERT_EQ(BOOTREPLY, pkt->getOp());
pkt4_receiveCall(pkt, false);
}
// Verifies that BOOTREQUEST is recognized and processed.
TEST_F(BootpTest, bootRequest) {
// The constructor does not allow to directly create a BOOTREQUEST packet.
Pkt4Ptr pkt(new Pkt4(DHCPDISCOVER, 12345));
pkt->setType(DHCP_NOTYPE);
pkt->delOption(DHO_DHCP_MESSAGE_TYPE);
ASSERT_EQ(BOOTREQUEST, pkt->getOp());
pkt4_receiveCall(pkt, true);
}
} // end of anonymous namespace
// 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 <config.h>
#include <log/logger_support.h>
#include <gtest/gtest.h>
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
isc::log::initLogger();
int result = RUN_ALL_TESTS();
return (result);
}
// 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 <config.h>
#include <hooks/hooks.h>
extern "C" {
/// @brief returns Kea hooks version.
int version() {
return (KEA_HOOKS_VERSION);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment