// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. #include #include #include #include #include #include #include #include #include using namespace std; using namespace isc::asiolink; using namespace isc::util; namespace isc { namespace dhcp { Option6IAAddr::Option6IAAddr(uint16_t type, const isc::asiolink::IOAddress& addr, uint32_t pref, uint32_t valid) :Option(V6, type), addr_(addr), preferred_(pref), valid_(valid) { setEncapsulatedSpace("dhcp6"); if (!addr.isV6()) { isc_throw(isc::BadValue, addr_ << " is not an IPv6 address"); } } Option6IAAddr::Option6IAAddr(uint32_t type, OptionBuffer::const_iterator begin, OptionBuffer::const_iterator end) :Option(V6, type), addr_("::") { setEncapsulatedSpace("dhcp6"); unpack(begin, end); } void Option6IAAddr::pack(isc::util::OutputBuffer& buf) { buf.writeUint16(type_); // len() returns complete option length. len field contains // length without 4-byte option header buf.writeUint16(len() - getHeaderLen()); if (!addr_.isV6()) { isc_throw(isc::BadValue, addr_ << " is not an IPv6 address"); } buf.writeData(&addr_.toBytes()[0], isc::asiolink::V6ADDRESS_LEN); buf.writeUint32(preferred_); buf.writeUint32(valid_); // parse suboption (there shouldn't be any for IAADDR) packOptions(buf); } void Option6IAAddr::unpack(OptionBuffer::const_iterator begin, OptionBuffer::const_iterator end) { if ( distance(begin, end) < OPTION6_IAADDR_LEN) { isc_throw(OutOfRange, "Option " << type_ << " truncated"); } // 16 bytes: IPv6 address addr_ = IOAddress::fromBytes(AF_INET6, &(*begin)); begin += V6ADDRESS_LEN; preferred_ = readUint32(&(*begin), distance(begin, end)); begin += sizeof(uint32_t); valid_ = readUint32(&(*begin), distance(begin, end)); begin += sizeof(uint32_t); unpackOptions(OptionBuffer(begin, end)); } std::string Option6IAAddr::toText(int indent /* =0 */) { stringstream tmp; for (int i=0; i