Commit fb5e1883 authored by Marcin Siodelski's avatar Marcin Siodelski

[master] Merge branch 'trac3560'

parents ad44a39d 33f53f5e
...@@ -14,7 +14,7 @@ CLEANFILES = *.gcno *.gcda ...@@ -14,7 +14,7 @@ CLEANFILES = *.gcno *.gcda
lib_LTLIBRARIES = libkea-dhcp++.la lib_LTLIBRARIES = libkea-dhcp++.la
libkea_dhcp___la_SOURCES = libkea_dhcp___la_SOURCES =
libkea_dhcp___la_SOURCES += classify.h libkea_dhcp___la_SOURCES += classify.cc classify.h
libkea_dhcp___la_SOURCES += dhcp6.h dhcp4.h libkea_dhcp___la_SOURCES += dhcp6.h dhcp4.h
libkea_dhcp___la_SOURCES += duid.cc duid.h libkea_dhcp___la_SOURCES += duid.cc duid.h
libkea_dhcp___la_SOURCES += hwaddr.cc hwaddr.h libkea_dhcp___la_SOURCES += hwaddr.cc hwaddr.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 <dhcp/classify.h>
#include <util/strutil.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/constants.hpp>
#include <boost/algorithm/string/split.hpp>
#include <vector>
namespace isc {
namespace dhcp {
ClientClasses::ClientClasses(const std::string& class_names)
: std::set<ClientClass>() {
std::vector<std::string> split_text;
boost::split(split_text, class_names, boost::is_any_of(","),
boost::algorithm::token_compress_off);
for (int i = 0; i < split_text.size(); ++i) {
std::string trimmed = util::str::trim(split_text[i]);
// Ignore empty class names.
if (!trimmed.empty()) {
insert(ClientClass(trimmed));
}
}
}
} // end of namespace isc::dhcp
} // end of namespace isc
...@@ -53,6 +53,17 @@ namespace dhcp { ...@@ -53,6 +53,17 @@ namespace dhcp {
/// documentation. See http://www.cplusplus.com/reference/set/set/. /// documentation. See http://www.cplusplus.com/reference/set/set/.
class ClientClasses : public std::set<ClientClass> { class ClientClasses : public std::set<ClientClass> {
public: public:
/// @brief Default constructor.
ClientClasses() : std::set<ClientClass>() {
}
/// @brief Constructor from comma separated values.
///
/// @param class_names A string containing a client classes separated
/// with commas. The class names are trimmed before insertion to the set.
ClientClasses(const std::string& class_names);
/// @brief returns if class x belongs to the defined classes /// @brief returns if class x belongs to the defined classes
/// ///
/// @param x client class to be checked /// @param x client class to be checked
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <boost/algorithm/string/constants.hpp> #include <boost/algorithm/string/constants.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <iomanip> #include <iomanip>
#include <cctype>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
...@@ -30,20 +31,20 @@ namespace dhcp { ...@@ -30,20 +31,20 @@ namespace dhcp {
DUID::DUID(const std::vector<uint8_t>& duid) { DUID::DUID(const std::vector<uint8_t>& duid) {
if (duid.size() > MAX_DUID_LEN) { if (duid.size() > MAX_DUID_LEN) {
isc_throw(OutOfRange, "DUID too large"); isc_throw(isc::BadValue, "DUID too large");
} }
if (duid.empty()) { if (duid.empty()) {
isc_throw(OutOfRange, "Empty DUIDs are not allowed"); isc_throw(isc::BadValue, "Empty DUIDs are not allowed");
} }
duid_ = duid; duid_ = duid;
} }
DUID::DUID(const uint8_t* data, size_t len) { DUID::DUID(const uint8_t* data, size_t len) {
if (len > MAX_DUID_LEN) { if (len > MAX_DUID_LEN) {
isc_throw(OutOfRange, "DUID too large"); isc_throw(isc::BadValue, "DUID too large");
} }
if (len == 0) { if (len == 0) {
isc_throw(OutOfRange, "Empty DUIDs/Client-ids not allowed"); isc_throw(isc::BadValue, "Empty DUIDs/Client-ids not allowed");
} }
duid_ = std::vector<uint8_t>(data, data + len); duid_ = std::vector<uint8_t>(data, data + len);
...@@ -58,19 +59,35 @@ DUID::decode(const std::string& text) { ...@@ -58,19 +59,35 @@ DUID::decode(const std::string& text) {
std::ostringstream s; std::ostringstream s;
for (size_t i = 0; i < split_text.size(); ++i) { for (size_t i = 0; i < split_text.size(); ++i) {
// If there are multiple tokens and the current one is empty, it // Check that only hexadecimal digits are used.
// means that two consecutive colons were specified. This is not size_t ch_index = 0;
// allowed for client identifier. while (ch_index < split_text[i].length()) {
if ((split_text.size() > 1) && split_text[i].empty()) { if (!isxdigit(split_text[i][ch_index])) {
isc_throw(isc::BadValue, "invalid identifier '" << text << "': " isc_throw(isc::BadValue, "invalid value '"
<< " tokens must be separated with a single colon"); << split_text[i][ch_index] << "' in"
<< " DUID '" << text << "'");
} else if (split_text[i].size() == 1) { }
s << "0"; ++ch_index;
} else if (split_text[i].size() > 2) {
isc_throw(isc::BadValue, "invalid identifier '" << text << "'");
} }
if (split_text.size() > 1) {
// If there are multiple tokens and the current one is empty, it
// means that two consecutive colons were specified. This is not
// allowed for client identifier.
if (split_text[i].empty()) {
isc_throw(isc::BadValue, "invalid identifier '"
<< text << "': " << " tokens must be"
" separated with a single colon");
} else if (split_text[i].size() > 2) {
isc_throw(isc::BadValue, "invalid identifier '"
<< text << "'");
}
}
if (split_text[i].size() % 2) {
s << "0";
}
s << split_text[i]; s << split_text[i];
} }
...@@ -133,7 +150,7 @@ bool DUID::operator!=(const DUID& other) const { ...@@ -133,7 +150,7 @@ bool DUID::operator!=(const DUID& other) const {
ClientId::ClientId(const std::vector<uint8_t>& clientid) ClientId::ClientId(const std::vector<uint8_t>& clientid)
: DUID(clientid) { : DUID(clientid) {
if (clientid.size() < MIN_CLIENT_ID_LEN) { if (clientid.size() < MIN_CLIENT_ID_LEN) {
isc_throw(OutOfRange, "client-id is too short (" << clientid.size() isc_throw(isc::BadValue, "client-id is too short (" << clientid.size()
<< "), at least 2 is required"); << "), at least 2 is required");
} }
} }
...@@ -142,7 +159,7 @@ ClientId::ClientId(const std::vector<uint8_t>& clientid) ...@@ -142,7 +159,7 @@ ClientId::ClientId(const std::vector<uint8_t>& clientid)
ClientId::ClientId(const uint8_t *clientid, size_t len) ClientId::ClientId(const uint8_t *clientid, size_t len)
: DUID(clientid, len) { : DUID(clientid, len) {
if (len < MIN_CLIENT_ID_LEN) { if (len < MIN_CLIENT_ID_LEN) {
isc_throw(OutOfRange, "client-id is too short (" << len isc_throw(isc::BadValue, "client-id is too short (" << len
<< "), at least 2 is required"); << "), at least 2 is required");
} }
} }
......
...@@ -98,8 +98,8 @@ class DUID { ...@@ -98,8 +98,8 @@ class DUID {
/// representing bytes of DUID must be separated by colons. Usually the /// representing bytes of DUID must be separated by colons. Usually the
/// single byte is represented by two hexadecimal digits. However, this /// single byte is represented by two hexadecimal digits. However, this
/// function allows one digit per byte. In this case, a zero is prepended /// function allows one digit per byte. In this case, a zero is prepended
/// before the conversion. For example, a DUID 0:1:2::4:5 equals to /// before the conversion. For example, a DUID 0:1:2:3:4:5 equals to
/// 00:01:02:00:04:05. /// 00:01:02:03:04:05.
/// ///
/// @param text DUID in the hexadecimal format with digits representing /// @param text DUID in the hexadecimal format with digits representing
/// individual bytes separated by colons. /// individual bytes separated by colons.
......
...@@ -34,14 +34,14 @@ HWAddr::HWAddr() ...@@ -34,14 +34,14 @@ HWAddr::HWAddr()
HWAddr::HWAddr(const uint8_t* hwaddr, size_t len, uint16_t htype) HWAddr::HWAddr(const uint8_t* hwaddr, size_t len, uint16_t htype)
:hwaddr_(hwaddr, hwaddr + len), htype_(htype) { :hwaddr_(hwaddr, hwaddr + len), htype_(htype) {
if (len > MAX_HWADDR_LEN) { if (len > MAX_HWADDR_LEN) {
isc_throw(InvalidParameter, "hwaddr length exceeds MAX_HWADDR_LEN"); isc_throw(isc::BadValue, "hwaddr length exceeds MAX_HWADDR_LEN");
} }
} }
HWAddr::HWAddr(const std::vector<uint8_t>& hwaddr, uint16_t htype) HWAddr::HWAddr(const std::vector<uint8_t>& hwaddr, uint16_t htype)
:hwaddr_(hwaddr), htype_(htype) { :hwaddr_(hwaddr), htype_(htype) {
if (hwaddr.size() > MAX_HWADDR_LEN) { if (hwaddr.size() > MAX_HWADDR_LEN) {
isc_throw(InvalidParameter, isc_throw(isc::BadValue,
"address vector size exceeds MAX_HWADDR_LEN"); "address vector size exceeds MAX_HWADDR_LEN");
} }
} }
......
// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -36,8 +36,7 @@ TEST(ClassifyTest, ClientClasses) { ...@@ -36,8 +36,7 @@ TEST(ClassifyTest, ClientClasses) {
EXPECT_FALSE(classes.contains("")); EXPECT_FALSE(classes.contains(""));
EXPECT_FALSE(classes.contains("alpha")); EXPECT_FALSE(classes.contains("alpha"));
EXPECT_FALSE(classes.contains("beta")); EXPECT_FALSE(classes.contains("beta"));
EXPECT_FALSE(classes.contains("gamma")); EXPECT_FALSE(classes.contains("gamma"));
classes.insert("beta"); classes.insert("beta");
EXPECT_FALSE(classes.contains("")); EXPECT_FALSE(classes.contains(""));
EXPECT_FALSE(classes.contains("alpha")); EXPECT_FALSE(classes.contains("alpha"));
...@@ -50,3 +49,39 @@ TEST(ClassifyTest, ClientClasses) { ...@@ -50,3 +49,39 @@ TEST(ClassifyTest, ClientClasses) {
EXPECT_TRUE (classes.contains("beta")); EXPECT_TRUE (classes.contains("beta"));
EXPECT_TRUE (classes.contains("gamma")); EXPECT_TRUE (classes.contains("gamma"));
} }
// Check if ClientClasses object can be created from the string of comma
// separated values.
TEST(ClassifyTest, ClientClassesFromString) {
{
ClientClasses classes("alpha, beta, gamma");
EXPECT_EQ(3, classes.size());
EXPECT_FALSE(classes.contains(""));
EXPECT_TRUE(classes.contains("alpha"));
EXPECT_TRUE(classes.contains("beta"));
EXPECT_TRUE(classes.contains("gamma"));
}
{
ClientClasses classes("alpha, , beta ,");
EXPECT_EQ(2, classes.size());
EXPECT_TRUE(classes.contains("alpha"));
EXPECT_FALSE(classes.contains(""));
EXPECT_TRUE(classes.contains("beta"));
}
{
ClientClasses classes("");
EXPECT_TRUE(classes.empty());
}
{
ClientClasses classes(" ");
EXPECT_TRUE(classes.empty());
}
{
ClientClasses classes(", ,, ,");
EXPECT_TRUE(classes.empty());
}
}
...@@ -84,24 +84,24 @@ TEST(DuidTest, size) { ...@@ -84,24 +84,24 @@ TEST(DuidTest, size) {
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<DUID> toolarge1(new DUID(data, MAX_DUID_LEN + 1)), scoped_ptr<DUID> toolarge1(new DUID(data, MAX_DUID_LEN + 1)),
OutOfRange); BadValue);
// that's one too much // that's one too much
data2.push_back(128); data2.push_back(128);
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<DUID> toolarge2(new DUID(data2)), scoped_ptr<DUID> toolarge2(new DUID(data2)),
OutOfRange); BadValue);
// empty duids are not allowed // empty duids are not allowed
vector<uint8_t> empty; vector<uint8_t> empty;
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<DUID> emptyDuid(new DUID(empty)), scoped_ptr<DUID> emptyDuid(new DUID(empty)),
OutOfRange); BadValue);
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<DUID> emptyDuid2(new DUID(data, 0)), scoped_ptr<DUID> emptyDuid2(new DUID(data, 0)),
OutOfRange); BadValue);
} }
// This test verifies if the implementation supports all defined // This test verifies if the implementation supports all defined
...@@ -222,33 +222,33 @@ TEST(ClientIdTest, size) { ...@@ -222,33 +222,33 @@ TEST(ClientIdTest, size) {
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<ClientId> toolarge1(new ClientId(data, MAX_CLIENT_ID_LEN + 1)), scoped_ptr<ClientId> toolarge1(new ClientId(data, MAX_CLIENT_ID_LEN + 1)),
OutOfRange); BadValue);
// that's one too much // that's one too much
data2.push_back(128); data2.push_back(128);
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<ClientId> toolarge2(new ClientId(data2)), scoped_ptr<ClientId> toolarge2(new ClientId(data2)),
OutOfRange); BadValue);
// empty client-ids are not allowed // empty client-ids are not allowed
vector<uint8_t> empty; vector<uint8_t> empty;
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<ClientId> empty_client_id1(new ClientId(empty)), scoped_ptr<ClientId> empty_client_id1(new ClientId(empty)),
OutOfRange); BadValue);
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<ClientId> empty_client_id2(new ClientId(data, 0)), scoped_ptr<ClientId> empty_client_id2(new ClientId(data, 0)),
OutOfRange); BadValue);
// client-id must be at least 2 bytes long // client-id must be at least 2 bytes long
vector<uint8_t> shorty(1,17); // just a single byte with value 17 vector<uint8_t> shorty(1,17); // just a single byte with value 17
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<ClientId> too_short_client_id1(new ClientId(shorty)), scoped_ptr<ClientId> too_short_client_id1(new ClientId(shorty)),
OutOfRange); BadValue);
EXPECT_THROW( EXPECT_THROW(
scoped_ptr<ClientId> too_short_client_id1(new ClientId(data, 1)), scoped_ptr<ClientId> too_short_client_id1(new ClientId(data, 1)),
OutOfRange); BadValue);
} }
// This test checks if the comparison operators are sane. // This test checks if the comparison operators are sane.
...@@ -299,6 +299,11 @@ TEST(ClientIdTest, fromText) { ...@@ -299,6 +299,11 @@ TEST(ClientIdTest, fromText) {
cid = ClientId::fromText("00:a:bb:D:ee:EF:ab") cid = ClientId::fromText("00:a:bb:D:ee:EF:ab")
); );
EXPECT_EQ("00:0a:bb:0d:ee:ef:ab", cid->toText()); EXPECT_EQ("00:0a:bb:0d:ee:ef:ab", cid->toText());
// ClientId without any colons is allowed.
ASSERT_NO_THROW(
cid = ClientId::fromText("0010abcdee");
);
EXPECT_EQ("00:10:ab:cd:ee", cid->toText());
// Repeated colon sign in the ClientId is not allowed. // Repeated colon sign in the ClientId is not allowed.
EXPECT_THROW( EXPECT_THROW(
ClientId::fromText("00::bb:D:ee:EF:ab"), ClientId::fromText("00::bb:D:ee:EF:ab"),
...@@ -310,6 +315,23 @@ TEST(ClientIdTest, fromText) { ...@@ -310,6 +315,23 @@ TEST(ClientIdTest, fromText) {
ClientId::fromText("00:01:021:03:04:05:06"), ClientId::fromText("00:01:021:03:04:05:06"),
isc::BadValue isc::BadValue
); );
// ClientId with two spaces between the colons should not be allowed.
EXPECT_THROW(
ClientId::fromText("00:01: :03:04:05:06"),
isc::BadValue
);
// ClientId with one space between the colons should not be allowed.
EXPECT_THROW(
ClientId::fromText("00:01: :03:04:05:06"),
isc::BadValue
);
// ClientId with three spaces between the colons should not be allowed.
EXPECT_THROW(
ClientId::fromText("00:01: :03:04:05:06"),
isc::BadValue
);
} }
......
...@@ -60,10 +60,10 @@ TEST(HWAddrTest, constructor) { ...@@ -60,10 +60,10 @@ TEST(HWAddrTest, constructor) {
// Check that over the limit data length throws exception // Check that over the limit data length throws exception
EXPECT_THROW(HWAddr(&big_data_vector[0], big_data_vector.size(), HTYPE_ETHER), EXPECT_THROW(HWAddr(&big_data_vector[0], big_data_vector.size(), HTYPE_ETHER),
InvalidParameter); BadValue);
// Check that over the limit vector throws exception // Check that over the limit vector throws exception
EXPECT_THROW(HWAddr(big_data_vector, HTYPE_ETHER), InvalidParameter); EXPECT_THROW(HWAddr(big_data_vector, HTYPE_ETHER), BadValue);
} }
// This test checks if the comparison operators are sane. // This test checks if the comparison operators are sane.
......
...@@ -58,6 +58,7 @@ libkea_dhcpsrv_la_SOURCES += dbaccess_parser.cc dbaccess_parser.h ...@@ -58,6 +58,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 += dhcpsrv_log.cc dhcpsrv_log.h
libkea_dhcpsrv_la_SOURCES += dhcp_config_parser.h libkea_dhcpsrv_la_SOURCES += dhcp_config_parser.h
libkea_dhcpsrv_la_SOURCES += dhcp_parsers.cc dhcp_parsers.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 += key_from_key.h
libkea_dhcpsrv_la_SOURCES += lease.cc lease.h libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
libkea_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h libkea_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h
...@@ -76,6 +77,7 @@ libkea_dhcpsrv_la_SOURCES += option_space_container.h ...@@ -76,6 +77,7 @@ libkea_dhcpsrv_la_SOURCES += option_space_container.h
libkea_dhcpsrv_la_SOURCES += pool.cc pool.h libkea_dhcpsrv_la_SOURCES += pool.cc pool.h
libkea_dhcpsrv_la_SOURCES += srv_config.cc srv_config.h libkea_dhcpsrv_la_SOURCES += srv_config.cc srv_config.h
libkea_dhcpsrv_la_SOURCES += subnet.cc subnet.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 += triplet.h
libkea_dhcpsrv_la_SOURCES += utils.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 <util/strutil.h>
#include <exceptions/exceptions.h>
namespace isc {
namespace dhcp {
IPv6Resrv::IPv6Resrv(const asiolink::IOAddress& prefix,
const uint8_t prefix_len)
: prefix_(asiolink::IOAddress("::")), prefix_len_(128) {
// Validate and set the actual values.
set(prefix, prefix_len);
}
void
IPv6Resrv::set(const asiolink::IOAddress& prefix, const uint8_t prefix_len) {
if (!prefix.isV6() || prefix.isV6Multicast()) {
isc_throw(isc::BadValue, "invalid prefix '" << prefix
<< " for new IPv6 reservation");
} else if (prefix_len > 128) {
isc_throw(isc::BadValue, "invalid prefix length '"
<< static_cast<int>(prefix_len)
<< "' for new IPv6 reservation");
}
prefix_ = prefix;
prefix_len_ = prefix_len;
}
bool
IPv6Resrv::operator==(const IPv6Resrv& other) const {
return (prefix_ == other.prefix_ &&
prefix_len_ == other.prefix_len_);
}
bool
IPv6Resrv::operator!=(const IPv6Resrv& other) const {
return (!operator==(other));
}
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,
const std::string& dhcp4_client_classes,
const std::string& dhcp6_client_classes)
: hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
// Initialize HWAddr or DUID
setIdentifier(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,
const std::string& dhcp4_client_classes,
const std::string& dhcp6_client_classes)
: hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation),
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
// Initialize HWAddr or DUID
setIdentifier(identifier, identifier_name);
}
void
Host::setIdentifier(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::setIdentifier(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");
}
}
void
Host::addReservation(const IPv6Resrv& reservation) {
ipv6_reservations_.insert(IPv6ResrvTuple(reservation.getType(),
reservation));
}
IPv6ResrvRange
Host::getIPv6Reservations(const IPv6Resrv::Type& type) const {
return (ipv6_reservations_.equal_range(type));
}
void
Host::addClientClassInternal(ClientClasses& classes,