2016-08-28 22:38:24 +02:00
|
|
|
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
2012-09-12 17:09:40 +02:00
|
|
|
//
|
2015-12-15 21:37:34 +01:00
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
2012-09-12 17:09:40 +02:00
|
|
|
|
2016-12-14 16:15:52 +02:00
|
|
|
#include <config.h>
|
|
|
|
|
2012-11-16 14:15:45 +00:00
|
|
|
#include <dhcp/duid.h>
|
2012-09-12 17:09:40 +02:00
|
|
|
#include <exceptions/exceptions.h>
|
2012-09-12 20:39:07 +02:00
|
|
|
#include <util/io_utilities.h>
|
2016-04-06 15:00:12 +02:00
|
|
|
#include <util/strutil.h>
|
2012-10-30 18:22:50 +01:00
|
|
|
#include <iomanip>
|
2014-10-17 15:49:18 +02:00
|
|
|
#include <cctype>
|
2012-11-16 14:15:45 +00:00
|
|
|
#include <sstream>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <stdint.h>
|
2012-09-12 17:09:40 +02:00
|
|
|
|
|
|
|
namespace isc {
|
|
|
|
namespace dhcp {
|
|
|
|
|
|
|
|
DUID::DUID(const std::vector<uint8_t>& duid) {
|
|
|
|
if (duid.size() > MAX_DUID_LEN) {
|
2019-07-03 14:24:04 -04:00
|
|
|
isc_throw(isc::BadValue, "DUID is " << duid.size()
|
|
|
|
<< ", exceeds max of " << MAX_DUID_LEN);
|
2012-09-12 17:09:40 +02:00
|
|
|
}
|
2013-02-27 12:13:04 +01:00
|
|
|
if (duid.empty()) {
|
2014-10-10 20:42:18 +02:00
|
|
|
isc_throw(isc::BadValue, "Empty DUIDs are not allowed");
|
2013-02-27 12:13:04 +01:00
|
|
|
}
|
|
|
|
duid_ = duid;
|
2012-09-12 17:09:40 +02:00
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
DUID::DUID(const uint8_t* data, size_t len) {
|
2012-09-12 17:09:40 +02:00
|
|
|
if (len > MAX_DUID_LEN) {
|
2019-07-03 14:24:04 -04:00
|
|
|
isc_throw(isc::BadValue, "DUID is " << len
|
|
|
|
<< ", exceeds max of " << MAX_DUID_LEN);
|
2012-09-12 17:09:40 +02:00
|
|
|
}
|
2013-02-27 12:13:04 +01:00
|
|
|
if (len == 0) {
|
2014-10-10 20:42:18 +02:00
|
|
|
isc_throw(isc::BadValue, "Empty DUIDs/Client-ids not allowed");
|
2013-02-27 12:13:04 +01:00
|
|
|
}
|
2012-09-12 17:09:40 +02:00
|
|
|
|
|
|
|
duid_ = std::vector<uint8_t>(data, data + len);
|
|
|
|
}
|
|
|
|
|
2014-03-24 14:32:10 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DUID
|
|
|
|
DUID::fromText(const std::string& text) {
|
2016-04-06 15:00:12 +02:00
|
|
|
std::vector<uint8_t> binary;
|
|
|
|
util::str::decodeFormattedHexString(text, binary);
|
|
|
|
return (DUID(binary));
|
2014-03-24 07:44:55 +01:00
|
|
|
}
|
|
|
|
|
2016-11-01 11:00:29 -04:00
|
|
|
const DUID&
|
|
|
|
DUID::EMPTY() {
|
|
|
|
static std::vector<uint8_t> empty_duid(1,0);
|
|
|
|
static DUID empty(empty_duid);
|
|
|
|
return (empty);
|
2015-09-21 14:52:26 +02:00
|
|
|
}
|
|
|
|
|
2012-10-30 18:22:50 +01:00
|
|
|
std::string DUID::toText() const {
|
|
|
|
std::stringstream tmp;
|
2012-11-02 19:55:55 +01:00
|
|
|
tmp << std::hex;
|
2012-10-30 18:22:50 +01:00
|
|
|
bool delim = false;
|
|
|
|
for (std::vector<uint8_t>::const_iterator it = duid_.begin();
|
|
|
|
it != duid_.end(); ++it) {
|
|
|
|
if (delim) {
|
|
|
|
tmp << ":";
|
|
|
|
}
|
2012-11-02 19:55:55 +01:00
|
|
|
tmp << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(*it);
|
2012-10-30 18:22:50 +01:00
|
|
|
delim = true;
|
|
|
|
}
|
|
|
|
return (tmp.str());
|
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
bool DUID::operator==(const DUID& other) const {
|
2012-09-12 17:09:40 +02:00
|
|
|
return (this->duid_ == other.duid_);
|
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
bool DUID::operator!=(const DUID& other) const {
|
2012-09-12 17:09:40 +02:00
|
|
|
return (this->duid_ != other.duid_);
|
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
// Constructor based on vector<uint8_t>
|
2012-09-12 20:39:07 +02:00
|
|
|
ClientId::ClientId(const std::vector<uint8_t>& clientid)
|
2012-11-20 12:45:01 +00:00
|
|
|
: DUID(clientid) {
|
2013-02-27 12:13:04 +01:00
|
|
|
if (clientid.size() < MIN_CLIENT_ID_LEN) {
|
2014-10-10 20:42:18 +02:00
|
|
|
isc_throw(isc::BadValue, "client-id is too short (" << clientid.size()
|
2013-02-27 12:13:04 +01:00
|
|
|
<< "), at least 2 is required");
|
|
|
|
}
|
2012-09-12 20:39:07 +02:00
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
// Constructor based on C-style data
|
2012-09-12 20:39:07 +02:00
|
|
|
ClientId::ClientId(const uint8_t *clientid, size_t len)
|
2012-11-20 12:45:01 +00:00
|
|
|
: DUID(clientid, len) {
|
2013-02-27 12:13:04 +01:00
|
|
|
if (len < MIN_CLIENT_ID_LEN) {
|
2014-10-10 20:42:18 +02:00
|
|
|
isc_throw(isc::BadValue, "client-id is too short (" << len
|
2013-02-27 12:13:04 +01:00
|
|
|
<< "), at least 2 is required");
|
|
|
|
}
|
2012-09-12 20:39:07 +02:00
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
// Returns a copy of client-id data
|
2013-11-15 13:45:56 +01:00
|
|
|
const std::vector<uint8_t>& ClientId::getClientId() const {
|
2012-10-10 19:28:09 +02:00
|
|
|
return (duid_);
|
2012-09-12 20:39:07 +02:00
|
|
|
}
|
|
|
|
|
2012-12-14 22:17:19 +00:00
|
|
|
// Returns the Client ID in text form
|
|
|
|
std::string ClientId::toText() const {
|
|
|
|
|
|
|
|
// As DUID is a private base class of ClientId, we can't access
|
|
|
|
// its public toText() method through inheritance: instead we
|
|
|
|
// need the interface of a ClientId::toText() that calls the
|
|
|
|
// equivalent method in the base class.
|
|
|
|
return (DUID::toText());
|
|
|
|
}
|
|
|
|
|
2014-03-24 14:32:10 +01:00
|
|
|
ClientIdPtr
|
|
|
|
ClientId::fromText(const std::string& text) {
|
2016-04-06 15:00:12 +02:00
|
|
|
std::vector<uint8_t> binary;
|
|
|
|
util::str::decodeFormattedHexString(text, binary);
|
2014-03-24 14:32:10 +01:00
|
|
|
return (ClientIdPtr(new ClientId(binary)));
|
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
// Compares two client-ids
|
|
|
|
bool ClientId::operator==(const ClientId& other) const {
|
2012-09-12 20:39:07 +02:00
|
|
|
return (this->duid_ == other.duid_);
|
|
|
|
}
|
|
|
|
|
2012-11-20 12:45:01 +00:00
|
|
|
// Compares two client-ids
|
|
|
|
bool ClientId::operator!=(const ClientId& other) const {
|
2012-09-12 20:39:07 +02:00
|
|
|
return (this->duid_ != other.duid_);
|
|
|
|
}
|
|
|
|
|
2012-09-12 17:09:40 +02:00
|
|
|
}; // end of isc::dhcp namespace
|
|
|
|
}; // end of isc namespace
|