diff --git a/src/lib/asiolink/io_address.cc b/src/lib/asiolink/io_address.cc index c805d5132a..90bdf57d29 100644 --- a/src/lib/asiolink/io_address.cc +++ b/src/lib/asiolink/io_address.cc @@ -76,6 +76,21 @@ IOAddress::fromBytes(short family, const uint8_t* data) { return IOAddress(string(addr_str)); } +std::vector +IOAddress::toBytes() const { + if (asio_address_.is_v4()) { + const asio::ip::address_v4::bytes_type bytes4 = + asio_address_.to_v4().to_bytes(); + return (std::vector(bytes4.begin(), bytes4.end())); + } + + // Not V4 address, so must be a V6 address (else we could never construct + // this object). + const asio::ip::address_v6::bytes_type bytes6 = + asio_address_.to_v6().to_bytes(); + return (std::vector(bytes6.begin(), bytes6.end())); +} + short IOAddress::getFamily() const { if (asio_address_.is_v4()) { diff --git a/src/lib/asiolink/io_address.h b/src/lib/asiolink/io_address.h index 042588caa0..5b11b8784c 100644 --- a/src/lib/asiolink/io_address.h +++ b/src/lib/asiolink/io_address.h @@ -24,6 +24,7 @@ #include #include +#include #include @@ -103,6 +104,19 @@ public: /// \return AF_INET for IPv4 or AF_INET6 for IPv6. short getFamily() const; + /// \brief Convenience function to check for an IPv4 address + /// + /// \return true if the address is a V4 address + bool isV4() const { + return (asio_address_.is_v4()); + } + + /// \brief Convenience function to check for an IPv6 address + /// + /// \return true if the address is a V6 address + bool isV6() const { + return (asio_address_.is_v6()); + } /// \brief Creates an address from over wire data. /// @@ -110,8 +124,13 @@ public: /// \param data pointer to first char of data /// /// \return Created IOAddress object - static IOAddress - fromBytes(short family, const uint8_t* data); + static IOAddress fromBytes(short family, const uint8_t* data); + + /// \brief Return address as set of bytes + /// + /// \return Contents of the address as a set of bytes in network-byte + /// order. + std::vector toBytes() const; /// \brief Compare addresses for equality /// diff --git a/src/lib/asiolink/tests/io_address_unittest.cc b/src/lib/asiolink/tests/io_address_unittest.cc index 5e621f37b7..55bf3611d3 100644 --- a/src/lib/asiolink/tests/io_address_unittest.cc +++ b/src/lib/asiolink/tests/io_address_unittest.cc @@ -18,7 +18,9 @@ #include #include +#include #include +#include using namespace isc::asiolink; @@ -84,6 +86,48 @@ TEST(IOAddressTest, fromBytes) { EXPECT_EQ(addr.toText(), IOAddress("192.0.2.3").toText()); } +TEST(IOAddressTest, toBytes) { + + // Address and network byte-order representation of the address. + const char* V4STRING = "192.0.2.1"; + uint8_t V4[] = {0xc0, 0x00, 0x02, 0x01}; + + const char* V6STRING = "2001:db8:1::dead:beef"; + uint8_t V6[] = { + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef + }; + + + // Do the V4 check. + IOAddress v4address(V4STRING); + std::vector v4bytes = v4address.toBytes(); + EXPECT_EQ(sizeof(V4), v4bytes.size()); + EXPECT_TRUE(std::equal(v4bytes.begin(), v4bytes.end(), &V4[0])); + + // Do the same for V6. + IOAddress v6address(V6STRING); + std::vector v6bytes = v6address.toBytes(); + EXPECT_EQ(sizeof(V6), v6bytes.size()); + EXPECT_TRUE(std::equal(v6bytes.begin(), v6bytes.end(), &V6[0])); +} + +TEST(IOAddressTest, isV4) { + const IOAddress address4("192.0.2.1"); + const IOAddress address6("2001:db8:1::dead:beef"); + + EXPECT_TRUE(address4.isV4()); + EXPECT_FALSE(address6.isV4()); +} + +TEST(IOAddressTest, isV6) { + const IOAddress address4("192.0.2.1"); + const IOAddress address6("2001:db8:1::dead:beef"); + + EXPECT_FALSE(address4.isV6()); + EXPECT_TRUE(address6.isV6()); +} + TEST(IOAddressTest, uint32) { IOAddress addr1("192.0.2.5");