netlink: Add common function for extracting payload
Change-Id: I809bd17d50ccb8a8f624b6117c088193f55e79de
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/ipaddress.cpp b/src/ipaddress.cpp
index 6aebc94..56bec97 100644
--- a/src/ipaddress.cpp
+++ b/src/ipaddress.cpp
@@ -98,7 +98,7 @@
{
throw std::runtime_error("Not an address msg");
}
- auto ifaddr = stdplus::raw::extract<ifaddrmsg>(msg);
+ const auto& ifaddr = netlink::extractRtData<ifaddrmsg>(msg);
// Filter out addresses we don't care about
unsigned ifindex = ifaddr.ifa_index;
diff --git a/src/neighbor.cpp b/src/neighbor.cpp
index cfa8e60..58e1a47 100644
--- a/src/neighbor.cpp
+++ b/src/neighbor.cpp
@@ -35,7 +35,7 @@
{
throw std::runtime_error("Not a neighbor msg");
}
- auto ndm = stdplus::raw::extract<ndmsg>(msg);
+ const auto& ndm = netlink::extractRtData<ndmsg>(msg);
// Filter out neighbors we don't care about
unsigned ifindex = ndm.ndm_ifindex;
diff --git a/src/netlink.hpp b/src/netlink.hpp
index 1260f8e..754b4b4 100644
--- a/src/netlink.hpp
+++ b/src/netlink.hpp
@@ -3,6 +3,7 @@
#include <linux/rtnetlink.h>
#include <function2/function2.hpp>
+#include <stdplus/raw.hpp>
#include <string_view>
#include <tuple>
#include <type_traits>
@@ -35,6 +36,20 @@
*/
void receive(int sock, ReceiveCallback cb);
+/* @brief Call on an rtnetlink payload
+ * Updates the input to remove the attr parsed out.
+ *
+ * @param[in,out] data - The buffer holding rtpayload to parse
+ * @return The payload for the rt msg
+ */
+template <typename T>
+constexpr const T& extractRtData(std::string_view& data)
+{
+ const T& ret = stdplus::raw::refFrom<T, stdplus::raw::Aligned>(data);
+ data.remove_prefix(NLMSG_ALIGN(sizeof(T)));
+ return ret;
+}
+
/* @brief Call on a block of rtattrs to parse a single one out
* Updates the input to remove the attr parsed out.
*
diff --git a/src/routing_table.cpp b/src/routing_table.cpp
index 20535e5..39cdf2d 100644
--- a/src/routing_table.cpp
+++ b/src/routing_table.cpp
@@ -53,7 +53,7 @@
{
throw std::runtime_error("Not a route msg");
}
- auto rtm = stdplus::raw::extract<rtmsg>(msg);
+ const auto& rtm = netlink::extractRtData<rtmsg>(msg);
if ((rtm.rtm_family != AF_INET && rtm.rtm_family != AF_INET6) ||
rtm.rtm_table != RT_TABLE_MAIN)
diff --git a/src/system_queries.cpp b/src/system_queries.cpp
index aa8e46b..0152f4a 100644
--- a/src/system_queries.cpp
+++ b/src/system_queries.cpp
@@ -131,7 +131,7 @@
{
throw std::runtime_error("Not an interface msg");
}
- auto ifinfo = stdplus::raw::extract<ifinfomsg>(msg);
+ const auto& ifinfo = netlink::extractRtData<ifinfomsg>(msg);
InterfaceInfo ret;
ret.flags = ifinfo.ifi_flags;
ret.idx = ifinfo.ifi_index;