Commit 34496322 authored by JINMEI Tatuya's avatar JINMEI Tatuya

[master] Merge branch 'master' of ssh://git.bind10.isc.org/var/bind10/git/bind10

parents e4be11b7 9c7390b2
...@@ -212,8 +212,8 @@ bool IfaceMgr::openSockets4(const uint16_t port) { ...@@ -212,8 +212,8 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
addr != addrs.end(); addr != addrs.end();
++addr) { ++addr) {
// Skip IPv6 addresses // Skip all but V4 addresses.
if (addr->getFamily() != AF_INET) { if (!addr->isV4()) {
continue; continue;
} }
...@@ -247,8 +247,8 @@ bool IfaceMgr::openSockets6(const uint16_t port) { ...@@ -247,8 +247,8 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
addr != addrs.end(); addr != addrs.end();
++addr) { ++addr) {
// skip IPv4 addresses // Skip all but V6 addresses.
if (addr->getFamily() != AF_INET6) { if (!addr->isV6()) {
continue; continue;
} }
...@@ -356,12 +356,13 @@ int IfaceMgr::openSocket(const std::string& ifname, const IOAddress& addr, ...@@ -356,12 +356,13 @@ int IfaceMgr::openSocket(const std::string& ifname, const IOAddress& addr,
if (!iface) { if (!iface) {
isc_throw(BadValue, "There is no " << ifname << " interface present."); isc_throw(BadValue, "There is no " << ifname << " interface present.");
} }
switch (addr.getFamily()) { if (addr.isV4()) {
case AF_INET:
return openSocket4(*iface, addr, port); return openSocket4(*iface, addr, port);
case AF_INET6:
} else if (addr.isV6()) {
return openSocket6(*iface, addr, port); return openSocket6(*iface, addr, port);
default:
} else {
isc_throw(BadValue, "Failed to detect family of address: " isc_throw(BadValue, "Failed to detect family of address: "
<< addr.toText()); << addr.toText());
} }
...@@ -469,7 +470,7 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) { ...@@ -469,7 +470,7 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
asio::error_code err_code; asio::error_code err_code;
// If remote address is broadcast address we have to // If remote address is broadcast address we have to
// allow this on the socket. // allow this on the socket.
if (remote_addr.getAddress().is_v4() && if (remote_addr.isV4() &&
(remote_addr == IOAddress(DHCP_IPV4_BROADCAST_ADDRESS))) { (remote_addr == IOAddress(DHCP_IPV4_BROADCAST_ADDRESS))) {
// Socket has to be open prior to setting the broadcast // Socket has to be open prior to setting the broadcast
// option. Otherwise set_option will complain about // option. Otherwise set_option will complain about
...@@ -556,9 +557,7 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) { ...@@ -556,9 +557,7 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
addr6.sin6_scope_id = if_nametoindex(iface.getName().c_str()); addr6.sin6_scope_id = if_nametoindex(iface.getName().c_str());
} }
memcpy(&addr6.sin6_addr, memcpy(&addr6.sin6_addr, &addr.toBytes()[0], sizeof(addr6.sin6_addr));
addr.getAddress().to_v6().to_bytes().data(),
sizeof(addr6.sin6_addr));
#ifdef HAVE_SA_LEN #ifdef HAVE_SA_LEN
addr6.sin6_len = sizeof(addr6); addr6.sin6_len = sizeof(addr6);
#endif #endif
...@@ -660,7 +659,7 @@ IfaceMgr::send(const Pkt6Ptr& pkt) { ...@@ -660,7 +659,7 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
to.sin6_family = AF_INET6; to.sin6_family = AF_INET6;
to.sin6_port = htons(pkt->getRemotePort()); to.sin6_port = htons(pkt->getRemotePort());
memcpy(&to.sin6_addr, memcpy(&to.sin6_addr,
pkt->getRemoteAddr().getAddress().to_v6().to_bytes().data(), &pkt->getRemoteAddr().toBytes()[0],
16); 16);
to.sin6_scope_id = pkt->getIndex(); to.sin6_scope_id = pkt->getIndex();
...@@ -798,7 +797,7 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) { ...@@ -798,7 +797,7 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
s != socket_collection.end(); ++s) { s != socket_collection.end(); ++s) {
// Only deal with IPv4 addresses. // Only deal with IPv4 addresses.
if (s->addr_.getFamily() == AF_INET) { if (s->addr_.isV4()) {
names << s->sockfd_ << "(" << iface->getName() << ") "; names << s->sockfd_ << "(" << iface->getName() << ") ";
// Add this socket to listening set // Add this socket to listening set
...@@ -950,8 +949,8 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */ ...@@ -950,8 +949,8 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
for (SocketCollection::const_iterator s = socket_collection.begin(); for (SocketCollection::const_iterator s = socket_collection.begin();
s != socket_collection.end(); ++s) { s != socket_collection.end(); ++s) {
// Only deal with IPv4 addresses. // Only deal with IPv6 addresses.
if (s->addr_.getFamily() == AF_INET6) { if (s->addr_.isV6()) {
names << s->sockfd_ << "(" << iface->getName() << ") "; names << s->sockfd_ << "(" << iface->getName() << ") ";
// Add this socket to listening set // Add this socket to listening set
......
...@@ -86,7 +86,7 @@ Option4AddrLst::pack4(isc::util::OutputBuffer& buf) { ...@@ -86,7 +86,7 @@ Option4AddrLst::pack4(isc::util::OutputBuffer& buf) {
} }
void Option4AddrLst::setAddress(const isc::asiolink::IOAddress& addr) { void Option4AddrLst::setAddress(const isc::asiolink::IOAddress& addr) {
if (addr.getFamily() != AF_INET) { if (!addr.isV4()) {
isc_throw(BadValue, "Can't store non-IPv4 address in " isc_throw(BadValue, "Can't store non-IPv4 address in "
<< "Option4AddrLst option"); << "Option4AddrLst option");
} }
...@@ -107,7 +107,7 @@ void Option4AddrLst::setAddresses(const AddressContainer& addrs) { ...@@ -107,7 +107,7 @@ void Option4AddrLst::setAddresses(const AddressContainer& addrs) {
void Option4AddrLst::addAddress(const isc::asiolink::IOAddress& addr) { void Option4AddrLst::addAddress(const isc::asiolink::IOAddress& addr) {
if (addr.getFamily() != AF_INET) { if (!addr.isV4()) {
isc_throw(BadValue, "Can't store non-IPv4 address in " isc_throw(BadValue, "Can't store non-IPv4 address in "
<< "Option4AddrLst option"); << "Option4AddrLst option");
} }
......
...@@ -49,7 +49,7 @@ Option6AddrLst::Option6AddrLst(uint16_t type, OptionBufferConstIter begin, ...@@ -49,7 +49,7 @@ Option6AddrLst::Option6AddrLst(uint16_t type, OptionBufferConstIter begin,
void void
Option6AddrLst::setAddress(const isc::asiolink::IOAddress& addr) { Option6AddrLst::setAddress(const isc::asiolink::IOAddress& addr) {
if (addr.getFamily() != AF_INET6) { if (!addr.isV6()) {
isc_throw(BadValue, "Can't store non-IPv6 address in Option6AddrLst option"); isc_throw(BadValue, "Can't store non-IPv6 address in Option6AddrLst option");
} }
...@@ -72,7 +72,13 @@ void Option6AddrLst::pack(isc::util::OutputBuffer& buf) { ...@@ -72,7 +72,13 @@ void Option6AddrLst::pack(isc::util::OutputBuffer& buf) {
for (AddressContainer::const_iterator addr=addrs_.begin(); for (AddressContainer::const_iterator addr=addrs_.begin();
addr!=addrs_.end(); ++addr) { addr!=addrs_.end(); ++addr) {
buf.writeData(addr->getAddress().to_v6().to_bytes().data(), V6ADDRESS_LEN); if (!addr->isV6()) {
isc_throw(isc::BadValue, addr->toText()
<< " is not an IPv6 address");
}
// If an address is IPv6 address it should have assumed
// length of V6ADDRESS_LEN.
buf.writeData(&addr->toBytes()[0], V6ADDRESS_LEN);
} }
} }
...@@ -104,8 +110,7 @@ std::string Option6AddrLst::toText(int indent /* =0 */) { ...@@ -104,8 +110,7 @@ std::string Option6AddrLst::toText(int indent /* =0 */) {
} }
uint16_t Option6AddrLst::len() { uint16_t Option6AddrLst::len() {
return (OPTION6_HDR_LEN + addrs_.size() * V6ADDRESS_LEN);
return (OPTION6_HDR_LEN + addrs_.size()*V6ADDRESS_LEN);
} }
} // end of namespace isc::dhcp } // end of namespace isc::dhcp
......
...@@ -51,9 +51,11 @@ void Option6IAAddr::pack(isc::util::OutputBuffer& buf) { ...@@ -51,9 +51,11 @@ void Option6IAAddr::pack(isc::util::OutputBuffer& buf) {
// length without 4-byte option header // length without 4-byte option header
buf.writeUint16(len() - getHeaderLen()); buf.writeUint16(len() - getHeaderLen());
if (!addr_.isV6()) {
buf.writeData(addr_.getAddress().to_v6().to_bytes().data(), isc_throw(isc::BadValue, addr_.toText()
isc::asiolink::V6ADDRESS_LEN); << " is not an IPv6 address");
}
buf.writeData(&addr_.toBytes()[0], isc::asiolink::V6ADDRESS_LEN);
buf.writeUint32(preferred_); buf.writeUint32(preferred_);
buf.writeUint32(valid_); buf.writeUint32(valid_);
......
...@@ -58,14 +58,12 @@ void ...@@ -58,14 +58,12 @@ void
OptionCustom::addArrayDataField(const asiolink::IOAddress& address) { OptionCustom::addArrayDataField(const asiolink::IOAddress& address) {
checkArrayType(); checkArrayType();
if ((address.getFamily() == AF_INET && if ((address.isV4() && definition_.getType() != OPT_IPV4_ADDRESS_TYPE) ||
definition_.getType() != OPT_IPV4_ADDRESS_TYPE) || (address.isV6() && definition_.getType() != OPT_IPV6_ADDRESS_TYPE)) {
(address.getFamily() == AF_INET6 &&
definition_.getType() != OPT_IPV6_ADDRESS_TYPE)) {
isc_throw(BadDataTypeCast, "invalid address specified " isc_throw(BadDataTypeCast, "invalid address specified "
<< address.toText() << ". Expected a valid IPv" << address.toText() << ". Expected a valid IPv"
<< (definition_.getType() == OPT_IPV4_ADDRESS_TYPE ? "4" : "6") << (definition_.getType() == OPT_IPV4_ADDRESS_TYPE ?
<< " address."); "4" : "6") << " address.");
} }
OptionBuffer buf; OptionBuffer buf;
...@@ -454,10 +452,8 @@ OptionCustom::writeAddress(const asiolink::IOAddress& address, ...@@ -454,10 +452,8 @@ OptionCustom::writeAddress(const asiolink::IOAddress& address,
checkIndex(index); checkIndex(index);
if ((address.getFamily() == AF_INET && if ((address.isV4() && buffers_[index].size() != V4ADDRESS_LEN) ||
buffers_[index].size() != V4ADDRESS_LEN) || (address.isV6() && buffers_[index].size() != V6ADDRESS_LEN)) {
(address.getFamily() == AF_INET6 &&
buffers_[index].size() != V6ADDRESS_LEN)) {
isc_throw(BadDataTypeCast, "invalid address specified " isc_throw(BadDataTypeCast, "invalid address specified "
<< address.toText() << ". Expected a valid IPv" << address.toText() << ". Expected a valid IPv"
<< (buffers_[index].size() == V4ADDRESS_LEN ? "4" : "6") << (buffers_[index].size() == V4ADDRESS_LEN ? "4" : "6")
......
...@@ -146,27 +146,8 @@ OptionDataTypeUtil::readAddress(const std::vector<uint8_t>& buf, ...@@ -146,27 +146,8 @@ OptionDataTypeUtil::readAddress(const std::vector<uint8_t>& buf,
void void
OptionDataTypeUtil::writeAddress(const asiolink::IOAddress& address, OptionDataTypeUtil::writeAddress(const asiolink::IOAddress& address,
std::vector<uint8_t>& buf) { std::vector<uint8_t>& buf) {
// @todo There is a ticket 2396 submitted, which adds the const std::vector<uint8_t>& vec = address.toBytes();
// functionality to return a buffer representation of buf.insert(buf.end(), vec.begin(), vec.end());
// IOAddress. If so, this function can be simplified.
if (address.getAddress().is_v4()) {
asio::ip::address_v4::bytes_type addr_bytes =
address.getAddress().to_v4().to_bytes();
// Increase the buffer size by the size of IPv4 address.
buf.resize(buf.size() + addr_bytes.size());
std::copy_backward(addr_bytes.begin(), addr_bytes.end(),
buf.end());
} else if (address.getAddress().is_v6()) {
asio::ip::address_v6::bytes_type addr_bytes =
address.getAddress().to_v6().to_bytes();
// Incresase the buffer size by the size of IPv6 address.
buf.resize(buf.size() + addr_bytes.size());
std::copy_backward(addr_bytes.begin(), addr_bytes.end(),
buf.end());
} else {
isc_throw(BadDataTypeCast, "the address " << address.toText()
<< " is neither valid IPv4 not IPv6 address.");
}
} }
void void
......
...@@ -379,12 +379,9 @@ OptionDefinition::writeToBuffer(const std::string& value, ...@@ -379,12 +379,9 @@ OptionDefinition::writeToBuffer(const std::string& value,
case OPT_IPV6_ADDRESS_TYPE: case OPT_IPV6_ADDRESS_TYPE:
{ {
asiolink::IOAddress address(value); asiolink::IOAddress address(value);
if (address.getFamily() != AF_INET && if (!address.isV4() && !address.isV6()) {
address.getFamily() != AF_INET6) {
isc_throw(BadDataTypeCast, "provided address " << address.toText() isc_throw(BadDataTypeCast, "provided address " << address.toText()
<< " is not a valid " << " is not a valid IPv4 or IPv6 address.");
<< (address.getAddress().is_v4() ? "IPv4" : "IPv6")
<< " address");
} }
OptionDataTypeUtil::writeAddress(address, buf); OptionDataTypeUtil::writeAddress(address, buf);
return; return;
......
...@@ -38,16 +38,8 @@ public: ...@@ -38,16 +38,8 @@ public:
/// @param [out] buf output buffer. /// @param [out] buf output buffer.
void writeAddress(const asiolink::IOAddress& address, void writeAddress(const asiolink::IOAddress& address,
std::vector<uint8_t>& buf) { std::vector<uint8_t>& buf) {
short family = address.getFamily(); const std::vector<uint8_t>& vec = address.toBytes();
if (family == AF_INET) { buf.insert(buf.end(), vec.begin(), vec.end());
asio::ip::address_v4::bytes_type buf_addr =
address.getAddress().to_v4().to_bytes();
buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
} else if (family == AF_INET6) {
asio::ip::address_v6::bytes_type buf_addr =
address.getAddress().to_v6().to_bytes();
buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
}
} }
/// @brief Write integer (signed or unsigned) into a buffer. /// @brief Write integer (signed or unsigned) into a buffer.
......
...@@ -34,16 +34,8 @@ public: ...@@ -34,16 +34,8 @@ public:
/// @param [out] buf output buffer. /// @param [out] buf output buffer.
void writeAddress(const asiolink::IOAddress& address, void writeAddress(const asiolink::IOAddress& address,
std::vector<uint8_t>& buf) { std::vector<uint8_t>& buf) {
short family = address.getFamily(); const std::vector<uint8_t>& vec = address.toBytes();
if (family == AF_INET) { buf.insert(buf.end(), vec.begin(), vec.end());
asio::ip::address_v4::bytes_type buf_addr =
address.getAddress().to_v4().to_bytes();
buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
} else if (family == AF_INET6) {
asio::ip::address_v6::bytes_type buf_addr =
address.getAddress().to_v6().to_bytes();
buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
}
} }
/// @brief Write integer (signed or unsigned) into a buffer. /// @brief Write integer (signed or unsigned) into a buffer.
......
...@@ -207,10 +207,9 @@ TEST_F(OptionDefinitionTest, ipv6AddressArray) { ...@@ -207,10 +207,9 @@ TEST_F(OptionDefinitionTest, ipv6AddressArray) {
// Write addresses to the buffer. // Write addresses to the buffer.
OptionBuffer buf(addrs.size() * asiolink::V6ADDRESS_LEN); OptionBuffer buf(addrs.size() * asiolink::V6ADDRESS_LEN);
for (int i = 0; i < addrs.size(); ++i) { for (int i = 0; i < addrs.size(); ++i) {
asio::ip::address_v6::bytes_type addr_bytes = const std::vector<uint8_t>& vec = addrs[i].toBytes();
addrs[i].getAddress().to_v6().to_bytes(); ASSERT_EQ(asiolink::V6ADDRESS_LEN, vec.size());
ASSERT_EQ(asiolink::V6ADDRESS_LEN, addr_bytes.size()); std::copy(vec.begin(), vec.end(),
std::copy(addr_bytes.begin(), addr_bytes.end(),
buf.begin() + i * asiolink::V6ADDRESS_LEN); buf.begin() + i * asiolink::V6ADDRESS_LEN);
} }
// Create DHCPv6 option from this buffer. Once option is created it is // Create DHCPv6 option from this buffer. Once option is created it is
...@@ -306,10 +305,9 @@ TEST_F(OptionDefinitionTest, ipv4AddressArray) { ...@@ -306,10 +305,9 @@ TEST_F(OptionDefinitionTest, ipv4AddressArray) {
// Write addresses to the buffer. // Write addresses to the buffer.
OptionBuffer buf(addrs.size() * asiolink::V4ADDRESS_LEN); OptionBuffer buf(addrs.size() * asiolink::V4ADDRESS_LEN);
for (int i = 0; i < addrs.size(); ++i) { for (int i = 0; i < addrs.size(); ++i) {
asio::ip::address_v4::bytes_type addr_bytes = const std::vector<uint8_t> vec = addrs[i].toBytes();
addrs[i].getAddress().to_v4().to_bytes(); ASSERT_EQ(asiolink::V4ADDRESS_LEN, vec.size());
ASSERT_EQ(asiolink::V4ADDRESS_LEN, addr_bytes.size()); std::copy(vec.begin(), vec.end(),
std::copy(addr_bytes.begin(), addr_bytes.end(),
buf.begin() + i * asiolink::V4ADDRESS_LEN); buf.begin() + i * asiolink::V4ADDRESS_LEN);
} }
// Create DHCPv6 option from this buffer. Once option is created it is // Create DHCPv6 option from this buffer. Once option is created it is
...@@ -512,11 +510,10 @@ TEST_F(OptionDefinitionTest, recordIAAddr6) { ...@@ -512,11 +510,10 @@ TEST_F(OptionDefinitionTest, recordIAAddr6) {
OptionPtr option_v6; OptionPtr option_v6;
asiolink::IOAddress addr_v6("2001:0db8::ff00:0042:8329"); asiolink::IOAddress addr_v6("2001:0db8::ff00:0042:8329");
OptionBuffer buf(asiolink::V6ADDRESS_LEN); OptionBuffer buf(asiolink::V6ADDRESS_LEN);
ASSERT_TRUE(addr_v6.getAddress().is_v6()); ASSERT_TRUE(addr_v6.isV6());
asio::ip::address_v6::bytes_type addr_bytes = const std::vector<uint8_t>& vec = addr_v6.toBytes();
addr_v6.getAddress().to_v6().to_bytes(); ASSERT_EQ(asiolink::V6ADDRESS_LEN, vec.size());
ASSERT_EQ(asiolink::V6ADDRESS_LEN, addr_bytes.size()); std::copy(vec.begin(), vec.end(), buf.begin());
std::copy(addr_bytes.begin(), addr_bytes.end(), buf.begin());
for (int i = 0; i < option6_iaaddr_len - asiolink::V6ADDRESS_LEN; ++i) { for (int i = 0; i < option6_iaaddr_len - asiolink::V6ADDRESS_LEN; ++i) {
buf.push_back(i); buf.push_back(i);
......
...@@ -53,8 +53,11 @@ isc::asiolink::IOAddress firstAddrInPrefix6(const isc::asiolink::IOAddress& pref ...@@ -53,8 +53,11 @@ isc::asiolink::IOAddress firstAddrInPrefix6(const isc::asiolink::IOAddress& pref
} }
// First we copy the whole address as 16 bytes. // First we copy the whole address as 16 bytes.
// We don't check that it is a valid IPv6 address and thus has
// the required length because it is already checked by
// the calling function.
uint8_t packed[V6ADDRESS_LEN]; uint8_t packed[V6ADDRESS_LEN];
memcpy(packed, prefix.getAddress().to_v6().to_bytes().data(), 16); memcpy(packed, &prefix.toBytes()[0], V6ADDRESS_LEN);
// If the length is divisible by 8, it is simple. We just zero out the host // If the length is divisible by 8, it is simple. We just zero out the host
// part. Otherwise we need to handle the byte that has to be partially // part. Otherwise we need to handle the byte that has to be partially
...@@ -95,6 +98,9 @@ isc::asiolink::IOAddress firstAddrInPrefix4(const isc::asiolink::IOAddress& pref ...@@ -95,6 +98,9 @@ isc::asiolink::IOAddress firstAddrInPrefix4(const isc::asiolink::IOAddress& pref
isc_throw(isc::BadValue, "Too large netmask. 0..32 is allowed in IPv4"); isc_throw(isc::BadValue, "Too large netmask. 0..32 is allowed in IPv4");
} }
// We don't check that it is a valid IPv4 address and thus has
// a required length of 4 bytes because it has been already
// checked by the calling function.
uint32_t addr = prefix; uint32_t addr = prefix;
return (IOAddress(addr & (~bitMask4[len]))); return (IOAddress(addr & (~bitMask4[len])));
} }
...@@ -132,7 +138,7 @@ isc::asiolink::IOAddress lastAddrInPrefix6(const isc::asiolink::IOAddress& prefi ...@@ -132,7 +138,7 @@ isc::asiolink::IOAddress lastAddrInPrefix6(const isc::asiolink::IOAddress& prefi
// First we copy the whole address as 16 bytes. // First we copy the whole address as 16 bytes.
uint8_t packed[V6ADDRESS_LEN]; uint8_t packed[V6ADDRESS_LEN];
memcpy(packed, prefix.getAddress().to_v6().to_bytes().data(), 16); memcpy(packed, &prefix.toBytes()[0], 16);
// if the length is divisible by 8, it is simple. We just fill the host part // if the length is divisible by 8, it is simple. We just fill the host part
// with ones. Otherwise we need to handle the byte that has to be partially // with ones. Otherwise we need to handle the byte that has to be partially
...@@ -169,19 +175,23 @@ namespace dhcp { ...@@ -169,19 +175,23 @@ namespace dhcp {
isc::asiolink::IOAddress firstAddrInPrefix(const isc::asiolink::IOAddress& prefix, isc::asiolink::IOAddress firstAddrInPrefix(const isc::asiolink::IOAddress& prefix,
uint8_t len) { uint8_t len) {
if (prefix.getFamily() == AF_INET) { if (prefix.isV4()) {
return firstAddrInPrefix4(prefix, len); return (firstAddrInPrefix4(prefix, len));
} else { } else {
return firstAddrInPrefix6(prefix, len); return (firstAddrInPrefix6(prefix, len));
} }
} }
isc::asiolink::IOAddress lastAddrInPrefix(const isc::asiolink::IOAddress& prefix, isc::asiolink::IOAddress lastAddrInPrefix(const isc::asiolink::IOAddress& prefix,
uint8_t len) { uint8_t len) {
if (prefix.getFamily() == AF_INET) { if (prefix.isV4()) {
return lastAddrInPrefix4(prefix, len); return (lastAddrInPrefix4(prefix, len));
} else { } else {
return lastAddrInPrefix6(prefix, len); return (lastAddrInPrefix6(prefix, len));
} }
} }
......
...@@ -30,20 +30,21 @@ AllocEngine::IterativeAllocator::IterativeAllocator() ...@@ -30,20 +30,21 @@ AllocEngine::IterativeAllocator::IterativeAllocator()
isc::asiolink::IOAddress isc::asiolink::IOAddress
AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress& addr) { AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress& addr) {
// Get a buffer holding an address.
const std::vector<uint8_t>& vec = addr.toBytes();
// Get the address length.
const int len = vec.size();
// Since the same array will be used to hold the IPv4 and IPv6
// address we have to make sure that the size of the array
// we allocate will work for both types of address.
BOOST_STATIC_ASSERT(V4ADDRESS_LEN <= V6ADDRESS_LEN);
uint8_t packed[V6ADDRESS_LEN]; uint8_t packed[V6ADDRESS_LEN];
int len;
// First we copy the whole address as 16 bytes. // Copy the address. It can be either V4 or V6.
if (addr.getFamily()==AF_INET) { std::memcpy(packed, &vec[0], len);
// IPv4
std::memcpy(packed, addr.getAddress().to_v4().to_bytes().data(), 4);
len = 4;
} else {
// IPv6
std::memcpy(packed, addr.getAddress().to_v6().to_bytes().data(), 16);
len = 16;
}
// Increase the address.
for (int i = len - 1; i >= 0; --i) { for (int i = len - 1; i >= 0; --i) {
++packed[i]; ++packed[i];
if (packed[i] != 0) { if (packed[i] != 0) {
......
...@@ -34,7 +34,7 @@ Pool4::Pool4(const isc::asiolink::IOAddress& first, ...@@ -34,7 +34,7 @@ Pool4::Pool4(const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last) const isc::asiolink::IOAddress& last)
:Pool(first, last) { :Pool(first, last) {
// check if specified address boundaries are sane // check if specified address boundaries are sane
if (first.getFamily() != AF_INET || last.getFamily() != AF_INET) { if (!first.isV4() || !last.isV4()) {
isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4"); isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4");
} }
...@@ -48,7 +48,7 @@ Pool4::Pool4(const isc::asiolink::IOAddress& prefix, ...@@ -48,7 +48,7 @@ Pool4::Pool4(const isc::asiolink::IOAddress& prefix,
:Pool(prefix, IOAddress("0.0.0.0")) { :Pool(prefix, IOAddress("0.0.0.0")) {
// check if the prefix is sane // check if the prefix is sane
if (prefix.getFamily() != AF_INET) { if (!prefix.isV4()) {
isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4"); isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4");
} }
...@@ -67,7 +67,7 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first, ...@@ -67,7 +67,7 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first,
:Pool(first, last), type_(type), prefix_len_(0) { :Pool(first, last), type_(type), prefix_len_(0) {
// check if specified address boundaries are sane // check if specified address boundaries are sane
if (first.getFamily() != AF_INET6 || last.getFamily() != AF_INET6) { if (!first.isV6() || !last.isV6()) {
isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6"); isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
} }
...@@ -98,7 +98,7 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix, ...@@ -98,7 +98,7 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix,
type_(type), prefix_len_(prefix_len) { type_(type), prefix_len_(prefix_len) {
// check if the prefix is sane // check if the prefix is sane
if (prefix.getFamily() != AF_INET6) { if (!prefix.isV6()) {
isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6"); isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
} }
......
...@@ -30,8 +30,8 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len, ...@@ -30,8 +30,8 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
:id_(getNextID()), prefix_(prefix), prefix_len_(len), t1_(t1), :id_(getNextID()), prefix_(prefix), prefix_len_(len), t1_(t1),
t2_(t2), valid_(valid_lifetime), t2_(t2), valid_(valid_lifetime),
last_allocated_(lastAddrInPrefix(prefix, len)) { last_allocated_(lastAddrInPrefix(prefix, len)) {
if ( (prefix.getFamily() == AF_INET6 && len > 128) || if ((prefix.isV6() && len > 128) ||
(prefix.getFamily() == AF_INET && len > 32) ) {