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
--- /dev/null
+// 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
--- /dev/null
+// 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
#include <map>
#include <asiolink/io_address.h>
#include <boost/shared_ptr.hpp>
+#include <dhcp/option.h>
+#include <dhcp/duid.h>
namespace isc {
namespace dhcp {
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
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
///
/// 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;
+ /// @brief did we update PTR record for this lease?
+ 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.
/// 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
///
/// @brief did we update AAAA record for this lease?
bool fqdn_fwd;
- /// @brief did we update PTR record for this lease?
+ /// @brief did we update PTR record for this lease?
bool fqdn_rev;
/// @brief additional options stored with this lease
/// That field is currently not used. We may keep extra options assigned
/// for leasequery and possibly other purposes.
/// @todo: Define this as a container of options
- std::string options;
+ std::string options;
/// @brief /// comments on that lease
///
/// (currently not used)
- std::string comments;
+ std::string comments;
};
/// @brief Pointer to a Lease6 structure.
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)
--- /dev/null
+// 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