neighbor: Refactor out netlink code

This will allow us to re-use the generic netlink bits for other netlink
request operations.

Adds test coverage to the netlink message parsing routines for sanity
and regression prevention.

Tested:
    Neighbor population still works when static neighbors are created on
    the BMC.

Change-Id: I755e86eb76a8f6f825616c13279328134de87da9
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/util.hpp b/util.hpp
index 723c941..fe94444 100644
--- a/util.hpp
+++ b/util.hpp
@@ -200,6 +200,53 @@
 
 } // namespace network
 
+/** @brief Copies data from a buffer into a copyable type
+ *
+ *  @param[in] data - The data buffer being extracted from
+ *  @param[in] emsg - The message to print if extraction fails
+ *  @return The copyable type with data populated
+ */
+template <typename T>
+T copyFrom(std::string_view data, const char* emsg = "Extract Failed")
+{
+    static_assert(std::is_trivially_copyable_v<T>);
+    T ret;
+    if (data.size() < sizeof(ret))
+    {
+        throw std::runtime_error(emsg);
+    }
+    std::memcpy(&ret, data.data(), sizeof(ret));
+    return ret;
+}
+
+/** @brief Extracts data from a buffer into a copyable type
+ *         Updates the data buffer to show that data was removed
+ *
+ *  @param[in,out] data - The data buffer being extracted from
+ *  @param[in] emsg     - The message to print if extraction fails
+ *  @return The copyable type with data populated
+ */
+template <typename T>
+T extract(std::string_view& data, const char* emsg = "Extract Failed")
+{
+    T ret = copyFrom<T>(data, emsg);
+    data.remove_prefix(sizeof(ret));
+    return ret;
+}
+
+/** @brief Compares two of the same trivially copyable types
+ *
+ *  @param[in] a - The data buffer being extracted from
+ *  @param[in] b - The message to print if extraction fails
+ *  @return True if the parameters are bitwise identical
+ */
+template <typename T>
+bool equal(const T& a, const T& b)
+{
+    static_assert(std::is_trivially_copyable_v<T>);
+    return memcmp(&a, &b, sizeof(T)) == 0;
+}
+
 class Descriptor
 {
   private: