15#include <boost/dynamic_bitset.hpp> 
   29                                   const uint8_t delegated_prefix_length,
 
   31                                   const uint8_t excluded_prefix_length)
 
   33      excluded_prefix_length_(excluded_prefix_length),
 
   37    if (!delegated_prefix.
isV6() || !excluded_prefix.
isV6() ||
 
   38        (delegated_prefix_length > 128) || (excluded_prefix_length_ > 128)) {
 
   39        isc_throw(BadValue, 
"invalid delegated or excluded prefix values specified: " 
   40                  << delegated_prefix << 
"/" 
   41                  << static_cast<int>(delegated_prefix_length) << 
", " 
   42                  << excluded_prefix << 
"/" 
   43                  << static_cast<int>(excluded_prefix_length_));
 
   47    if (excluded_prefix_length_ <= delegated_prefix_length) {
 
   49                  << excluded_prefix << 
"/" 
   50                  << 
static_cast<int>(excluded_prefix_length_)
 
   51                  << 
" must be greater than the length of the" 
   52                  " delegated prefix " << delegated_prefix << 
"/" 
   53                  << 
static_cast<int>(delegated_prefix_length));
 
   58    std::vector<uint8_t> delegated_prefix_bytes = delegated_prefix.
toBytes();
 
   59    boost::dynamic_bitset<uint8_t> delegated_prefix_bits(delegated_prefix_bytes.rbegin(),
 
   60                                                         delegated_prefix_bytes.rend());
 
   62    std::vector<uint8_t> excluded_prefix_bytes = excluded_prefix.
toBytes();
 
   63    boost::dynamic_bitset<uint8_t> excluded_prefix_bits(excluded_prefix_bytes.rbegin(),
 
   64                                                        excluded_prefix_bytes.rend());
 
   68    const uint8_t delta = 128 - delegated_prefix_length;
 
   70    if ((delegated_prefix_bits >> delta) != (excluded_prefix_bits >> delta)) {
 
   72                  << excluded_prefix << 
"/" 
   73                  << 
static_cast<int>(excluded_prefix_length_)
 
   74                  << 
" must have the same common prefix part of " 
   75                  << 
static_cast<int>(delegated_prefix_length)
 
   76                  << 
" as the delegated prefix " 
   77                  << delegated_prefix << 
"/" 
   78                  << 
static_cast<int>(delegated_prefix_length));
 
   84    excluded_prefix_bits <<= delegated_prefix_length;
 
   87    const uint8_t subnet_id_length = getSubnetIDLength(delegated_prefix_length,
 
   88                                                       excluded_prefix_length);
 
   89    for (uint8_t i = 0; i < subnet_id_length; ++i) {
 
   91        const boost::dynamic_bitset<uint8_t> first_byte = excluded_prefix_bits >> 120;
 
   94        uint8_t val = 
static_cast<uint8_t
>(first_byte.to_ulong());
 
   98        if (i == subnet_id_length - 1) {
 
   99            uint8_t length_delta = excluded_prefix_length_ - delegated_prefix_length;
 
  100            if (length_delta % 8 != 0) {
 
  102                mask <<= (8 - (length_delta % 8));
 
  107        subnet_id_.push_back(val);
 
  110        excluded_prefix_bits <<= 8;
 
 
  117      excluded_prefix_length_(0),
 
 
  131    if ((excluded_prefix_length_ == 0) || subnet_id_.empty()) {
 
  133                  " must not be empty");
 
  143    buf.
writeData(
static_cast<const void*
>(&subnet_id_[0]), subnet_id_.size());
 
 
  153    if (std::distance(begin, end) < 2) {
 
  158    uint8_t excluded_prefix_length = *begin++;
 
  159    if (excluded_prefix_length == 0) {
 
  163    std::vector<uint8_t> subnet_id_bytes(begin, end);
 
  168    uint8_t last_bits_num = excluded_prefix_length % 8;
 
  169    if (last_bits_num > 0) {
 
  170        *subnet_id_bytes.rbegin() = (*subnet_id_bytes.rbegin() >> (8 - last_bits_num)
 
  171                                     << (8 - (last_bits_num)));
 
  174    excluded_prefix_length_ = excluded_prefix_length;
 
  175    subnet_id_.swap(subnet_id_bytes);
 
 
  180    return (
getHeaderLen() + 
sizeof(excluded_prefix_length_) + subnet_id_.size());
 
 
  185    std::ostringstream s;
 
  187    s << 
"excluded-prefix-len=" << 
static_cast<unsigned>(excluded_prefix_length_)
 
 
  194                                    const uint8_t delegated_prefix_length)
 const {
 
  196    std::vector<uint8_t> delegated_prefix_bytes = delegated_prefix.
toBytes();
 
  199    const uint8_t bytes_length = (delegated_prefix_length / 8) +
 
  200        static_cast<uint8_t
>(delegated_prefix_length % 8 != 0);
 
  201    std::fill(delegated_prefix_bytes.begin() + bytes_length,
 
  202              delegated_prefix_bytes.end(), 0);
 
  205    boost::dynamic_bitset<uint8_t> bits(delegated_prefix_bytes.rbegin(),
 
  206                                        delegated_prefix_bytes.rend());
 
  208    boost::dynamic_bitset<uint8_t> subnet_id_bits(subnet_id_.rbegin(),
 
  213    for (
int i = subnet_id_bits.size() - 1; i >= 0; --i) {
 
  214        bits.set(128 - delegated_prefix_length - subnet_id_bits.size() + i,
 
  215                 subnet_id_bits.test(i));
 
  219    std::vector<uint8_t> bytes(V6ADDRESS_LEN);
 
  220    boost::to_block_range(bits, bytes.rbegin());
 
 
  227Option6PDExclude::getSubnetIDLength(
const uint8_t delegated_prefix_length,
 
  228                                    const uint8_t excluded_prefix_length)
 const {
 
  229    uint8_t subnet_id_length_bits = excluded_prefix_length -
 
  230        delegated_prefix_length - 1;
 
  231    uint8_t subnet_id_length = (subnet_id_length_bits / 8) + 1;
 
  232    return (subnet_id_length);
 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
The IOAddress class represents an IP addresses (version agnostic)
bool isV6() const
Convenience function to check for an IPv6 address.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
virtual OptionPtr clone() const
Copies this option and returns a pointer to the copy.
asiolink::IOAddress getExcludedPrefix(const asiolink::IOAddress &delegated_prefix, const uint8_t delegated_prefix_length) const
Returns excluded prefix.
virtual std::string toText(int indent=0) const
Returns Prefix Exclude option in textual format.
Option6PDExclude(const isc::asiolink::IOAddress &delegated_prefix, const uint8_t delegated_prefix_length, const isc::asiolink::IOAddress &excluded_prefix, const uint8_t excluded_prefix_length)
Constructor.
virtual uint16_t len() const
Returns length of the complete option (data length + DHCPv6 option header)
virtual void pack(isc::util::OutputBuffer &buf, bool check=true) const
Writes option in wire-format to a buffer.
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.
std::string headerToText(const int indent=0, const std::string &type_name="") const
Returns option header in the textual format.
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
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
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.
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
boost::shared_ptr< Option > OptionPtr
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.