[Open Screen] Accept a variable length hardware address.

Some network interfaces have up to a 16-byte hardware address.  Don't
assume the address is 6 bytes and allow variable length addresses.

Fixed: 356381986
Change-Id: Ie8f6752f4ae2d49c094bf3fd0e163ad13e96896b
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/5879001
Commit-Queue: Jordan Bayles <jophba@chromium.org>
Reviewed-by: Jordan Bayles <jophba@chromium.org>
diff --git a/platform/base/interface_info.h b/platform/base/interface_info.h
index 327de15..b5eaa6e 100644
--- a/platform/base/interface_info.h
+++ b/platform/base/interface_info.h
@@ -45,8 +45,9 @@
   // identifying this interface on the host machine.
   NetworkInterfaceIndex index = kInvalidNetworkInterfaceIndex;
 
-  // MAC address of the interface.  All 0s if unavailable.
-  std::array<uint8_t, 6> hardware_address = {};
+  // MAC address of the interface.  Typically 6 or 16 bytes.  Empty if
+  // unavailable.
+  std::vector<uint8_t> hardware_address;
 
   // Interface name (e.g. eth0) if available.
   std::string name;
diff --git a/platform/impl/network_interface_linux.cc b/platform/impl/network_interface_linux.cc
index 67fb1ad..14b0bbd 100644
--- a/platform/impl/network_interface_linux.cc
+++ b/platform/impl/network_interface_linux.cc
@@ -25,6 +25,7 @@
 
 #include "platform/api/network_interface.h"
 #include "platform/base/ip_address.h"
+#include "platform/base/span.h"
 #include "platform/impl/network_interface.h"
 #include "platform/impl/scoped_pipe.h"
 #include "util/osp_logging.h"
@@ -94,9 +95,10 @@
       info->name =
           GetInterfaceName(reinterpret_cast<const char*>(RTA_DATA(rta)));
     } else if (rta->rta_type == IFLA_ADDRESS) {
-      OSP_CHECK_EQ(sizeof(info->hardware_address), RTA_PAYLOAD(rta));
-      std::memcpy(info->hardware_address.data(), RTA_DATA(rta),
-                  sizeof(info->hardware_address));
+      ByteView address_bytes(reinterpret_cast<uint8_t*>(RTA_DATA(rta)),
+                             RTA_PAYLOAD(rta));
+      info->hardware_address.assign(address_bytes.cbegin(),
+                                    address_bytes.cend());
     }
   }
 
diff --git a/platform/impl/network_interface_mac.cc b/platform/impl/network_interface_mac.cc
index bed500c..2d32b3f 100644
--- a/platform/impl/network_interface_mac.cc
+++ b/platform/impl/network_interface_mac.cc
@@ -20,6 +20,7 @@
 
 #include "platform/api/network_interface.h"
 #include "platform/base/ip_address.h"
+#include "platform/base/span.h"
 #include "platform/impl/network_interface.h"
 #include "platform/impl/scoped_pipe.h"
 #include "util/osp_logging.h"
@@ -129,11 +130,10 @@
     // Add another address to the list of addresses for the current interface.
     if (cur->ifa_addr->sa_family == AF_LINK) {  // Hardware ethernet address.
       auto* const addr_dl = reinterpret_cast<const sockaddr_dl*>(cur->ifa_addr);
-      const caddr_t lladdr = LLADDR(addr_dl);
-      static_assert(sizeof(lladdr) >= sizeof(interface->hardware_address),
-                    "Platform defines too-small link addresses?");
-      memcpy(&interface->hardware_address[0], &lladdr[0],
-             sizeof(interface->hardware_address));
+      ByteView address_bytes(reinterpret_cast<uint8_t*>(LLADDR(addr_dl)),
+                             addr_dl->sdl_alen);
+      interface->hardware_address.assign(address_bytes.cbegin(),
+                                         address_bytes.cend());
     } else if (cur->ifa_addr->sa_family == AF_INET6) {  // Ipv6 address.
       struct in6_ifreq ifr = {};
       // Reject network interfaces that have a deprecated flag set.