16#include <boost/algorithm/string/predicate.hpp>
25 if (boost::iequals(fmt_str,
"JSON")) {
37 std::ostringstream stream;
38 stream <<
"UNKNOWN(" << format <<
")";
39 return (stream.str());
43 if (mode_str ==
"check-with-dhcid") {
47 if (mode_str ==
"no-check-with-dhcid") {
51 if (mode_str ==
"check-exists-with-dhcid") {
55 if (mode_str ==
"no-check-without-dhcid") {
66 return (
"check-with-dhcid");
68 return (
"no-check-with-dhcid");
70 return (
"check-exists-with-dhcid");
72 return (
"no-check-without-dhcid");
77 std::ostringstream stream;
78 stream <<
"unknown(" << mode <<
")";
79 return (stream.str());
90const uint8_t DHCID_ID_HWADDR = 0x0;
92const uint8_t DHCID_ID_CLIENTID = 0x1;
94const uint8_t DHCID_ID_DUID = 0x2;
106 const std::vector<uint8_t>& wire_fqdn) {
111 const std::vector<uint8_t>& wire_fqdn) {
116 const std::vector<uint8_t>& wire_fqdn) {
137 const std::vector<uint8_t>& wire_fqdn) {
143 if (!clientid_data.empty() && clientid_data[0] == 255) {
144 if (clientid_data.size() <= 5) {
146 "unable to compute DHCID from client identifier, embedded DUID "
147 "length of: " << clientid_data.size() <<
", is too short");
152 if (clientid_data.size() > 135) {
154 "unable to compute DHCID from client identifier, embedded DUID "
155 "length of: " << clientid_data.size() <<
", is too long");
157 std::vector<uint8_t>::const_iterator start = clientid_data.begin() + 5;
158 std::vector<uint8_t>::const_iterator end = clientid_data.end();
159 std::vector<uint8_t> duid(start, end);
160 createDigest(DHCID_ID_DUID, duid, wire_fqdn);
162 createDigest(DHCID_ID_CLIENTID, clientid_data, wire_fqdn);
168 const std::vector<uint8_t>& wire_fqdn) {
171 "unable to compute DHCID from the HW address, "
172 "NULL pointer has been specified");
173 }
else if (hwaddr->hwaddr_.empty()) {
175 "unable to compute DHCID from the HW address, "
176 "HW address is empty");
178 std::vector<uint8_t> hwaddr_data;
179 hwaddr_data.push_back(hwaddr->htype_);
180 hwaddr_data.insert(hwaddr_data.end(), hwaddr->hwaddr_.begin(),
181 hwaddr->hwaddr_.end());
182 createDigest(DHCID_ID_HWADDR, hwaddr_data, wire_fqdn);
187 const std::vector<uint8_t>& wire_fqdn) {
189 createDigest(DHCID_ID_DUID, duid.
getDuid(), wire_fqdn);
193D2Dhcid::createDigest(
const uint8_t identifier_type,
194 const std::vector<uint8_t>& identifier_data,
195 const std::vector<uint8_t>& wire_fqdn) {
199 if (wire_fqdn.empty()) {
201 "empty FQDN used to create DHCID");
208 if (identifier_data.empty()) {
210 "empty DUID used to create DHCID");
214 std::vector<uint8_t> data = identifier_data;
217 data.insert(data.end(), wire_fqdn.begin(), wire_fqdn.end());
226 }
catch (
const std::exception& ex) {
227 isc_throw(isc::dhcp_ddns::DhcidRdataComputeError,
228 "error while generating DHCID from DUID: "
240 bytes_.resize(3 + hash.getLength());
243 bytes_[1] = identifier_type;
247 std::memcpy(&bytes_[3], hash.getData(), hash.getLength());
258 : change_type_(
CHG_ADD), forward_change_(false), reverse_change_(false),
259 fqdn_(
""), ip_io_address_(
"0.0.0.0"), dhcid_(), lease_length_(0),
265 const bool forward_change,
const bool reverse_change,
266 const std::string& fqdn,
const std::string& ip_address,
267 const D2Dhcid& dhcid,
const uint32_t lease_length,
269 : change_type_(change_type), forward_change_(forward_change),
270 reverse_change_(reverse_change), fqdn_(fqdn), ip_io_address_(
"0.0.0.0"),
271 dhcid_(dhcid), lease_length_(lease_length),
272 conflict_resolution_mode_(conflict_resolution_mode),
299 std::vector<uint8_t> vec;
303 std::string string_data(vec.begin(), vec.end());
313 }
catch (
const std::exception& ex) {
341 std::string json =
toJSON();
342 uint16_t length = json.size();
369 "Malformed NameChangeRequest JSON: " << ex.
what());
379 ElementMap element_map = elements->mapValue();
391 element = ncr->getElement(
"change-type", element_map);
392 ncr->setChangeType(element);
394 element = ncr->getElement(
"forward-change", element_map);
395 ncr->setForwardChange(element);
397 element = ncr->getElement(
"reverse-change", element_map);
398 ncr->setReverseChange(element);
400 element = ncr->getElement(
"fqdn", element_map);
401 ncr->setFqdn(element);
403 element = ncr->getElement(
"ip-address", element_map);
404 ncr->setIpAddress(element);
406 element = ncr->getElement(
"dhcid", element_map);
407 ncr->setDhcid(element);
409 element = ncr->getElement(
"lease-length", element_map);
410 ncr->setLeaseLength(element);
415 auto found = element_map.find(
"conflict-resolution-mode");
416 if (found != element_map.end()) {
417 ncr->setConflictResolutionMode(found->second);
419 found = element_map.find(
"use-conflict-resolution");
420 if (found != element_map.end()) {
421 ncr->translateUseConflictResolution(found->second);
427 found = element_map.find(
"next-ncr");
428 if (found != element_map.end()) {
429 auto next_ncr =
fromJSON(found->second);
430 ncr->setNextNcr(next_ncr);
436 ncr->validateContent();
448 std::ostringstream stream;
451 <<
"\"forward-change\":"
453 <<
"\"reverse-change\":"
455 <<
"\"fqdn\":\"" <<
getFqdn() <<
"\","
459 <<
"\"conflict-resolution-mode\":"
463 stream <<
",\"next-ncr\":" << next_ncr_->toJSON();
468 return (stream.str());
481 if (dhcid_.getBytes().size() == 0) {
486 if (!forward_change_ && !reverse_change_) {
488 "Invalid Request, forward and reverse flags are both false");
496 ElementMap::const_iterator it = element_map.find(name);
497 if (it == element_map.end()) {
500 "NameChangeRequest value missing for: " << name );
509 change_type_ = value;
517 raw_value = element->intValue();
521 "Wrong data type for change_type: " << ex.
what());
527 "Invalid data value for change_type: " << raw_value);
536 forward_change_ = value;
544 value = element->boolValue();
548 "Wrong data type for forward-change: " << ex.
what());
557 reverse_change_ = value;
565 value = element->boolValue();
569 "Wrong data type for reverse_change: " << ex.
what());
578 setFqdn(element->stringValue());
586 }
catch (
const std::exception& ex) {
588 "Invalid FQDN value: " << value <<
", reason: "
600 "Invalid ip address string for ip_address: " << value);
606 ip_io_address_ = value;
616 dhcid_.fromStr(value);
626 lease_length_ = value;
634 value = element->intValue();
638 "Wrong data type for lease_length: " << ex.
what());
642 if (value > std::numeric_limits<uint32_t>::max()) {
644 "is too large for unsigned 32-bit integer.");
648 "is negative. It must greater than or equal to zero ");
658 bool value = element->boolValue();
669 conflict_resolution_mode_ = value;
692 std::ostringstream stream;
694 stream <<
"Type: " <<
static_cast<int>(change_type_) <<
" (";
695 switch (change_type_) {
697 stream <<
"CHG_ADD)\n";
700 stream <<
"CHG_REMOVE)\n";
704 stream <<
"Invalid Value\n";
707 stream <<
"Forward Change: " << (forward_change_ ?
"yes" :
"no")
709 <<
"Reverse Change: " << (reverse_change_ ?
"yes" :
"no")
711 <<
"FQDN: [" << fqdn_ <<
"]" << std::endl
712 <<
"IP Address: [" << ip_io_address_ <<
"]" << std::endl
713 <<
"DHCID: [" << dhcid_.toStr() <<
"]" << std::endl
714 <<
"TTL: " << lease_length_ << std::endl
715 <<
"Conflict Resolution Mode: "
720 stream <<
"Next NCR:" << std::endl << next_ncr_->toText();
723 return (stream.str());
728 return ((change_type_ == other.change_type_) &&
729 (forward_change_ == other.forward_change_) &&
730 (reverse_change_ == other.reverse_change_) &&
731 (fqdn_ == other.fqdn_) &&
732 (ip_io_address_ == other.ip_io_address_) &&
733 (dhcid_ == other.dhcid_) &&
734 (lease_length_ == other.lease_length_) &&
735 (conflict_resolution_mode_ == other.conflict_resolution_mode_));
740 return (!(*
this == other));
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
The IOAddress class represents an IP addresses (version agnostic).
An exception that is thrown if an error occurs within the IO module.
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
A standard Data module exception that is thrown if a function is called for an Element that has a wro...
Holds DUID (DHCPv6 Unique Identifier).
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
Container class for handling the DHCID value within a NameChangeRequest.
void fromHWAddr(const isc::dhcp::HWAddrPtr &hwaddr, const std::vector< uint8_t > &wire_fqdn)
Sets the DHCID value based on the HW address and FQDN.
void fromDUID(const isc::dhcp::DUID &duid, const std::vector< uint8_t > &wire_fqdn)
Sets the DHCID value based on the DUID and FQDN.
D2Dhcid()
Default constructor.
void fromClientId(const std::vector< uint8_t > &clientid_data, const std::vector< uint8_t > &wire_fqdn)
Sets the DHCID value based on the Client Identifier.
void fromStr(const std::string &data)
Sets the DHCID value based on the given string.
std::string toStr() const
Returns the DHCID value as a string of hexadecimal digits.
Exception thrown when there is an error occurred during computation of the DHCID.
bool operator==(const NameChangeRequest &b) const
bool operator!=(const NameChangeRequest &b) const
void setStatus(const NameChangeStatus value)
Sets the request status to the given value.
const std::string & getFqdn() const
Fetches the request FQDN.
void setChangeType(const NameChangeType value)
Sets the change type to the given value.
std::string toText() const
Returns a text rendition of the contents of the request.
uint32_t getLeaseLength() const
Fetches the request lease length.
void setIpAddress(const std::string &value)
Sets the IP address to the given value.
void translateUseConflictResolution(isc::data::ConstElementPtr element)
Sets the conflict resolution mode based on the value of the given boolean Element.
const D2Dhcid & getDhcid() const
Fetches the request DHCID.
void setDhcid(const std::string &value)
Sets the DHCID based on the given string value.
std::string toJSON() const
Instance method for marshalling the contents of the request into a string of JSON text.
ConflictResolutionMode getConflictResolutionMode() const
Fetches the conflict resolution mode.
std::string getIpAddress() const
Fetches the request IP address string.
void setFqdn(const std::string &value)
Sets the FQDN to the given value.
void setReverseChange(const bool value)
Sets the reverse change flag to the given value.
void setLeaseLength(const uint32_t value)
Sets the lease length to the given value.
void toFormat(const NameChangeFormat format, isc::util::OutputBuffer &buffer) const
Instance method for marshalling the contents of the request into the given buffer in the given format...
NameChangeRequest()
Default Constructor.
NameChangeType getChangeType() const
Fetches the request change type.
static NameChangeRequestPtr fromJSON(const std::string &json)
Static method for creating a NameChangeRequest from a string containing a JSON rendition of a request...
void setForwardChange(const bool value)
Sets the forward change flag to the given value.
isc::data::ConstElementPtr getElement(const std::string &name, const ElementMap &element_map) const
Given a name, finds and returns an element from a map of elements.
void setConflictResolutionMode(const ConflictResolutionMode value)
Sets the conflict resolution mode to the given value.
bool isForwardChange() const
Checks forward change flag.
static NameChangeRequestPtr fromFormat(const NameChangeFormat format, isc::util::InputBuffer &buffer)
Static method for creating a NameChangeRequest from a buffer containing a marshalled request in a giv...
void validateContent()
Validates the content of a populated request.
bool isReverseChange() const
Checks reverse change flag.
Exception thrown when NameChangeRequest marshalling error occurs.
The Name class encapsulates DNS names.
std::string toText(bool omit_final_dot=false) const
Convert the Name to a string.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
void digest(const void *data, const size_t data_len, const HashAlgorithm hash_algorithm, isc::util::OutputBuffer &result, size_t len)
Create an Hash digest for the given data.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
NameChangeFormat
Defines the list of data wire formats supported.
NameChangeStatus
Defines the runtime processing status values for requests.
NameChangeType
Defines the types of DNS updates that can be requested.
@ CHECK_EXISTS_WITH_DHCID
std::map< std::string, isc::data::ConstElementPtr > ElementMap
Defines a map of Elements, keyed by their string name.
std::ostream & operator<<(std::ostream &os, const D2Dhcid &dhcid)
NameChangeFormat stringToNcrFormat(const std::string &fmt_str)
Function which converts labels to NameChangeFormat enum values.
ConflictResolutionMode StringToConflictResolutionMode(const std::string &mode_str)
Function which converts string to ConflictResolutionMode enum values.
std::string ConflictResolutionModeToString(const ConflictResolutionMode &mode)
Function which converts ConflictResolutionMode enums to text labels.
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
std::string ncrFormatToString(NameChangeFormat format)
Function which converts NameChangeFormat enums to text labels.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
void decodeHex(const string &encoded_str, vector< uint8_t > &output)
Decode a base16 encoded string into binary data.
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
Defines the logger used by the top-level component of kea-lfc.
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...