23 bool convenient_notation)
25 convenient_notation_(convenient_notation) {
31 return (cloneInternal<OptionClasslessStaticRoute>());
38 for (
auto const& route : static_routes_) {
40 auto dest = encodeDestinationDescriptor(route);
41 buf.writeData(&dest[0], dest.size());
43 buf.writeUint32(std::get<2>(route).toUint32());
51 if (distance(begin, end) < 5) {
53 <<
type_ <<
" has invalid length=" << distance(begin, end)
54 <<
", must be at least 5.");
57 if (convenient_notation_) {
64 std::string config_txt = std::string(begin, end);
65 parseConfigData(config_txt);
67 parseWireData(begin, end);
75 std::ostringstream stream;
76 std::string in(indent,
' ');
77 stream << in <<
"type=" <<
type_ <<
"(CLASSLESS_STATIC_ROUTE), "
80 for (
auto const& route : static_routes_) {
81 stream <<
", Route " << ++i <<
" (subnet " << std::get<0>(route).toText() <<
"/"
82 <<
static_cast<int>(std::get<1>(route)) <<
", router IP "
83 << std::get<2>(route).toText() <<
")";
86 return (stream.str());
97OptionClasslessStaticRoute::encodeDestinationDescriptor(
const StaticRouteTuple& route) {
99 const std::vector<uint8_t>& subnet = std::get<0>(route).toBytes();
100 const uint8_t& mask_width = std::get<1>(route);
102 std::vector<uint8_t> res;
103 res.push_back(mask_width);
104 if (mask_width == 0) {
109 uint8_t significant_octets = calcSignificantOctets(mask_width);
110 res.insert(res.end(), subnet.begin(), subnet.begin() + significant_octets);
116OptionClasslessStaticRoute::calcSignificantOctets(
const uint8_t& mask_width) {
117 return ((mask_width + 7) / 8);
121OptionClasslessStaticRoute::calcDataLen() {
123 for (
auto const& route : static_routes_) {
125 len += calcSignificantOctets(std::get<1>(route)) + 1;
127 len += V4ADDRESS_LEN;
135 while (begin != end) {
137 if (distance(begin, end) < 5) {
139 <<
type_ <<
" has invalid length=" << distance(begin, end)
140 <<
", must be at least 5.");
144 uint8_t mask_width = *begin;
145 if (mask_width > 32) {
147 <<
type_ <<
" has invalid value, provided width of subnet mask "
148 <<
static_cast<int>(mask_width) <<
" is not valid.");
151 uint8_t significant_octets = calcSignificantOctets(mask_width);
155 if (distance(begin, end) < (significant_octets + V4ADDRESS_LEN)) {
157 "DHCPv4 OptionClasslessStaticRoute " <<
type_ <<
" is truncated.");
161 uint32_t subnet_octets;
164 switch (significant_octets) {
169 subnet_octets = *begin;
170 subnet_nr =
IOAddress(subnet_octets << 24);
173 subnet_octets =
readUint16(&(*begin), distance(begin, end));
174 subnet_nr =
IOAddress(subnet_octets << 16);
180 subnet_octets =
readUint32(&(*begin), distance(begin, end));
181 subnet_nr =
IOAddress(subnet_octets & 0xFFFFFF00);
184 subnet_octets =
readUint32(&(*begin), distance(begin, end));
189 begin += significant_octets;
193 begin += V4ADDRESS_LEN;
195 StaticRouteTuple route = std::make_tuple(subnet_nr, mask_width, router_addr);
196 static_routes_.push_back(route);
201OptionClasslessStaticRoute::parseConfigData(
const std::string& config_txt) {
204 for (
auto const& route_str :
tokens) {
206 if (parts.size() != 2) {
209 <<
" has invalid value, option definition must"
210 " have comma separated routes formatted as in "
211 "example: 10.229.0.128/25 - 10.229.0.1");
214 std::string txt_subnet_prefix =
str::trim(parts[0]);
217 size_t pos = txt_subnet_prefix.find(
'/');
218 if (pos == std::string::npos) {
220 <<
type_ <<
" has invalid value, provided IPv4 prefix "
221 << txt_subnet_prefix <<
" is not valid.");
224 std::string txt_subnet_addr = txt_subnet_prefix.substr(0, pos);
227 subnet_addr =
IOAddress(txt_subnet_addr);
228 if (!subnet_addr.isV4()) {
231 }
catch (
const std::exception& e) {
233 <<
type_ <<
" has invalid value, provided subnet_addr "
234 << txt_subnet_addr <<
" is not a valid IPv4 address. "
235 <<
"Error: " << e.what());
238 std::string txt_prefix_len = txt_subnet_prefix.substr(pos + 1);
239 int16_t prefix_len = 0;
243 prefix_len = boost::lexical_cast<int16_t>(txt_prefix_len);
244 if (prefix_len > 32) {
247 }
catch (
const std::exception& e) {
249 <<
type_ <<
" has invalid value, provided prefix len "
250 << txt_prefix_len <<
" is not valid. "
251 <<
"Error: " << e.what());
255 std::string txt_router =
str::trim(parts[1]);
258 if (!router_addr.isV4()) {
261 }
catch (
const std::exception& e) {
263 <<
type_ <<
" has invalid value, provided router address "
264 << txt_router <<
" is not a valid IPv4 address. "
265 <<
"Error: " << e.what());
268 StaticRouteTuple route = std::make_tuple(subnet_addr, prefix_len, router_addr);
269 static_routes_.push_back(route);
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 parameter given to a method would refer to or modify out-of-r...
The IOAddress class represents an IP addresses (version agnostic)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
std::string toText(int indent=0) const override
Returns string representation of the option.
OptionPtr clone() const override
Copies this option and returns a pointer to the copy.
void pack(util::OutputBuffer &buf, bool check=true) const override
Writes option in wire-format to a buffer.
void unpack(OptionBufferConstIter begin, OptionBufferConstIter end) override
Parses option from the received buffer.
OptionClasslessStaticRoute(OptionBufferConstIter begin, OptionBufferConstIter end, bool convenient_notation=false)
Constructor of the Option from data in the buffer.
uint16_t len() const override
Returns length of the complete option (data length + DHCPv4 option header)
uint16_t type_
option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
virtual uint16_t getHeaderLen() const
Returns length of header (2 for v4, 4 for v6)
void packHeader(isc::util::OutputBuffer &buf, bool check=true) const
Store option's header in a buffer.
void check() const
A protected method used for option correctness.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::tuple< asiolink::IOAddress, uint8_t, asiolink::IOAddress > StaticRouteTuple
Defines a tuple of Subnet number, Subnet mask width and IPv4 router address.
@ DHO_CLASSLESS_STATIC_ROUTE
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
boost::shared_ptr< Option > OptionPtr
vector< string > tokens(const string &text, const string &delim, bool escape)
Split string into tokens.
string trim(const string &input)
Trim leading and trailing spaces.
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
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.