From: Marcin Siodelski Date: Wed, 8 Aug 2012 18:03:13 +0000 (+0200) Subject: [1959] Added generation of DUID prefix if it is not given by user. X-Git-Tag: trac2351_base~47^2~11^2~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=967e3ec6188b8a41e7f830bd13deda30afe5fa44;p=thirdparty%2Fkea.git [1959] Added generation of DUID prefix if it is not given by user. --- diff --git a/tests/tools/perfdhcp/command_options.cc b/tests/tools/perfdhcp/command_options.cc index 55380d086b..210ed04920 100644 --- a/tests/tools/perfdhcp/command_options.cc +++ b/tests/tools/perfdhcp/command_options.cc @@ -20,8 +20,10 @@ #include #include #include +#include #include +#include #include #include "command_options.h" @@ -367,6 +369,12 @@ CommandOptions::initialize(int argc, char** argv) { isc_throw(InvalidParameter, "without an inteface server is required"); } + + // If DUID is not specified from command line we need to + // generate one. + if (duid_prefix_.size() == 0) { + generateDuidPrefix(); + } } void @@ -476,6 +484,36 @@ CommandOptions::decodeDuid(const std::string& base) { } } +void +CommandOptions::generateDuidPrefix() { + using namespace boost::posix_time; + // Duid prefix will be most likely generated only once but + // it is ok if it is called more then once so we simply + // regenerate it and discard previous value. + duid_prefix_.clear(); + const uint8_t duid_prefix_len = 14; + duid_prefix_.resize(duid_prefix_len); + // The first four octets consist of DUID LLT and hardware type. + duid_prefix_[0] = DUID_LLT >> 8; + duid_prefix_[1] = DUID_LLT & 0xff; + duid_prefix_[2] = HWTYPE_ETHERNET >> 8; + duid_prefix_[3] = HWTYPE_ETHERNET & 0xff; + + // As described in RFC3315: 'the time value is the time + // that the DUID is generated represented in seconds + // since midnight (UTC), January 1, 2000, modulo 2^32.' + ptime now = microsec_clock::universal_time(); + ptime duid_epoch(from_iso_string("20000101T000000")); + time_period period(duid_epoch, now); + uint32_t duration_sec = htonl(period.length().total_seconds()); + memcpy(&duid_prefix_[4], &duration_sec, 4); + + // Set link layer address (6 octets). This value may be + // randomized before sending a packet to simulate different + // clients. + memcpy(&duid_prefix_[8], &mac_prefix_[0], 6); +} + uint8_t CommandOptions::convertHexString(const std::string& text) const { unsigned int ui = 0; diff --git a/tests/tools/perfdhcp/command_options.h b/tests/tools/perfdhcp/command_options.h index 459efa598b..b75c43864c 100644 --- a/tests/tools/perfdhcp/command_options.h +++ b/tests/tools/perfdhcp/command_options.h @@ -346,6 +346,12 @@ private: /// \param base Base string given as -b duid=0F1234 /// \throws isc::InvalidParameter if DUID is invalid void decodeDuid(const std::string& base); + + /// \brief Generates DUID-LLT (based on link layer address). + /// + /// Function generates DUID based on link layer address and + /// initiates duid_prefix_ value with it. + void generateDuidPrefix(); /// \brief Converts two-digit hexadecimal string to a byte /// diff --git a/tests/tools/perfdhcp/tests/command_options_unittest.cc b/tests/tools/perfdhcp/tests/command_options_unittest.cc index 669d792bb5..e3e3384b22 100644 --- a/tests/tools/perfdhcp/tests/command_options_unittest.cc +++ b/tests/tools/perfdhcp/tests/command_options_unittest.cc @@ -71,11 +71,25 @@ protected: EXPECT_EQ(0, opt.getClientsNum()); // default mac - uint8_t mac[6] = { 0x00, 0x0C, 0x01, 0x02, 0x03, 0x04 }; + const uint8_t mac[6] = { 0x00, 0x0C, 0x01, 0x02, 0x03, 0x04 }; std::vector v1 = opt.getMacPrefix(); ASSERT_EQ(6, v1.size()); EXPECT_TRUE(std::equal(v1.begin(), v1.end(), mac)); + // Check if DUID is initialized. The DUID-LLT is expected + // to start with DUID_LLT value of 1 and hardware ethernet + // type equal to 1 (HWETHER_TYPE). + const uint8_t duid_llt_and_hw[4] = { 0x0, 0x1, 0x0, 0x1 }; + // We assume DUID-LLT length 14. This includes 4 octets of + // DUID_LLT value, two octets of hardware type, 4 octets + // of time value and 6 octets of variable link layer (MAC) + // address. + const int duid_llt_size = 14; + std::vector v2 = opt.getDuidPrefix(); + ASSERT_EQ(duid_llt_size, opt.getDuidPrefix().size()); + EXPECT_TRUE(std::equal(v2.begin(), v2.begin() + 4, + duid_llt_and_hw)); + EXPECT_EQ(0, opt.getBase().size()); EXPECT_EQ(0, opt.getNumRequests().size()); EXPECT_EQ(0, opt.getPeriod());