Commit e205a10d authored by Marcin Siodelski's avatar Marcin Siodelski

[3560] Basic implementation of the Host class.

parent 728359ea
......@@ -57,6 +57,7 @@ libkea_dhcpsrv_la_SOURCES += dbaccess_parser.cc dbaccess_parser.h
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
......@@ -75,6 +76,7 @@ libkea_dhcpsrv_la_SOURCES += option_space_container.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
......
// 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
// 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
// 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
......@@ -64,6 +64,7 @@ libdhcpsrv_unittests_SOURCES += d2_client_unittest.cc
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
......
// 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
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