27 const size_t DUID_TYPE_LEN = 2;
30 const size_t MIN_MAC_LEN = 6;
33 const size_t ENTERPRISE_ID_LEN = 4;
36 const size_t DUID_EN_IDENTIFIER_LEN = 6;
43 DUIDFactory::DUIDFactory(
const std::string& storage_location)
44 : storage_location_(
trim(storage_location)), duid_() {
49 return (!storage_location_.empty());
54 const std::vector<uint8_t>& ll_identifier) {
61 uint16_t htype_current = 0;
62 uint32_t time_current = 0;
63 std::vector<uint8_t> identifier_current;
67 std::vector<uint8_t> duid_vec = duid_->getDuid();
68 if ((duid_->getType() ==
DUID::DUID_LLT) && (duid_vec.size() > 8)) {
69 htype_current =
readUint16(&duid_vec[2], duid_vec.size() - 2);
70 time_current =
readUint32(&duid_vec[4], duid_vec.size() - 4);
71 identifier_current.assign(duid_vec.begin() + 8, duid_vec.end());
75 uint32_t time_out = time_in;
79 time_out = (time_current != 0 ? time_current :
83 std::vector<uint8_t> ll_identifier_out = ll_identifier;
84 uint16_t htype_out = htype;
89 if (ll_identifier_out.empty()) {
91 if (identifier_current.empty()) {
92 createLinkLayerId(ll_identifier_out, htype_out);
95 ll_identifier_out = identifier_current;
96 htype_out = htype_current;
99 }
else if (htype_out == 0) {
102 htype_out = ((htype_current != 0) ? htype_current :
108 std::vector<uint8_t> duid_out(DUID_TYPE_LEN +
sizeof(time_out) +
113 duid_out.insert(duid_out.end(), ll_identifier_out.begin(),
114 ll_identifier_out.end());
122 const std::vector<uint8_t>& identifier) {
129 uint32_t enterprise_id_current = 0;
130 std::vector<uint8_t> identifier_current;
134 std::vector<uint8_t> duid_vec = duid_->getDuid();
135 if ((duid_->getType() ==
DUID::DUID_EN) && (duid_vec.size() > 6)) {
136 enterprise_id_current =
readUint32(&duid_vec[2], duid_vec.size() - 2);
137 identifier_current.assign(duid_vec.begin() + 6, duid_vec.end());
143 uint32_t enterprise_id_out = enterprise_id;
144 if (enterprise_id_out == 0) {
145 if (enterprise_id_current != 0) {
146 enterprise_id_out = enterprise_id_current;
148 enterprise_id_out = ENTERPRISE_ID_ISC;
153 std::vector<uint8_t> duid_out(DUID_TYPE_LEN + ENTERPRISE_ID_LEN);
155 writeUint32(enterprise_id_out, &duid_out[2], ENTERPRISE_ID_LEN);
159 if (identifier.empty()) {
161 if (identifier_current.empty()) {
164 duid_out.resize(DUID_TYPE_LEN + ENTERPRISE_ID_LEN +
165 DUID_EN_IDENTIFIER_LEN);
168 ::srandom(time(NULL));
169 fillRandom(duid_out.begin() + DUID_TYPE_LEN + ENTERPRISE_ID_LEN,
174 duid_out.insert(duid_out.end(), identifier_current.begin(),
175 identifier_current.end());
180 duid_out.insert(duid_out.end(), identifier.begin(), identifier.end());
189 const std::vector<uint8_t>& ll_identifier) {
196 uint16_t htype_current = 0;
197 std::vector<uint8_t> identifier_current;
201 std::vector<uint8_t> duid_vec = duid_->getDuid();
202 if ((duid_->getType() ==
DUID::DUID_LL) && (duid_vec.size() > 4)) {
203 htype_current =
readUint16(&duid_vec[2], duid_vec.size() - 2);
204 identifier_current.assign(duid_vec.begin() + 4, duid_vec.end());
208 std::vector<uint8_t> ll_identifier_out = ll_identifier;
209 uint16_t htype_out = htype;
214 if (ll_identifier_out.empty()) {
216 if (identifier_current.empty()) {
217 createLinkLayerId(ll_identifier_out, htype_out);
220 ll_identifier_out = identifier_current;
221 htype_out = htype_current;
224 }
else if (htype_out == 0) {
227 htype_out = ((htype_current != 0) ? htype_current :
233 std::vector<uint8_t> duid_out(DUID_TYPE_LEN +
sizeof(htype_out));
236 duid_out.insert(duid_out.end(), ll_identifier_out.begin(),
237 ll_identifier_out.end());
244 DUIDFactory::createLinkLayerId(std::vector<uint8_t>& identifier,
245 uint16_t& htype)
const {
263 if (iface->getMacLen() < MIN_MAC_LEN) {
268 if (iface->flag_loopback_) {
273 if (!iface->flag_up_) {
280 if (
isRangeZero(iface->getMac(), iface->getMac() + iface->getMacLen())) {
285 identifier.assign(iface->getMac(), iface->getMac() + iface->getMacLen());
286 htype = iface->getHWType();
289 if ((htype == static_cast<uint16_t>(
HTYPE_ETHER)) &&
290 (iface->getMacLen() == 6)) {
297 if (identifier.empty()) {
299 " generating a DUID-LLT");
304 DUIDFactory::set(
const std::vector<uint8_t>& duid_vector) {
315 ofs.open(storage_location_.c_str(), std::ofstream::out |
316 std::ofstream::trunc);
319 << storage_location_ <<
" for writing");
323 DUID duid(duid_vector);
329 << storage_location_);
339 duid_.reset(
new DUID(duid_vector));
356 const std::vector<uint8_t> empty_vector;
378 DUIDFactory::readFromFile() {
381 std::ostringstream duid_str;
384 ifs.open(storage_location_.c_str(), std::ifstream::in);
386 std::string read_contents;
387 while (!ifs.eof() && ifs.good()) {
388 ifs >> read_contents;
389 duid_str << read_contents;
396 if (duid_str.tellp() != std::streampos(0)) {
boost::shared_ptr< DUID > DuidPtr
uint8_t * writeUint32(uint32_t value, uint8_t *buffer, size_t length)
Write Unsigned 32-Bit Integer to Buffer.
void createLLT(const uint16_t htype, const uint32_t time_in, const std::vector< uint8_t > &ll_identifier)
Generates DUID-LLT.
link-layer + time, see RFC3315, section 11.2
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
static DUID fromText(const std::string &text)
Create DUID from the textual format.
static const size_t MIN_DUID_LEN
minimum duid size The minimal DUID size specified in RFC 8415 is 1.
DuidPtr get()
Returns current DUID.
Holds DUID (DHCPv6 Unique Identifier)
bool isRangeZero(Iterator begin, Iterator end)
Checks if specified range in a container contains only zeros.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
uint8_t * writeUint16(uint16_t value, void *buffer, size_t length)
Write Unsigned 16-Bit Integer to Buffer.
void createLL(const uint16_t htype, const std::vector< uint8_t > &ll_identifier)
Generates DUID-LL.
A generic exception that is thrown when an unexpected error condition occurs.
bool isStored() const
Checks if generated DUID will be stored in the file.
link-layer, see RFC3315, section 11.4
uint32_t readUint32(const uint8_t *buffer, size_t length)
Read Unsigned 32-Bit Integer from Buffer.
Defines the logger used by the top-level component of kea-lfc.
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
A generic exception that is thrown if a function is called in a prohibited way.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
void createEN(const uint32_t enterprise_id, const std::vector< uint8_t > &identifier)
Generates DUID-EN.
string trim(const string &instring)
Trim Leading and Trailing Spaces.
enterprise-id, see RFC3315, section 11.3
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
void fillRandom(Iterator begin, Iterator end)
Fill in specified range with a random data.