16 #include <boost/dynamic_bitset.hpp> 
   30                                    const uint8_t delegated_prefix_length,
 
   32                                    const uint8_t excluded_prefix_length)
 
   34       excluded_prefix_length_(excluded_prefix_length),
 
   38     if (!delegated_prefix.
isV6() || !excluded_prefix.
isV6() ||
 
   39         (delegated_prefix_length > 128) || (excluded_prefix_length_ > 128)) {
 
   41                   << delegated_prefix << 
"/" 
   42                   << static_cast<int>(delegated_prefix_length) << 
", " 
   43                   << excluded_prefix << 
"/" 
   44                   << static_cast<int>(excluded_prefix_length_));
 
   48     if (excluded_prefix_length_ <= delegated_prefix_length) {
 
   50                   << excluded_prefix << 
"/" 
   51                   << static_cast<int>(excluded_prefix_length_)
 
   52                   << 
" must be greater than the length of the" 
   53                   " delegated prefix " << delegated_prefix << 
"/" 
   54                   << static_cast<int>(delegated_prefix_length));
 
   59     std::vector<uint8_t> delegated_prefix_bytes = delegated_prefix.
toBytes();
 
   60     boost::dynamic_bitset<uint8_t> delegated_prefix_bits(delegated_prefix_bytes.rbegin(),
 
   61                                                          delegated_prefix_bytes.rend());
 
   63     std::vector<uint8_t> excluded_prefix_bytes = excluded_prefix.
toBytes();
 
   64     boost::dynamic_bitset<uint8_t> excluded_prefix_bits(excluded_prefix_bytes.rbegin(),
 
   65                                                         excluded_prefix_bytes.rend());
 
   69     const uint8_t delta = 128 - delegated_prefix_length;
 
   71     if ((delegated_prefix_bits >> delta) != (excluded_prefix_bits >> delta)) {
 
   73                   << excluded_prefix << 
"/" 
   74                   << static_cast<int>(excluded_prefix_length_)
 
   75                   << 
" must have the same common prefix part of " 
   76                   << static_cast<int>(delegated_prefix_length)
 
   77                   << 
" as the delegated prefix " 
   78                   << delegated_prefix << 
"/" 
   79                   << static_cast<int>(delegated_prefix_length));
 
   85     excluded_prefix_bits <<= delegated_prefix_length;
 
   88     const uint8_t subnet_id_length = getSubnetIDLength(delegated_prefix_length,
 
   89                                                        excluded_prefix_length);
 
   90     for (uint8_t i = 0; i < subnet_id_length; ++i) {
 
   92         const boost::dynamic_bitset<uint8_t> first_byte = excluded_prefix_bits >> 120;
 
   95         uint8_t val = 
static_cast<uint8_t
>(first_byte.to_ulong());
 
   99         if (i == subnet_id_length - 1) {
 
  100             uint8_t length_delta = excluded_prefix_length_ - delegated_prefix_length;
 
  101             if (length_delta % 8 != 0) {
 
  103                 mask <<= (8 - (length_delta % 8));
 
  108         subnet_id_.push_back(val);
 
  111         excluded_prefix_bits <<= 8;
 
  118       excluded_prefix_length_(0),
 
  125     return (cloneInternal<Option6PDExclude>());
 
  132     if ((excluded_prefix_length_ == 0) || subnet_id_.empty()) {
 
  134                   " must not be empty");
 
  144     buf.
writeData(static_cast<const void*>(&subnet_id_[0]), subnet_id_.size());
 
  154     if (std::distance(begin, end) < 2) {
 
  159     uint8_t excluded_prefix_length = *begin++;
 
  160     if (excluded_prefix_length == 0) {
 
  164     std::vector<uint8_t> subnet_id_bytes(begin, end);
 
  169     uint8_t last_bits_num = excluded_prefix_length % 8;
 
  170     if (last_bits_num > 0) {
 
  171         *subnet_id_bytes.rbegin() = (*subnet_id_bytes.rbegin() >> (8 - last_bits_num)
 
  172                                      << (8 - (last_bits_num)));
 
  175     excluded_prefix_length_ = excluded_prefix_length;
 
  176     subnet_id_.swap(subnet_id_bytes);
 
  181     return (
getHeaderLen() + 
sizeof(excluded_prefix_length_) + subnet_id_.size());
 
  186     std::ostringstream s;
 
  188     s << 
"excluded-prefix-len=" << 
static_cast<unsigned>(excluded_prefix_length_)
 
  195                                     const uint8_t delegated_prefix_length)
 const {
 
  197     std::vector<uint8_t> delegated_prefix_bytes = delegated_prefix.
toBytes();
 
  200     const uint8_t bytes_length = (delegated_prefix_length / 8) +
 
  201         static_cast<uint8_t>(delegated_prefix_length % 8 != 0);
 
  202     std::fill(delegated_prefix_bytes.begin() + bytes_length,
 
  203               delegated_prefix_bytes.end(), 0);
 
  206     boost::dynamic_bitset<uint8_t> bits(delegated_prefix_bytes.rbegin(),
 
  207                                         delegated_prefix_bytes.rend());
 
  209     boost::dynamic_bitset<uint8_t> subnet_id_bits(subnet_id_.rbegin(),
 
  214     for (
int i = subnet_id_bits.size() - 1; i >= 0; --i) {
 
  215         bits.set(128 - delegated_prefix_length - subnet_id_bits.size() + i,
 
  216                  subnet_id_bits.test(i));
 
  220     std::vector<uint8_t> bytes(V6ADDRESS_LEN);
 
  221     boost::to_block_range(bits, bytes.rbegin());
 
  228 Option6PDExclude::getSubnetIDLength(
const uint8_t delegated_prefix_length,
 
  229                                     const uint8_t excluded_prefix_length)
 const {
 
  230     uint8_t subnet_id_length_bits = excluded_prefix_length -
 
  231         delegated_prefix_length - 1;
 
  232     uint8_t subnet_id_length = (subnet_id_length_bits / 8) + 1;
 
  233     return (subnet_id_length);
 
asiolink::IOAddress getExcludedPrefix(const asiolink::IOAddress &delegated_prefix, const uint8_t delegated_prefix_length) const 
Returns excluded prefix. 
void packHeader(isc::util::OutputBuffer &buf) const 
Store option's header in a buffer. 
virtual void pack(isc::util::OutputBuffer &buf) const 
Writes option in wire-format to a buffer. 
boost::shared_ptr< Option > OptionPtr
virtual uint16_t len() const 
Returns length of the complete option (data length + DHCPv6 option header) 
virtual uint16_t getHeaderLen() const 
Returns length of header (2 for v4, 4 for v6) 
std::vector< uint8_t > toBytes() const 
Return address as set of bytes. 
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. 
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. 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data. 
The OutputBuffer class is a buffer abstraction for manipulating mutable data. 
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer 
Defines the logger used by the top-level component of kea-dhcp-ddns. 
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 ('hex') format. 
virtual std::string toText(int indent=0) const 
Returns Prefix Exclude option in textual format. 
virtual OptionPtr clone() const 
Copies this option and returns a pointer to the copy. 
std::string headerToText(const int indent=0, const std::string &type_name="") const 
Returns option header in the textual format. 
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer. 
bool isV6() const 
Convenience function to check for an IPv6 address. 
The IOAddress class represents an IP addresses (version agnostic) 
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.