Commit 967e3ec6 authored by Marcin Siodelski's avatar Marcin Siodelski

[1959] Added generation of DUID prefix if it is not given by user.

parent 25ae3625
......@@ -20,8 +20,10 @@
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <exceptions/exceptions.h>
#include <dhcp/dhcp6.h>
#include <dhcp/iface_mgr.h>
#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;
......
......@@ -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
///
......
......@@ -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<uint8_t> 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<uint8_t> 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());
......
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