Commit 5ff43d80 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[2140] DUID is now a separate class in separate files

parent 2c7936f0
......@@ -29,6 +29,7 @@ libb10_dhcp___la_SOURCES += option4_addrlst.cc option4_addrlst.h
libb10_dhcp___la_SOURCES += dhcp6.h dhcp4.h
libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h
libb10_dhcp___la_SOURCES += pkt4.cc pkt4.h
libb10_dhcp___la_SOURCES += duid.cc duid.h
EXTRA_DIST = README
#EXTRA_DIST += log_messages.mes
......
// Copyright (C) 2012 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 <vector>
#include <exceptions/exceptions.h>
#include <dhcp/duid.h>
namespace isc {
namespace dhcp {
DUID::DUID(const std::vector<uint8_t>& duid) {
if (duid.size() > MAX_DUID_LEN) {
isc_throw(OutOfRange, "DUID too large");
} else {
duid_ = duid;
}
}
DUID::DUID(const uint8_t * data, size_t len) {
if (len > MAX_DUID_LEN) {
isc_throw(OutOfRange, "DUID too large");
}
duid_ = std::vector<uint8_t>(data, data + len);
}
const std::vector<uint8_t>& DUID::getDuid() const {
return duid_;
}
DUID::DUIDType DUID::getType() const {
if (duid_.size() < 2) {
return (DUID_UNKNOWN);
}
uint16_t type = (duid_[0] << 8) + duid_[1];
if (type < DUID_MAX) {
return (static_cast<DUID::DUIDType>(type));
} else {
return (DUID_UNKNOWN);
}
}
bool DUID::operator == (const DUID& other) const {
return (this->duid_ == other.duid_);
}
bool DUID::operator != (const DUID& other) const {
return (this->duid_ != other.duid_);
}
}; // end of isc::dhcp namespace
}; // end of isc namespace
// Copyright (C) 2012 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 <stdint.h>
#include <unistd.h>
#include <vector>
namespace isc {
namespace dhcp {
/// @brief Holds DUID (DHCPv6 Unique Identifier)
///
/// This class holds DUID, that is used in client-id, server-id and
/// several other options. It is used to identify DHCPv6 entity.
class DUID {
public:
/// @brief maximum duid size
/// As defined in RFC3315, section 9.1
static const size_t MAX_DUID_LEN = 128;
/// @brief specifies DUID type
typedef enum {
DUID_UNKNOWN = 0, ///< invalid/unknown type
DUID_LLT = 1, ///< link-layer + time, see RFC3315, section 9.2
DUID_EN = 2, ///< enterprise-id, see RFC3315, section 9.3
DUID_LL = 3, ///< link-layer, see RFC3315, section 9.4
DUID_UUID = 4, ///< UUID, see RFC6355
DUID_MAX ///< not a real type, just maximum defined value + 1
} DUIDType;
/// @brief creates a DUID
DUID(const std::vector<uint8_t>& duid);
/// @brief creates a DUID
DUID(const uint8_t *duid, size_t len);
/// @brief returns a const reference to the actual DUID value
///
/// Note: This reference is only valid as long as the DUID
/// that returned it.
const std::vector<uint8_t>& getDuid() const;
/// @brief returns DUID type
DUIDType getType() const;
// compares two DUIDs
bool operator == (const DUID& other) const;
// compares two DUIDs
bool operator != (const DUID& other) const;
protected:
/// the actual content of the DUID
std::vector<uint8_t> duid_;
};
}; // end of isc::dhcp namespace
}; // end of isc namespace
......@@ -18,6 +18,8 @@
#include <map>
#include <asiolink/io_address.h>
#include <boost/shared_ptr.hpp>
#include <dhcp/option.h>
#include <dhcp/duid.h>
namespace isc {
namespace dhcp {
......@@ -35,31 +37,6 @@ class ClientId {
std::vector<uint8_t> clientid_;
};
/// @brief Holds DUID (DHCPv6 Unique Identifier)
///
/// This class holds DUID, that is used in client-id, server-id and
/// several other options. It is used to identify DHCPv6 entity.
class DUID {
/// @brief specifies DUID type
typedef enum {
DUID_UNKNOWN = 0, // invalid/unknown type
DUID_LLT = 1, // link-layer + time, see RFC3315, section 9.2
DUID_EN = 2, // enterprise-id, see RFC3315, section 9.3
DUID_LL = 3, // link-layer, see RFC3315, section 9.4
DUID_UUID = 4, // UUID, see RFC6355
} DUIDType;
public:
DUID(const std::vector<uint8_t>& duid);
DUID(const char *duid, size_t len);
const std::vector<uint8_t> getDuid() const;
DUIDType getType();
bool operator == (const DUID& other);
protected:
std::vector<uint8_t> duid_;
};
/// @brief Structure that holds a lease for IPv4 address
///
/// For performance reasons it is a simple structure, not a class. If we chose
......@@ -79,13 +56,15 @@ struct Lease4 {
uint32_t ext_; /// address extension
/// @brief hardware address
std::vector<uint8_t> hwaddr;
std::vector<uint8_t> hwaddr_;
/// @brief client identifier
std::vector<uint8_t> client_id;
std::vector<uint8_t> client_id_;
/// valid lifetime timestamp
uint32_t valid_lft;
/// @brief valid lifetime
///
/// Expressed as number of seconds since cltt
uint32_t valid_lft_;
/// @brief Recycle timer
///
......@@ -93,44 +72,45 @@ struct Lease4 {
/// or expired. This timer specifies number of seconds that it should be kept
/// after release or expiration, in case the client returns. This feature is not
/// currently used and this value is set to 0.
uint32_t recycle_time;
uint32_t recycle_time_;
/// @brief client last transmission time
///
/// Specifies a timestamp, when last transmission from a client was received.
time_t cltt;
time_t cltt_;
/// @brief Pool identifier
///
/// Specifies pool-id of the pool that the lease belongs to
uint32_t pool_id;
uint32_t pool_id_;
/// @brief Is this a fixed lease?
///
/// Fixed leases are kept after they are released/expired.
bool fixed;
bool fixed_;
/// @brief client hostname
///
/// This field may be empty
std::string hostname;
std::string hostname_;
/// @brief did we update AAAA record for this lease?
bool fqdn_fwd;
bool fqdn_fwd_;
/// @brief did we update PTR record for this lease?
bool fqdn_rev;
bool fqdn_rev_;
/// @brief additional options stored with this lease
///
/// Currently not used.
std::string options;
/// This field is currently not used.
/// @todo We need a way to store options in the databased.
Option::OptionCollection options_;
/// @brief Lease comments.
///
/// Currently not used. It may be used for keeping comments made by the
/// system administrator.
std::string comments;
std::string comments_;
};
/// @brief Pointer to a Lease4 structure.
......
......@@ -39,6 +39,7 @@ libdhcp___unittests_SOURCES += ../option4_addrlst.cc ../option4_addrlst.h option
libdhcp___unittests_SOURCES += ../option.h ../option.cc option_unittest.cc
libdhcp___unittests_SOURCES += ../pkt6.h ../pkt6.cc pkt6_unittest.cc
libdhcp___unittests_SOURCES += ../pkt4.h ../pkt4.cc pkt4_unittest.cc
libdhcp___unittests_SOURCES += ../duid.h ../duid.cc duid_unittest.cc
libdhcp___unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
libdhcp___unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
......
// Copyright (C) 2011 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 <iostream>
#include <sstream>
#include <arpa/inet.h>
#include <gtest/gtest.h>
#include <exceptions/exceptions.h>
#include <boost/scoped_ptr.hpp>
#include <dhcp/duid.h>
using namespace std;
using namespace isc;
using namespace isc::dhcp;
// don't import the entire boost namespace. It will unexpectedly hide uint8_t
// for some systems.
using boost::scoped_ptr;
namespace {
TEST(DuidTest, constructor) {
uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
vector<uint8_t> data2(data1, data1 + sizeof(data1));
scoped_ptr<DUID> duid1(new DUID(data1, sizeof(data1)));
scoped_ptr<DUID> duid2(new DUID(data2));
vector<uint8_t> vecdata = duid1->getDuid();
EXPECT_EQ(data2, vecdata);
EXPECT_EQ(DUID::DUID_LLT, duid1->getType());
vecdata = duid2->getDuid();
EXPECT_EQ(data2, vecdata);
EXPECT_EQ(DUID::DUID_LLT, duid2->getType());
}
TEST(DuidTest, size) {
const int MAX_DUID_SIZE = 128;
uint8_t data[MAX_DUID_SIZE + 1];
vector<uint8_t> data2;
for (uint8_t i = 0; i < MAX_DUID_SIZE + 1; ++i) {
data[i] = i;
if (i < MAX_DUID_SIZE)
data2.push_back(i);
}
ASSERT_EQ(data2.size(), MAX_DUID_SIZE);
scoped_ptr<DUID> duidmaxsize1(new DUID(data, MAX_DUID_SIZE));
scoped_ptr<DUID> duidmaxsize2(new DUID(data2));
EXPECT_THROW(
scoped_ptr<DUID> toolarge1(new DUID(data, MAX_DUID_SIZE + 1)),
OutOfRange);
// that's one too much
data2.push_back(128);
EXPECT_THROW(
scoped_ptr<DUID> toolarge2(new DUID(data2)),
OutOfRange);
}
TEST(DuidTest, getType) {
uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6};
uint8_t en[] = {0, 2, 2, 3, 4, 5, 6};
uint8_t ll[] = {0, 3, 2, 3, 4, 5, 6};
uint8_t uuid[] = {0, 4, 2, 3, 4, 5, 6};
uint8_t invalid[] = {0,55, 2, 3, 4, 5, 6};
scoped_ptr<DUID> duid_llt(new DUID(llt, sizeof(llt)));
scoped_ptr<DUID> duid_en(new DUID(en, sizeof(en)));
scoped_ptr<DUID> duid_ll(new DUID(ll, sizeof(ll)));
scoped_ptr<DUID> duid_uuid(new DUID(uuid, sizeof(uuid)));
scoped_ptr<DUID> duid_invalid(new DUID(invalid, sizeof(invalid)));
EXPECT_EQ(DUID::DUID_LLT, duid_llt->getType());
EXPECT_EQ(DUID::DUID_EN, duid_en->getType());
EXPECT_EQ(DUID::DUID_LL, duid_ll->getType());
EXPECT_EQ(DUID::DUID_UUID, duid_uuid->getType());
EXPECT_EQ(DUID::DUID_UNKNOWN, duid_invalid->getType());
}
TEST(DuidTest, operators) {
uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
uint8_t data2[] = {0, 1, 2, 3, 4};
uint8_t data3[] = {0, 1, 2, 3, 4, 5, 7}; // last digit different
uint8_t data4[] = {0, 1, 2, 3, 4, 5, 6}; // the same as 1
scoped_ptr<DUID> duid1(new DUID(data1, sizeof(data1)));
scoped_ptr<DUID> duid2(new DUID(data2, sizeof(data2)));
scoped_ptr<DUID> duid3(new DUID(data3, sizeof(data3)));
scoped_ptr<DUID> duid4(new DUID(data4, sizeof(data4)));
EXPECT_TRUE(*duid1 == *duid4);
EXPECT_FALSE(*duid1 == *duid2);
EXPECT_FALSE(*duid1 == *duid3);
EXPECT_FALSE(*duid1 != *duid4);
EXPECT_TRUE(*duid1 != *duid2);
EXPECT_TRUE(*duid1 != *duid3);
}
} // 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