mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[#3074] change option type to binary
This commit is contained in:
@@ -2022,7 +2022,7 @@ types are given in :ref:`dhcp-types`.
|
||||
+----------------------------------------+------+---------------------------+-------------+-------------+
|
||||
| domain-search | 119 | fqdn | true | false |
|
||||
+----------------------------------------+------+---------------------------+-------------+-------------+
|
||||
| classless-static-route | 121 | ipv4-address | true | false |
|
||||
| classless-static-route | 121 | binary | true | false |
|
||||
+----------------------------------------+------+---------------------------+-------------+-------------+
|
||||
| vivco-suboptions | 124 | record (uint32, binary) | false | false |
|
||||
+----------------------------------------+------+---------------------------+-------------+-------------+
|
||||
|
@@ -6,6 +6,10 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <util/strutil.h>
|
||||
|
||||
#include <boost/algorithm/string/erase.hpp>
|
||||
|
||||
#include <option_classless_static_route.h>
|
||||
|
||||
using namespace isc::asiolink;
|
||||
@@ -40,14 +44,91 @@ OptionClasslessStaticRoute::pack(isc::util::OutputBuffer& buf, bool check) const
|
||||
|
||||
void
|
||||
OptionClasslessStaticRoute::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) {
|
||||
// Static route definition requires n * 3 IPv4 addresses (n>0):
|
||||
// Subnet number, subnet mask, router IP
|
||||
if (!distance(begin, end) || distance(begin, end) % (V4ADDRESS_LEN * 3)) {
|
||||
// Classless Static route option data must contain at least 5 octets.
|
||||
// 1 octet - shortest possible destination descriptor (0x00) + 4 octets router IPv4 addr.
|
||||
if (distance(begin, end) < 5) {
|
||||
isc_throw(OutOfRange, "DHCPv4 OptionClasslessStaticRoute "
|
||||
<< type_ << " has invalid length=" << distance(begin, end)
|
||||
<< ", must be divisible by 12 and must not be 0.");
|
||||
<< ", must be at least 5.");
|
||||
}
|
||||
|
||||
// As an alternative to binary format,
|
||||
// we provide convenience option definition as a string in format:
|
||||
// subnet1 - router1 IP addr, subnet2 - router2 IP addr, ...
|
||||
// e.g.:
|
||||
// 10.0.0.0/8 - 10.2.3.1, 10.229.0.128/25 - 10.1.0.3, ...
|
||||
// where destination descriptors will be encoded as per RFC3442.
|
||||
// We need to determine if OptionBuffer contains dash `-` separator (0x2d).
|
||||
// If not, we assume this is binary format and no encoding needs to be done.
|
||||
auto begin_copy = begin;
|
||||
while (begin_copy != end) {
|
||||
if (*begin_copy == '-') {
|
||||
break;
|
||||
}
|
||||
++begin_copy;
|
||||
}
|
||||
if (begin_copy == end) {
|
||||
// no separator found, assuming this is a hex on-wire data
|
||||
setData(begin, end); // TODO: do this or parse hex and feed static_routes_
|
||||
// TODO: pack(), toText(), len() etc. basing on _data
|
||||
} else {
|
||||
// separator was found, assuming this is option data string from config
|
||||
std::string buffer_to_str = std::string(begin, end);
|
||||
// this option allows more than one static route, so let's separate them using comma
|
||||
std::vector<std::string> tokens = util::str::tokens(buffer_to_str, std::string(","));
|
||||
std::ostringstream stream;
|
||||
for (const auto& route_str : tokens) {
|
||||
std::vector<std::string> parts = util::str::tokens(util::str::trim(route_str), std::string("-"));
|
||||
if (parts.size() != 2) {
|
||||
isc_throw(BadValue, "DHCPv4 OptionClasslessStaticRoute "
|
||||
<< type_ << " has invalid value, route definition must"
|
||||
" have format as in example: 10.229.0.128/25 - 10.229.0.1, "
|
||||
"0.0.0.0/0 - 10.129.0.2");
|
||||
}
|
||||
std::string txt = parts[0];
|
||||
|
||||
// first let's remove any whitespaces
|
||||
boost::erase_all(txt, " "); // space
|
||||
boost::erase_all(txt, "\t"); // tabulation
|
||||
|
||||
// Is this prefix/len notation?
|
||||
size_t pos = txt.find("/");
|
||||
|
||||
if (pos == std::string::npos) {
|
||||
isc_throw(BadValue, "DHCPv4 OptionClasslessStaticRoute "
|
||||
<< type_ << " has invalid value, provided IPv4 prefix "
|
||||
<< parts[0] << " is not valid.");
|
||||
}
|
||||
|
||||
std::string txt_address = txt.substr(0, pos);
|
||||
isc::asiolink::IOAddress address = isc::asiolink::IOAddress(txt_address);
|
||||
if (!address.isV4()) {
|
||||
isc_throw(BadValue, "DHCPv4 OptionClasslessStaticRoute "
|
||||
<< type_ << " has invalid value, provided address "
|
||||
<< txt_address
|
||||
<< " is not a valid IPv4 address.");
|
||||
}
|
||||
|
||||
std::string txt_prefix = txt.substr(pos + 1);
|
||||
uint8_t len = 0;
|
||||
try {
|
||||
// start with the first character after /
|
||||
len = static_cast<uint8_t>(boost::lexical_cast<int64_t>(txt_prefix));
|
||||
} catch (...) {
|
||||
isc_throw(BadValue, "DHCPv4 OptionClasslessStaticRoute "
|
||||
<< type_ << " has invalid value, provided prefix len "
|
||||
<< txt_prefix
|
||||
<< " is not valid.");
|
||||
}
|
||||
|
||||
stream << route_str << ", ";
|
||||
}
|
||||
|
||||
|
||||
isc_throw(OutOfRange, "DHCPv4 OptionClasslessStaticRoute unpack from string '" + (buffer_to_str) + "' tokens: " + stream.str());
|
||||
}
|
||||
|
||||
|
||||
while (begin != end) {
|
||||
// Subnet number IP address e.g. 10.229.0.128
|
||||
const uint8_t* ptr = &(*begin);
|
||||
|
@@ -332,8 +332,8 @@ const OptionDefParams STANDARD_V4_OPTION_DEFINITIONS[] = {
|
||||
OPT_IPV4_ADDRESS_TYPE, false, NO_RECORD_DEF, "" },
|
||||
{ "domain-search", DHO_DOMAIN_SEARCH, DHCP4_OPTION_SPACE, OPT_FQDN_TYPE,
|
||||
true, NO_RECORD_DEF, "" },
|
||||
{ "classless-static-route", DHO_CLASSLESS_STATIC_ROUTE, DHCP4_OPTION_SPACE, OPT_IPV4_ADDRESS_TYPE,
|
||||
true, NO_RECORD_DEF, "" },
|
||||
{ "classless-static-route", DHO_CLASSLESS_STATIC_ROUTE, DHCP4_OPTION_SPACE, OPT_BINARY_TYPE,
|
||||
false, NO_RECORD_DEF, "" },
|
||||
{ "vivco-suboptions", DHO_VIVCO_SUBOPTIONS, DHCP4_OPTION_SPACE,
|
||||
OPT_RECORD_TYPE, false, RECORD_DEF(VIVCO_RECORDS), "" },
|
||||
// Vendor-Identifying Vendor Specific Information option payload begins with a
|
||||
|
Reference in New Issue
Block a user