27const size_t DUID_TYPE_LEN = 2;
30const size_t MIN_MAC_LEN = 6;
33const size_t ENTERPRISE_ID_LEN = 4;
36const size_t DUID_EN_IDENTIFIER_LEN = 6;
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());
244DUIDFactory::createLinkLayerId(std::vector<uint8_t>& identifier,
245 uint16_t& htype)
const {
247 for (
auto const& iface :
IfaceMgr::instance().getIfaces()) {
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");
304DUIDFactory::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);
326 ofs << duid.toText();
329 << storage_location_);
339 duid_.reset(
new DUID(duid_vector));
356 const std::vector<uint8_t> empty_vector;
378DUIDFactory::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)) {
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
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.
DUIDFactory(const std::string &storage_location="")
Constructor.
void createLLT(const uint16_t htype, const uint32_t time_in, const std::vector< uint8_t > &ll_identifier)
Generates DUID-LLT.
void createEN(const uint32_t enterprise_id, const std::vector< uint8_t > &identifier)
Generates DUID-EN.
DuidPtr get()
Returns current DUID.
void createLL(const uint16_t htype, const std::vector< uint8_t > &ll_identifier)
Generates DUID-LL.
static constexpr size_t MIN_DUID_LEN
minimum duid size
static DUID fromText(const std::string &text)
Create DUID from the textual format.
@ DUID_LL
link-layer, see RFC3315, section 11.4
@ DUID_LLT
link-layer + time, see RFC3315, section 11.2
@ DUID_EN
enterprise-id, see RFC3315, section 11.3
Handles network interfaces, transmission and reception.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< DUID > DuidPtr
@ HTYPE_ETHER
Ethernet 10Mbps.
string trim(const string &input)
Trim leading and trailing spaces.
void fillRandom(Iterator begin, Iterator end)
Fill in specified range with a random data.
uint8_t * writeUint32(uint32_t const value, void *const buffer, size_t const length)
uint32_t wrapper over writeUint.
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
bool isRangeZero(Iterator begin, Iterator end)
Checks if specified range in a container contains only zeros.
uint8_t * writeUint16(uint16_t const value, void *const buffer, size_t const length)
uint16_t wrapper over writeUint.
uint32_t readUint32(void const *const buffer, size_t const length)
uint32_t wrapper over readUint.
Defines the logger used by the top-level component of kea-lfc.