Fix representation IPv6 DNS servers

The `getNameServerFromResolvd` function ignores the family type of
address received from `systemd-resolvd`. It leads to an incorrect
representation of IPv6 addresses.

This commit fixes that.

Resolves openbmc/phosphor-networkd#34

Testing:
Add an IPv6 DNS server:
```
busctl set-property xyz.openbmc_project.Network \
                    /xyz/openbmc_project/network/eth0 \
                    xyz.openbmc_project.Network.EthernetInterface \
                    StaticNameServers as 1 2001:db8:1::1
```
After the setting will be applied the `Nameservers` property must
contain valid representation:
```
busctl get-property xyz.openbmc_project.Network \
                    /xyz/openbmc_project/network/eth0 \
                    xyz.openbmc_project.Network.EthernetInterface \
                    Nameservers

as 1 "2001:db8:1::1"
```

Change-Id: Id69a0ffcceedd5be28e26ea9b9aca7f37e6a9345
Signed-off-by: Alexander Filippov <a.filippov@yadro.com>
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
index c47a759..6b3099e 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -756,14 +756,42 @@
     auto tupleVector = std::get_if<type>(&name);
     for (auto i = tupleVector->begin(); i != tupleVector->end(); ++i)
     {
-        std::vector<uint8_t> ipaddress = std::get<1>(*i);
-        std::string address;
-        for (auto byte : ipaddress)
+        int addressFamily = std::get<0>(*i);
+        std::vector<uint8_t>& ipaddress = std::get<1>(*i);
+
+        switch (addressFamily)
         {
-            address += std::to_string(byte) + ".";
+            case AF_INET:
+                if (ipaddress.size() == sizeof(struct in_addr))
+                {
+                    servers.push_back(toString(
+                        *reinterpret_cast<struct in_addr*>(ipaddress.data())));
+                }
+                else
+                {
+                    log<level::ERR>(
+                        "Invalid data recived from Systemd-Resolved");
+                }
+                break;
+
+            case AF_INET6:
+                if (ipaddress.size() == sizeof(struct in6_addr))
+                {
+                    servers.push_back(toString(
+                        *reinterpret_cast<struct in6_addr*>(ipaddress.data())));
+                }
+                else
+                {
+                    log<level::ERR>(
+                        "Invalid data recived from Systemd-Resolved");
+                }
+                break;
+
+            default:
+                log<level::ERR>(
+                    "Unsupported address family in DNS from Systemd-Resolved");
+                break;
         }
-        address.pop_back();
-        servers.push_back(address);
     }
     return servers;
 }
diff --git a/test/test_util.cpp b/test/test_util.cpp
index e3a1fba..7742ca7 100644
--- a/test/test_util.cpp
+++ b/test/test_util.cpp
@@ -57,10 +57,12 @@
 {
     struct in_addr ip1;
     EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
+    EXPECT_EQ("192.168.10.1", toString(ip1));
     EXPECT_EQ("192.168.10.1", toString(InAddrAny(ip1)));
 
     struct in6_addr ip2;
     EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
+    EXPECT_EQ("fdd8:b5ad:9d93:94ee::2:1", toString(ip2));
     EXPECT_EQ("fdd8:b5ad:9d93:94ee::2:1", toString(InAddrAny(ip2)));
 }
 
diff --git a/util.cpp b/util.cpp
index 0c5dbff..e517f06 100644
--- a/util.cpp
+++ b/util.cpp
@@ -176,33 +176,44 @@
     throw std::runtime_error("Unsupported address family");
 }
 
+std::string toString(const struct in_addr& addr)
+{
+    std::string ip(INET_ADDRSTRLEN, '\0');
+    if (inet_ntop(AF_INET, &addr, ip.data(), ip.size()) == nullptr)
+    {
+        throw std::runtime_error("Failed to convert IP4 to string");
+    }
+
+    ip.resize(strlen(ip.c_str()));
+    return ip;
+}
+
+std::string toString(const struct in6_addr& addr)
+{
+    std::string ip(INET6_ADDRSTRLEN, '\0');
+    if (inet_ntop(AF_INET6, &addr, ip.data(), ip.size()) == nullptr)
+    {
+        throw std::runtime_error("Failed to convert IP6 to string");
+    }
+
+    ip.resize(strlen(ip.c_str()));
+    return ip;
+}
+
 std::string toString(const InAddrAny& addr)
 {
-    std::string ip;
     if (std::holds_alternative<struct in_addr>(addr))
     {
         const auto& v = std::get<struct in_addr>(addr);
-        ip.resize(INET_ADDRSTRLEN);
-        if (inet_ntop(AF_INET, &v, ip.data(), ip.size()) == NULL)
-        {
-            throw std::runtime_error("Failed to convert IP4 to string");
-        }
+        return toString(v);
     }
     else if (std::holds_alternative<struct in6_addr>(addr))
     {
         const auto& v = std::get<struct in6_addr>(addr);
-        ip.resize(INET6_ADDRSTRLEN);
-        if (inet_ntop(AF_INET6, &v, ip.data(), ip.size()) == NULL)
-        {
-            throw std::runtime_error("Failed to convert IP6 to string");
-        }
+        return toString(v);
     }
-    else
-    {
-        throw std::runtime_error("Invalid addr type");
-    }
-    ip.resize(strlen(ip.c_str()));
-    return ip;
+
+    throw std::runtime_error("Invalid addr type");
 }
 
 bool isLinkLocalIP(const std::string& address)
diff --git a/util.hpp b/util.hpp
index 05c400b..7e1aab6 100644
--- a/util.hpp
+++ b/util.hpp
@@ -98,6 +98,8 @@
  * @returns String representation of the ip.
  */
 std::string toString(const InAddrAny& addr);
+std::string toString(const struct in_addr& addr);
+std::string toString(const struct in6_addr& addr);
 
 /* @brief converts the prefix into subnetmask.
  * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).