| Kea 3.0.2-git

option6_dnr.cc
Go to the documentation of this file.
1// Copyright (C) 2023-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <dhcp/option6_dnr.h>
10#include <util/io.h>
11
12 using namespace isc::asiolink;
13 using namespace isc::util;
14
15 namespace isc {
16 namespace dhcp {
17
18 Option6Dnr::Option6Dnr(OptionBufferConstIter begin,
19 OptionBufferConstIter end,
20 bool convenient_notation)
21 : Option(V6, D6O_V6_DNR), DnrInstance(V6), convenient_notation_(convenient_notation) {
22 unpack(begin, end);
23}
24
25 OptionPtr
26 Option6Dnr::clone() const {
27 return (cloneInternal<Option6Dnr>());
28}
29
30 void
31 Option6Dnr::pack(util::OutputBuffer& buf, bool check) const {
32 packHeader(buf, check);
33
34 buf.writeUint16(service_priority_);
35 buf.writeUint16(adn_length_);
36 packAdn(buf);
37 if (adn_only_mode_) {
38 return;
39 }
40
41 buf.writeUint16(addr_length_);
42 packAddresses(buf);
43 packSvcParams(buf);
44}
45
46 void
47 Option6Dnr::packAddresses(util::OutputBuffer& buf) const {
48 for (auto const& address : ip_addresses_) {
49 if (!address.isV6()) {
50 isc_throw(isc::BadValue, getLogPrefix()
51 << address.toText() << " is not an IPv6 address");
52 }
53
54 buf.writeData(&address.toBytes()[0], V6ADDRESS_LEN);
55 }
56}
57
58 void
59 Option6Dnr::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) {
60 if (convenient_notation_) {
61 // parse convenient notation
62 std::string config_txt = std::string(begin, end);
63 parseDnrInstanceConfigData(config_txt);
64 } else {
65 if (std::distance(begin, end) < getMinimalLength()) {
66 isc_throw(OutOfRange, getLogPrefix()
67 << "data truncated to size " << std::distance(begin, end));
68 }
69
70 setData(begin, end);
71
72 // First two octets of Option data is Service Priority - this is mandatory field.
73 unpackServicePriority(begin);
74
75 // Next come two octets of ADN Length plus the ADN data itself (variable length).
76 // This is Opaque Data Tuple so let's use this class to retrieve the ADN data.
77 unpackAdn(begin, end);
78
79 if (begin == end) {
80 // ADN only mode, other fields are not included.
81 return;
82 }
83
84 adn_only_mode_ = false;
85
86 unpackAddresses(begin, end);
87
88 // SvcParams (variable length) field is last.
89 unpackSvcParams(begin, end);
90 }
91}
92
93std::string
94 Option6Dnr::toText(int indent) const {
95 std::ostringstream stream;
96 std::string in(indent, ' '); // base indentation
97 stream << in << "type=" << type_ << "(V6_DNR), "
98 << "len=" << (len() - getHeaderLen()) << ", " << getDnrInstanceAsText();
99 return (stream.str());
100}
101
102uint16_t
103 Option6Dnr::len() const {
104 return (OPTION6_HDR_LEN + dnrInstanceLen());
105}
106
107 void
108 Option6Dnr::unpackAddresses(OptionBufferConstIter& begin, OptionBufferConstIter end) {
109 if (std::distance(begin, end) < getAddrLengthSize()) {
110 isc_throw(OutOfRange, getLogPrefix() << "after"
111 " ADN field, there should be at least "
112 "2 bytes long Addr Length field");
113 }
114
115 // Next come two octets of Addr Length.
116 addr_length_ = isc::util::readUint16(&(*begin), getAddrLengthSize());
117 begin += getAddrLengthSize();
118 // It MUST be a multiple of 16.
119 if ((addr_length_ % V6ADDRESS_LEN) != 0) {
120 isc_throw(OutOfRange, getLogPrefix()
121 << "Addr Len=" << addr_length_ << " is not divisible by 16");
122 }
123
124 // As per RFC9463 3.1.8:
125 // If additional data is supplied (i.e. not ADN only mode),
126 // the option includes at least one valid IP address.
127 if (addr_length_ == 0) {
128 isc_throw(OutOfRange, getLogPrefix()
129 << "Addr Len=" << addr_length_
130 << " but it must contain at least one valid IP address");
131 }
132
133 // Check if IPv6 Address(es) field is not truncated.
134 if (std::distance(begin, end) < addr_length_) {
135 isc_throw(OutOfRange, getLogPrefix() << "Addr Len=" << addr_length_
136 << " but IPv6 address(es) are truncated to len="
137 << std::distance(begin, end));
138 }
139
140 // Let's unpack the ipv6-address(es).
141 auto addr_end = begin + addr_length_;
142 while (begin != addr_end) {
143 try {
144 addIpAddress(IOAddress::fromBytes(AF_INET6, &(*begin)));
145 } catch (const Exception& ex) {
146 isc_throw(BadValue, getLogPrefix() << "failed to parse IPv6 address"
147 << " - " << ex.what());
148 }
149
150 begin += V6ADDRESS_LEN;
151 }
152}
153
154} // namespace dhcp
155} // namespace isc
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition exceptions/exceptions.h:132
isc::Exception
This is a base class for exceptions thrown from the DNS library module.
Definition exceptions/exceptions.h:23
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition exceptions/exceptions.cc:32
isc::OutOfRange
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Definition exceptions/exceptions.h:115
isc::asiolink::IOAddress::fromBytes
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
Definition io_address.cc:66
isc::dhcp::DnrInstance::getDnrInstanceAsText
std::string getDnrInstanceAsText() const
Returns string representation of the DNR instance.
Definition option4_dnr.cc:345
isc::dhcp::DnrInstance::unpackSvcParams
void unpackSvcParams(OptionBufferConstIter &begin, OptionBufferConstIter end)
Unpacks Service Parameters from wire data buffer and stores it in svc_params_buf_.
Definition option4_dnr.cc:448
isc::dhcp::DnrInstance::getMinimalLength
uint8_t getMinimalLength() const
Returns minimal length of the DNR instance data (without headers) in octets.
Definition option4_dnr.h:176
isc::dhcp::DnrInstance::ip_addresses_
AddressContainer ip_addresses_
Vector container holding one or more IP addresses.
Definition option4_dnr.h:360
isc::dhcp::DnrInstance::packAdn
void packAdn(isc::util::OutputBuffer &buf) const
Writes the ADN FQDN in the wire format into a buffer.
Definition option4_dnr.cc:221
isc::dhcp::DnrInstance::addr_length_
uint16_t addr_length_
Length of included IP addresses in octets.
Definition option4_dnr.h:352
isc::dhcp::DnrInstance::getAddrLengthSize
uint8_t getAddrLengthSize() const
Returns size in octets of Addr Length field.
Definition option4_dnr.h:181
isc::dhcp::DnrInstance::parseDnrInstanceConfigData
void parseDnrInstanceConfigData(const std::string &config_txt)
Parses a convenient notation of the option data, which may be used in config.
Definition option4_dnr.cc:551
isc::dhcp::DnrInstance::unpackServicePriority
void unpackServicePriority(OptionBufferConstIter &begin)
Unpacks Service Priority from wire data buffer and stores it in service_priority_.
Definition option4_dnr.cc:404
isc::dhcp::DnrInstance::service_priority_
uint16_t service_priority_
The priority of this instance compared to other DNR instances.
Definition option4_dnr.h:346
isc::dhcp::DnrInstance::packSvcParams
void packSvcParams(isc::util::OutputBuffer &buf) const
Writes the Service Parameters in the wire format into a buffer.
Definition option4_dnr.cc:248
isc::dhcp::DnrInstance::getLogPrefix
std::string getLogPrefix() const
Returns Log prefix depending on V4/V6 Option universe.
Definition option4_dnr.h:198
isc::dhcp::DnrInstance::adn_only_mode_
bool adn_only_mode_
Flag stating whether ADN only mode is used or not.
Definition option4_dnr.h:369
isc::dhcp::DnrInstance::adn_length_
uint16_t adn_length_
Length of the authentication-domain-name data in octets.
Definition option4_dnr.h:349
isc::dhcp::DnrInstance::dnrInstanceLen
uint16_t dnrInstanceLen() const
Calculates and returns length of DNR Instance data in octets.
Definition option4_dnr.cc:377
isc::dhcp::DnrInstance::addIpAddress
void addIpAddress(const asiolink::IOAddress &ip_address)
Adds IP address to ip_addresses_ container.
Definition option4_dnr.cc:387
isc::dhcp::DnrInstance::unpackAdn
void unpackAdn(OptionBufferConstIter &begin, OptionBufferConstIter end)
Unpacks the ADN from given wire data buffer and stores it in adn_ field.
Definition option4_dnr.cc:260
isc::dhcp::DnrInstance::DnrInstance
DnrInstance(Option::Universe universe)
Constructor of the empty DNR Instance.
Definition option4_dnr.cc:212
isc::dhcp::Option6Dnr::len
uint16_t len() const override
Returns length of the complete option (data length + DHCPv4/DHCPv6 option header).
Definition option6_dnr.cc:103
isc::dhcp::Option6Dnr::Option6Dnr
Option6Dnr(OptionBufferConstIter begin, OptionBufferConstIter end, bool convenient_notation=false)
Constructor of the Option from on-wire data.
Definition option6_dnr.cc:18
isc::dhcp::Option6Dnr::packAddresses
void packAddresses(isc::util::OutputBuffer &buf) const override
Writes the IP address(es) in the wire format into a buffer.
Definition option6_dnr.cc:47
isc::dhcp::Option6Dnr::unpackAddresses
void unpackAddresses(OptionBufferConstIter &begin, OptionBufferConstIter end) override
Unpacks IP address(es) from wire data and stores it/them in ip_addresses_.
Definition option6_dnr.cc:108
isc::dhcp::Option6Dnr::toText
std::string toText(int indent=0) const override
Returns string representation of the option.
Definition option6_dnr.cc:94
isc::dhcp::Option6Dnr::unpack
void unpack(OptionBufferConstIter begin, OptionBufferConstIter end) override
Parses received wire data buffer.
Definition option6_dnr.cc:59
isc::dhcp::Option6Dnr::pack
void pack(util::OutputBuffer &buf, bool check=false) const override
Writes option in wire-format to a buffer.
Definition option6_dnr.cc:31
isc::dhcp::Option6Dnr::clone
OptionPtr clone() const override
Copies this option and returns a pointer to the copy.
Definition option6_dnr.cc:26
isc::dhcp::Option::type_
uint16_t type_
option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
Definition option.h:597
isc::dhcp::Option::getHeaderLen
virtual uint16_t getHeaderLen() const
Returns length of header (2 for v4, 4 for v6).
Definition option.cc:327
isc::dhcp::Option::V6
@ V6
Definition option.h:90
isc::dhcp::Option::OPTION6_HDR_LEN
static const size_t OPTION6_HDR_LEN
length of any DHCPv6 option header
Definition option.h:87
isc::dhcp::Option::setData
void setData(InputIterator first, InputIterator last)
Sets content of this option from buffer.
Definition option.h:434
isc::dhcp::Option::cloneInternal
OptionPtr cloneInternal() const
Copies this option and returns a pointer to the copy.
Definition option.h:504
isc::dhcp::Option::packHeader
void packHeader(isc::util::OutputBuffer &buf, bool check=true) const
Store option's header in a buffer.
Definition option.cc:119
isc::dhcp::Option::Option
Option(Universe u, uint16_t type)
ctor, used for options constructed, usually during transmission
Definition option.cc:39
isc::dhcp::Option::check
void check() const
A protected method used for option correctness.
Definition option.cc:90
isc::util::OutputBuffer
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition buffer.h:346
isc::util::OutputBuffer::writeUint16
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
Definition buffer.h:501
isc::util::OutputBuffer::writeData
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition buffer.h:559
D6O_V6_DNR
@ D6O_V6_DNR
Definition dhcp6.h:164
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
io.h
isc::asiolink
Definition addr_utilities.cc:170
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::OptionBufferConstIter
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition option.h:30
isc::dhcp::OptionPtr
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
isc::util
Definition time_utils.cc:43
isc::util::readUint16
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
Definition io.h:76
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
option6_dnr.h