diff options
-rw-r--r-- | src/lib/dhcpsrv/host.cc | 8 | ||||
-rw-r--r-- | src/lib/dhcpsrv/host.h | 31 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/host_unittest.cc | 130 |
3 files changed, 164 insertions, 5 deletions
diff --git a/src/lib/dhcpsrv/host.cc b/src/lib/dhcpsrv/host.cc index c336dc1eff..be6e8439b6 100644 --- a/src/lib/dhcpsrv/host.cc +++ b/src/lib/dhcpsrv/host.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2016 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 @@ -78,7 +78,8 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len, ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()), hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes), - dhcp6_client_classes_(dhcp6_client_classes) { + dhcp6_client_classes_(dhcp6_client_classes), + cfg_option4_(), cfg_option6_() { // Initialize HWAddr or DUID setIdentifier(identifier, identifier_len, identifier_type); @@ -99,7 +100,8 @@ Host::Host(const std::string& identifier, const std::string& identifier_name, ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()), hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes), - dhcp6_client_classes_(dhcp6_client_classes) { + dhcp6_client_classes_(dhcp6_client_classes), + cfg_option4_(new CfgOption()), cfg_option6_(new CfgOption()) { // Initialize HWAddr or DUID setIdentifier(identifier, identifier_name); diff --git a/src/lib/dhcpsrv/host.h b/src/lib/dhcpsrv/host.h index 108396ca40..0a61c9654f 100644 --- a/src/lib/dhcpsrv/host.h +++ b/src/lib/dhcpsrv/host.h @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2016 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 @@ -11,6 +11,7 @@ #include <dhcp/classify.h> #include <dhcp/duid.h> #include <dhcp/hwaddr.h> +#include <dhcpsrv/cfg_option.h> #include <dhcpsrv/subnet_id.h> #include <boost/shared_ptr.hpp> #include <list> @@ -409,6 +410,30 @@ public: return (dhcp6_client_classes_); } + /// @brief Returns pointer to the DHCPv4 option data configuration for + /// this host. + CfgOptionPtr getCfgOption4() { + return (cfg_option4_); + } + + /// @brief Returns const pointer to the DHCPv4 option data configuration for + /// this host. + ConstCfgOptionPtr getCfgOption4() const { + return (cfg_option4_); + } + + /// @brief Returns pointer to the DHCPv6 option data configuration for + /// this host. + CfgOptionPtr getCfgOption6() { + return (cfg_option6_); + } + + /// @brief Returns const pointer to the DHCPv6 option data configuration for + /// this host. + ConstCfgOptionPtr getCfgOption6() const { + return (cfg_option6_); + } + /// @brief Returns information about the host in the textual format. std::string toText() const; @@ -447,6 +472,10 @@ private: ClientClasses dhcp4_client_classes_; /// @brief Collection of classes associated with a DHCPv6 client. ClientClasses dhcp6_client_classes_; + /// @brief Pointer to the DHCPv4 option data configuration for this host. + CfgOptionPtr cfg_option4_; + /// @brief Pointer to the DHCPv6 option data configuration for this host. + CfgOptionPtr cfg_option6_; }; /// @brief Pointer to the @c Host object. diff --git a/src/lib/dhcpsrv/tests/host_unittest.cc b/src/lib/dhcpsrv/tests/host_unittest.cc index 9fcb40e4a2..41b2678ff6 100644 --- a/src/lib/dhcpsrv/tests/host_unittest.cc +++ b/src/lib/dhcpsrv/tests/host_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2016 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 @@ -503,6 +503,134 @@ TEST(HostTest, addClientClasses) { EXPECT_TRUE(host->getClientClasses6().contains("bar")); } +// This test checks that it is possible to add DHCPv4 options for a host. +TEST(HostTest, addOptions4) { + Host host("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2), + IOAddress("192.0.2.3")); + + // Differentiate options by their codes (100-109) + for (uint16_t code = 100; code < 110; ++code) { + OptionPtr option(new Option(Option::V4, code, OptionBuffer(10, 0xFF))); + ASSERT_NO_THROW(host.getCfgOption4()->add(option, false, "dhcp4")); + } + + // Add 7 options to another option space. The option codes partially overlap + // with option codes that we have added to dhcp6 option space. + for (uint16_t code = 105; code < 112; ++code) { + OptionPtr option(new Option(Option::V4, code, OptionBuffer(10, 0xFF))); + ASSERT_NO_THROW(host.getCfgOption4()->add(option, false, "isc")); + } + + // Get options from the Subnet and check if all 10 are there. + OptionContainerPtr options = host.getCfgOption4()->getAll("dhcp4"); + ASSERT_TRUE(options); + ASSERT_EQ(10, options->size()); + + // It should be possible to retrieve DHCPv6 options but the container + // should be empty. + OptionContainerPtr options6 = host.getCfgOption6()->getAll("dhcp6"); + ASSERT_TRUE(options6); + EXPECT_TRUE(options6->empty()); + + // Also make sure that for dhcp6 option space no DHCPv4 options are + // returned. This is to check that containers for DHCPv4 and DHCPv6 + // options do not share information. + options6 = host.getCfgOption6()->getAll("dhcp4"); + ASSERT_TRUE(options6); + EXPECT_TRUE(options6->empty()); + + // Validate codes of options added to dhcp6 option space. + uint16_t expected_code = 100; + for (OptionContainer::const_iterator option_desc = options->begin(); + option_desc != options->end(); ++option_desc) { + ASSERT_TRUE(option_desc->option_); + EXPECT_EQ(expected_code, option_desc->option_->getType()); + ++expected_code; + } + + options = host.getCfgOption4()->getAll("isc"); + ASSERT_TRUE(options); + ASSERT_EQ(7, options->size()); + + // Validate codes of options added to isc option space. + expected_code = 105; + for (OptionContainer::const_iterator option_desc = options->begin(); + option_desc != options->end(); ++option_desc) { + ASSERT_TRUE(option_desc->option_); + EXPECT_EQ(expected_code, option_desc->option_->getType()); + ++expected_code; + } + + // Try to get options from a non-existing option space. + options = host.getCfgOption4()->getAll("abcd"); + ASSERT_TRUE(options); + EXPECT_TRUE(options->empty()); +} + +// This test checks that it is possible to add DHCPv6 options for a host. +TEST(HostTest, addOptions6) { + Host host("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2), + IOAddress("192.0.2.3")); + + // Differentiate options by their codes (100-109) + for (uint16_t code = 100; code < 110; ++code) { + OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF))); + ASSERT_NO_THROW(host.getCfgOption6()->add(option, false, "dhcp6")); + } + + // Add 7 options to another option space. The option codes partially overlap + // with option codes that we have added to dhcp6 option space. + for (uint16_t code = 105; code < 112; ++code) { + OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF))); + ASSERT_NO_THROW(host.getCfgOption6()->add(option, false, "isc")); + } + + // Get options from the Subnet and check if all 10 are there. + OptionContainerPtr options = host.getCfgOption6()->getAll("dhcp6"); + ASSERT_TRUE(options); + ASSERT_EQ(10, options->size()); + + // It should be possible to retrieve DHCPv6 options but the container + // should be empty. + OptionContainerPtr options4 = host.getCfgOption4()->getAll("dhcp4"); + ASSERT_TRUE(options4); + EXPECT_TRUE(options4->empty()); + + // Also make sure that for dhcp6 option space no DHCPv4 options are + // returned. This is to check that containers for DHCPv4 and DHCPv6 + // options do not share information. + options4 = host.getCfgOption4()->getAll("dhcp6"); + ASSERT_TRUE(options4); + EXPECT_TRUE(options4->empty()); + + // Validate codes of options added to dhcp6 option space. + uint16_t expected_code = 100; + for (OptionContainer::const_iterator option_desc = options->begin(); + option_desc != options->end(); ++option_desc) { + ASSERT_TRUE(option_desc->option_); + EXPECT_EQ(expected_code, option_desc->option_->getType()); + ++expected_code; + } + + options = host.getCfgOption6()->getAll("isc"); + ASSERT_TRUE(options); + ASSERT_EQ(7, options->size()); + + // Validate codes of options added to isc option space. + expected_code = 105; + for (OptionContainer::const_iterator option_desc = options->begin(); + option_desc != options->end(); ++option_desc) { + ASSERT_TRUE(option_desc->option_); + EXPECT_EQ(expected_code, option_desc->option_->getType()); + ++expected_code; + } + + // Try to get options from a non-existing option space. + options = host.getCfgOption6()->getAll("abcd"); + ASSERT_TRUE(options); + EXPECT_TRUE(options->empty()); +} + TEST(HostTest, getIdentifierAsText) { Host host1("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2), |