23                                                       bool convenient_notation)
 
   25      convenient_notation_(convenient_notation) {
 
 
   38    for (
auto const& route : static_routes_) {
 
   40        auto dest = encodeDestinationDescriptor(route);
 
 
   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) {
 
  138            isc_throw(OutOfRange, 
"DHCPv4 OptionClasslessStaticRoute " 
  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) {
 
  146            isc_throw(BadValue, 
"DHCPv4 OptionClasslessStaticRoute " 
  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 (
static_cast<size_t>(distance(begin, end)) <
 
  156            (significant_octets + V4ADDRESS_LEN)) {
 
  158                      "DHCPv4 OptionClasslessStaticRoute " << 
type_ << 
" is truncated.");
 
  162        uint32_t subnet_octets;
 
  165        switch (significant_octets) {
 
  170            subnet_octets = *begin;
 
  171            subnet_nr = IOAddress(subnet_octets << 24);
 
  174            subnet_octets = 
readUint16(&(*begin), distance(begin, end));
 
  175            subnet_nr = IOAddress(subnet_octets << 16);
 
  181            subnet_octets = 
readUint32(&(*begin), distance(begin, end));
 
  182            subnet_nr = IOAddress(subnet_octets & 0xFFFFFF00);
 
  185            subnet_octets = 
readUint32(&(*begin), distance(begin, end));
 
  186            subnet_nr = IOAddress(subnet_octets);
 
  190        begin += significant_octets;
 
  193        IOAddress router_addr = IOAddress(
readUint32(&(*begin), distance(begin, end)));
 
  194        begin += V4ADDRESS_LEN;
 
  196        StaticRouteTuple route = std::make_tuple(subnet_nr, mask_width, router_addr);
 
  197        static_routes_.push_back(route);
 
  202OptionClasslessStaticRoute::parseConfigData(
const std::string& config_txt) {
 
  205    for (
auto const& route_str : tokens) {
 
  207        if (parts.size() != 2) {
 
  208            isc_throw(BadValue, 
"DHCPv4 OptionClasslessStaticRoute " 
  210                                    << 
" has invalid value, option definition must" 
  211                                       " have comma separated routes formatted as in " 
  212                                       "example: 10.229.0.128/25 - 10.229.0.1");
 
  215        std::string txt_subnet_prefix = 
str::trim(parts[0]);
 
  218        size_t pos = txt_subnet_prefix.find(
'/');
 
  219        if (pos == std::string::npos) {
 
  220            isc_throw(BadValue, 
"DHCPv4 OptionClasslessStaticRoute " 
  221                                    << 
type_ << 
" has invalid value, provided IPv4 prefix " 
  222                                    << txt_subnet_prefix << 
" is not valid.");
 
  225        std::string txt_subnet_addr = txt_subnet_prefix.substr(0, pos);
 
  226        IOAddress subnet_addr = IOAddress(
"::");
 
  228            subnet_addr = IOAddress(txt_subnet_addr);
 
  229            if (!subnet_addr.
isV4()) {
 
  230                isc_throw(BadValue, 
"This is not IPv4 address.");
 
  232        } 
catch (
const std::exception& e) {
 
  233            isc_throw(BadValue, 
"DHCPv4 OptionClasslessStaticRoute " 
  234                                    << 
type_ << 
" has invalid value, provided subnet_addr " 
  235                                    << txt_subnet_addr << 
" is not a valid IPv4 address. " 
  236                                    << 
"Error: " << e.what());
 
  239        std::string txt_prefix_len = txt_subnet_prefix.substr(pos + 1);
 
  240        int16_t prefix_len = 0;
 
  244            prefix_len = boost::lexical_cast<int16_t>(txt_prefix_len);
 
  245            if (prefix_len > 32) {
 
  246                isc_throw(BadValue, 
"Provided IPv4 prefix len is out of 0-32 range.");
 
  248        } 
catch (
const std::exception& e) {
 
  249            isc_throw(BadValue, 
"DHCPv4 OptionClasslessStaticRoute " 
  250                                    << 
type_ << 
" has invalid value, provided prefix len " 
  251                                    << txt_prefix_len << 
" is not valid. " 
  252                                    << 
"Error: " << e.what());
 
  255        IOAddress router_addr = IOAddress(
"::");
 
  256        std::string txt_router = 
str::trim(parts[1]);
 
  258            router_addr = IOAddress(txt_router);
 
  259            if (!router_addr.
isV4()) {
 
  260                isc_throw(BadValue, 
"This is not IPv4 address.");
 
  262        } 
catch (
const std::exception& e) {
 
  263            isc_throw(BadValue, 
"DHCPv4 OptionClasslessStaticRoute " 
  264                                    << 
type_ << 
" has invalid value, provided router address " 
  265                                    << txt_router << 
" is not a valid IPv4 address. " 
  266                                    << 
"Error: " << e.what());
 
  269        StaticRouteTuple route = std::make_tuple(subnet_addr, prefix_len, router_addr);
 
  270        static_routes_.push_back(route);
 
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
bool isV4() const
Convenience function to check for an IPv4 address.
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)
OptionPtr cloneInternal() const
Copies this option and returns a pointer to the copy.
void packHeader(isc::util::OutputBuffer &buf, bool check=true) const
Store option's header in a buffer.
Option(Universe u, uint16_t type)
ctor, used for options constructed, usually during transmission
void check() const
A protected method used for option correctness.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
void writeUint32(uint32_t data)
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order.
#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.