libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h
libkea_dhcpsrv_la_SOURCES += dhcp_config_parser.h
libkea_dhcpsrv_la_SOURCES += dhcp_parsers.cc dhcp_parsers.h
+libkea_dhcpsrv_la_SOURCES += host.cc host.h
libkea_dhcpsrv_la_SOURCES += key_from_key.h
libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
libkea_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h
libkea_dhcpsrv_la_SOURCES += pool.cc pool.h
libkea_dhcpsrv_la_SOURCES += srv_config.cc srv_config.h
libkea_dhcpsrv_la_SOURCES += subnet.cc subnet.h
+libkea_dhcpsrv_la_SOURCES += subnet_id.h
libkea_dhcpsrv_la_SOURCES += triplet.h
libkea_dhcpsrv_la_SOURCES += utils.h
--- /dev/null
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <dhcpsrv/host.h>
+#include <exceptions/exceptions.h>
+
+namespace isc {
+namespace dhcp {
+
+Host::Host(const uint8_t* identifier, const size_t identifier_len,
+ const IdentifierType& identifier_type,
+ const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
+ const asiolink::IOAddress& ipv4_reservation,
+ const std::string& hostname)
+ : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
+ ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
+ hostname_(hostname), dhcp4_client_classes_(), dhcp6_client_classes_() {
+
+ decodeIdentifier(identifier, identifier_len, identifier_type);
+}
+
+Host::Host(const std::string& identifier, const std::string& identifier_name,
+ const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
+ const asiolink::IOAddress& ipv4_reservation,
+ const std::string& hostname)
+ : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
+ ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
+ hostname_(hostname), dhcp4_client_classes_(), dhcp6_client_classes_() {
+
+ decodeIdentifier(identifier, identifier_name);
+}
+
+void
+Host::decodeIdentifier(const uint8_t* identifier, const size_t len,
+ const IdentifierType& type) {
+ switch (type) {
+ case IDENT_HWADDR:
+ hw_address_ = HWAddrPtr(new HWAddr(identifier, len, HTYPE_ETHER));
+ duid_.reset();
+ break;
+ case IDENT_DUID:
+ duid_ = DuidPtr(new DUID(identifier, len));
+ hw_address_.reset();
+ break;
+ default:
+ isc_throw(isc::BadValue, "invalid client identifier type '"
+ << static_cast<int>(type) << "' when creating host "
+ " instance");
+ }
+}
+
+void
+Host::decodeIdentifier(const std::string& identifier, const std::string& name) {
+ if (name == "hw-address") {
+ hw_address_ = HWAddrPtr(new HWAddr(HWAddr::fromText(identifier)));
+ duid_.reset();
+ } else if (name == "duid") {
+ duid_ = DuidPtr(new DUID(DUID::fromText(identifier)));
+ hw_address_.reset();
+ } else {
+ isc_throw(isc::BadValue, "invalid client identifier type '"
+ << name << "' when creating host instance");
+ }
+}
+
+
+} // end of namespace isc::dhcp
+} // end of namespace isc
--- /dev/null
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef HOST_H
+#define HOST_H
+
+#include <asiolink/io_address.h>
+#include <dhcp/classify.h>
+#include <dhcp/duid.h>
+#include <dhcp/hwaddr.h>
+#include <dhcpsrv/subnet_id.h>
+#include <list>
+#include <map>
+#include <string>
+#include <utility>
+
+namespace isc {
+namespace dhcp {
+
+class IPv6Resrv {
+public:
+
+ enum Type {
+ TYPE_NA,
+ TYPE_PD
+ };
+
+ IPv6Resrv(const asiolink::IOAddress& address,
+ const uint8_t prefix_len = 128)
+ : address_(address), prefix_len_(prefix_len) {
+ }
+
+ const asiolink::IOAddress& getAddress() const {
+ return (address_);
+ }
+
+ uint8_t getPrefixLen() const {
+ return (prefix_len_);
+ }
+
+ Type getType() const {
+ return (prefix_len_ == 128 ? TYPE_NA : TYPE_PD);
+ }
+
+ void set(const asiolink::IOAddress& address, const uint8_t prefix_len) {
+ address_ = address;
+ prefix_len_ = prefix_len;
+ }
+
+private:
+ asiolink::IOAddress address_;
+ uint8_t prefix_len_;
+
+};
+
+/// @brief Collection of IPv6 reservations for the host.
+typedef std::multimap<IPv6Resrv::Type, IPv6Resrv> IPv6ResrvCollection;
+typedef IPv6ResrvCollection::iterator IPv6ResrvIterator;
+typedef std::pair<IPv6ResrvIterator, IPv6ResrvIterator> IPv6ResrvRange;
+
+class Host {
+public:
+
+ enum IdentifierType {
+ IDENT_HWADDR,
+ IDENT_DUID
+ };
+
+ Host(const uint8_t* identifier, const size_t identifier_len,
+ const IdentifierType& identifier_type,
+ const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
+ const asiolink::IOAddress& ipv4_reservation,
+ const std::string& hostname = "");
+
+ Host(const std::string& identifier, const std::string& identifier_name,
+ const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
+ const asiolink::IOAddress& ipv4_reservation,
+ const std::string& hostname = "");
+
+ void addReservation(const IPv6Resrv& reservation);
+
+ void setIdentifier(const uint8_t* identifier, const size_t identifier_len,
+ const IdentifierType& identifier_type);
+
+ void setIdentifier(const std::string& identifier, const std::string& name);
+
+ HWAddrPtr getHWAddress() const {
+ return (hw_address_);
+ }
+
+ DuidPtr getDuid() const {
+ return (duid_);
+ }
+
+ SubnetID getIPv4SubnetID() const {
+ return (ipv4_subnet_id_);
+ }
+
+ SubnetID getIPv6SubnetID() const {
+ return (ipv6_subnet_id_);
+ }
+
+ const asiolink::IOAddress& getIPv4Reservation() const {
+ return (ipv4_reservation_);
+ }
+
+ IPv6ResrvRange getIPv6Reservations(const IPv6Resrv& type) const;
+
+ const std::string& getHostname() const {
+ return (hostname_);
+ }
+
+ const ClientClasses& getClientClasses4() const {
+ return (dhcp4_client_classes_);
+ }
+
+ const ClientClasses& getClientClasses6() const {
+ return (dhcp6_client_classes_);
+ }
+
+private:
+
+ void decodeIdentifier(const uint8_t* identifier, const size_t len,
+ const IdentifierType& type);
+
+ void decodeIdentifier(const std::string& identifier,
+ const std::string& name);
+
+ HWAddrPtr hw_address_;
+ DuidPtr duid_;
+ SubnetID ipv4_subnet_id_;
+ SubnetID ipv6_subnet_id_;
+ asiolink::IOAddress ipv4_reservation_;
+ IPv6ResrvCollection ipv6_reservations_;
+ std::string hostname_;
+ ClientClasses dhcp4_client_classes_;
+ ClientClasses dhcp6_client_classes_;
+};
+
+}
+}
+
+#endif // HOST_H
--- /dev/null
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef SUBNET_ID_H
+#define SUBNET_ID_H
+
+namespace isc {
+namespace dhcp {
+
+/// @brief Defines unique IPv4 or IPv6 subnet identifier.
+///
+/// Each subnet for which the DHCP service has been configured is identifed
+/// by the unique value called subnet id. Right now it is represented as
+/// a simple unsiged integer. In the future it may be extended to more complex
+/// type.
+typedef uint32_t SubnetID;
+
+}
+}
+
+#endif // SUBNET_ID_H
libdhcpsrv_unittests_SOURCES += d2_udp_unittest.cc
libdhcpsrv_unittests_SOURCES += daemon_unittest.cc
libdhcpsrv_unittests_SOURCES += dbaccess_parser_unittest.cc
+libdhcpsrv_unittests_SOURCES += host_unittest.cc
libdhcpsrv_unittests_SOURCES += lease_file_io.cc lease_file_io.h
libdhcpsrv_unittests_SOURCES += lease_unittest.cc
libdhcpsrv_unittests_SOURCES += lease_mgr_factory_unittest.cc
--- /dev/null
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+
+#include <dhcpsrv/host.h>
+#include <boost/scoped_ptr.hpp>
+#include <gtest/gtest.h>
+
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
+
+namespace {
+
+TEST(IPv6ResrvTest, constructorAddress) {
+ IPv6Resrv resrv(IOAddress("2001:db8:1::cafe"));
+ EXPECT_EQ("2001:db8:1::cafe", resrv.getAddress().toText());
+ EXPECT_EQ(128, resrv.getPrefixLen());
+ EXPECT_EQ(IPv6Resrv::TYPE_NA, resrv.getType());
+}
+
+TEST(IPv6ResrvTest, constructorPrefix) {
+ IPv6Resrv resrv(IOAddress("2001:db8:1::"), 64);
+ EXPECT_EQ("2001:db8:1::", resrv.getAddress().toText());
+ EXPECT_EQ(64, resrv.getPrefixLen());
+ EXPECT_EQ(IPv6Resrv::TYPE_PD, resrv.getType());
+}
+
+TEST(IPv6ResrvTest, setPrefix) {
+ IPv6Resrv resrv(IOAddress("2001:db8:1::1"));
+ ASSERT_EQ("2001:db8:1::1", resrv.getAddress().toText());
+ ASSERT_EQ(128, resrv.getPrefixLen());
+ ASSERT_EQ(IPv6Resrv::TYPE_NA, resrv.getType());
+
+ ASSERT_NO_THROW(resrv.set(IOAddress("2001:db8::"), 48));
+ EXPECT_EQ("2001:db8::", resrv.getAddress().toText());
+ EXPECT_EQ(48, resrv.getPrefixLen());
+ EXPECT_EQ(IPv6Resrv::TYPE_PD, resrv.getType());
+}
+
+TEST(HostTest, createFromHWAddrString) {
+ boost::scoped_ptr<Host> host;
+ ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address",
+ SubnetID(1), SubnetID(2),
+ IOAddress("192.0.2.3"),
+ "somehost.example.org")));
+
+ HWAddrPtr hwaddr = host->getHWAddress();
+ ASSERT_TRUE(hwaddr);
+
+ EXPECT_EQ("hwtype=1 01:02:03:04:05:06", hwaddr->toText());
+
+ EXPECT_FALSE(host->getDuid());
+ EXPECT_EQ(1, host->getIPv4SubnetID());
+ EXPECT_EQ(2, host->getIPv6SubnetID());
+ EXPECT_EQ("192.0.2.3", host->getIPv4Reservation().toText());
+ EXPECT_EQ("somehost.example.org", host->getHostname());
+
+ // Use invalid identifier name
+ EXPECT_THROW(Host("01:02:03:04:05:06", "bogus", SubnetID(1), SubnetID(2),
+ IOAddress("192.0.2.3"), "somehost.example.org"),
+ isc::BadValue);
+
+ // Use invalid HW address.
+ EXPECT_THROW(Host("010203040506", "hw-address", SubnetID(1), SubnetID(2),
+ IOAddress("192.0.2.3"), "somehost.example.org"),
+ isc::BadValue);
+}
+
+TEST(HostTest, createFromDUIDString) {
+ boost::scoped_ptr<Host> host;
+ /* ASSERT_NO_THROW(host.reset(new Host("a1:b2:c3:d4:e5:06", "duid",
+ SubnetID(10), SubnetID(20),
+ IOAddress("192.0.2.5"),
+ "me.example.org"))); */
+
+ try {
+ host.reset(new Host("a1:b2:c3:d4:e5:06", "duid",
+ SubnetID(10), SubnetID(20),
+ IOAddress("192.0.2.5"),
+ "me.example.org"));
+ } catch (const std::exception& ex) {
+ std::cout << ex.what() << std::endl;
+ }
+
+ DuidPtr duid = host->getDuid();
+ ASSERT_TRUE(duid);
+
+ EXPECT_EQ("a1:b2:c3:d4:e5:06", duid->toText());
+
+ /* EXPECT_FALSE(host->getDuid());
+ EXPECT_EQ(1, host->getIPv4SubnetID());
+ EXPECT_EQ(2, host->getIPv6SubnetID());
+ EXPECT_EQ("192.0.2.3", host->getIPv4Reservation().toText());
+ EXPECT_EQ("somehost.example.org", host->getHostname());
+
+ // Use invalid identifier name
+ EXPECT_THROW(Host("01:02:03:04:05:06", "bogus", SubnetID(1), SubnetID(2),
+ IOAddress("192.0.2.3"), "somehost.example.org"),
+ isc::BadValue);
+
+ // Use invalid HW address.
+ EXPECT_THROW(Host("010203040506", "hw-address", SubnetID(1), SubnetID(2),
+ IOAddress("192.0.2.3"), "somehost.example.org"),
+ isc::BadValue); */
+}
+
+
+
+} // end of anonymous namespace