rtnetlink: Migrate IP functions

Change-Id: I4c87b59306911df4c5a73e441b2b962fbaab072c
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/rtnetlink.cpp b/src/rtnetlink.cpp
index 6e0946f..5d6e660 100644
--- a/src/rtnetlink.cpp
+++ b/src/rtnetlink.cpp
@@ -1,6 +1,7 @@
 #include "rtnetlink.hpp"
 
 #include "netlink.hpp"
+#include "util.hpp"
 
 #include <linux/rtnetlink.h>
 
@@ -19,10 +20,10 @@
         switch (hdr.rta_type)
         {
             case RTA_OIF:
-                ifIdx.emplace(stdplus::raw::copyFrom<int>(data));
+                ifIdx.emplace(stdplus::raw::copyFromStrict<int>(data));
                 break;
             case RTA_GATEWAY:
-                gw.emplace(stdplus::raw::copyFrom<Addr>(data));
+                gw.emplace(stdplus::raw::copyFromStrict<Addr>(data));
                 break;
         }
     }
@@ -51,4 +52,33 @@
     return std::nullopt;
 }
 
+AddressInfo addrFromRtm(std::string_view msg)
+{
+    const auto& ifa = extractRtData<ifaddrmsg>(msg);
+
+    AddressInfo ret;
+    ret.ifidx = ifa.ifa_index;
+    ret.flags = ifa.ifa_flags;
+    ret.scope = ifa.ifa_scope;
+    std::optional<InAddrAny> addr;
+    while (!msg.empty())
+    {
+        auto [hdr, data] = extractRtAttr(msg);
+        if (hdr.rta_type == IFA_ADDRESS)
+        {
+            addr.emplace(addrFromBuf(ifa.ifa_family, data));
+        }
+        else if (hdr.rta_type == IFA_FLAGS)
+        {
+            ret.flags = stdplus::raw::copyFromStrict<uint32_t>(data);
+        }
+    }
+    if (!addr)
+    {
+        throw std::runtime_error("Missing address");
+    }
+    ret.ifaddr = {*addr, ifa.ifa_prefixlen};
+    return ret;
+}
+
 } // namespace phosphor::network::netlink