summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/dhcpsrv/host.cc8
-rw-r--r--src/lib/dhcpsrv/host.h31
-rw-r--r--src/lib/dhcpsrv/tests/host_unittest.cc130
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),