Browse Source

[2396] Add methods to IOAddress: toBytes(), isV4() and isV6()

Stephen Morris 12 years ago
parent
commit
8bc5490b0e

+ 15 - 0
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<uint8_t>
+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<uint8_t>(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<uint8_t>(bytes6.begin(), bytes6.end()));
+}
+
 short
 IOAddress::getFamily() const {
     if (asio_address_.is_v4()) {

+ 21 - 2
src/lib/asiolink/io_address.h

@@ -24,6 +24,7 @@
 
 #include <functional>
 #include <string>
+#include <vector>
 
 #include <exceptions/exceptions.h>
 
@@ -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<uint8_t> toBytes() const;
 
     /// \brief Compare addresses for equality
     ///

+ 44 - 0
src/lib/asiolink/tests/io_address_unittest.cc

@@ -18,7 +18,9 @@
 #include <asiolink/io_error.h>
 #include <asiolink/io_address.h>
 
+#include <algorithm>
 #include <cstring>
+#include <vector>
 
 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<uint8_t> 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<uint8_t> 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");