util: Clean up MAC address formatting

We should be using the built in ether_addr type wherever we want to
reference the MAC address in byte form. This gets rid of the integer MAC
type and makes functions that consistently take the byte form of the MAC
where possible.

Change-Id: Ic9e3eae8b5608ef517416215fb336871911975cc
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/util.cpp b/util.cpp
index 91030c8..a17bc5d 100644
--- a/util.cpp
+++ b/util.cpp
@@ -16,6 +16,7 @@
 #include <phosphor-logging/log.hpp>
 #include <stdexcept>
 #include <string>
+#include <variant>
 #include <xyz/openbmc_project/Common/error.hpp>
 
 namespace phosphor
@@ -549,7 +550,7 @@
     "xyz.openbmc_project.Inventory.Item.NetworkInterface";
 constexpr auto invRoot = "/xyz/openbmc_project/inventory";
 
-std::string getfromInventory(sdbusplus::bus::bus& bus)
+ether_addr getfromInventory(sdbusplus::bus::bus& bus)
 {
     std::vector<DbusInterface> interfaces;
     interfaces.emplace_back(invNetworkIntf);
@@ -583,8 +584,6 @@
     auto objPath = objectTree.begin()->first;
     auto service = objectTree.begin()->second.begin()->first;
 
-    sdbusplus::message::variant<std::string> value;
-
     auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
                                       propIntf, methodGet);
 
@@ -599,8 +598,19 @@
         elog<InternalFailure>();
     }
 
+    std::variant<std::string> value;
     reply.read(value);
-    return sdbusplus::message::variant_ns::get<std::string>(value);
+    return fromString(std::get<std::string>(value));
+}
+
+ether_addr fromString(const char* str)
+{
+    struct ether_addr* mac = ether_aton(str);
+    if (mac == nullptr)
+    {
+        throw std::runtime_error("Invalid mac address string");
+    }
+    return *mac;
 }
 
 std::string toString(const ether_addr& mac)
@@ -608,6 +618,26 @@
     return ether_ntoa(&mac);
 }
 
+bool isEmpty(const ether_addr& mac)
+{
+    return equal(mac, ether_addr{});
+}
+
+bool isMulticast(const ether_addr& mac)
+{
+    return mac.ether_addr_octet[0] & 0b1;
+}
+
+bool isUnicast(const ether_addr& mac)
+{
+    return !isEmpty(mac) && !isMulticast(mac);
+}
+
+bool isLocalAdmin(const ether_addr& mac)
+{
+    return mac.ether_addr_octet[0] & 0b10;
+}
+
 } // namespace mac_address
 } // namespace network
 } // namespace phosphor