ClatUtils - implement hardwareAddressType()
Test: builds and atest netd_unit_test
Bug: 65674744
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ia032ab061bf7121affc465ec6cd63524979f26b1
diff --git a/server/ClatUtils.cpp b/server/ClatUtils.cpp
index ddf8cd9..6edc97a 100644
--- a/server/ClatUtils.cpp
+++ b/server/ClatUtils.cpp
@@ -16,11 +16,43 @@
#include "ClatUtils.h"
+#include <errno.h>
+#include <linux/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
#define LOG_TAG "ClatUtils"
#include <log/log.h>
+#include "android-base/unique_fd.h"
+
namespace android {
namespace net {
+int hardwareAddressType(const std::string& interface) {
+ base::unique_fd ufd(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+
+ if (ufd < 0) {
+ const int err = errno;
+ ALOGE("socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)");
+ return -err;
+ };
+
+ struct ifreq ifr = {};
+ // We use strncpy() instead of strlcpy() since kernel has to be able
+ // to handle non-zero terminated junk passed in by userspace anyway,
+ // and this way too long interface names (more than IFNAMSIZ-1 = 15
+ // characters plus terminating NULL) will not get truncated to 15
+ // characters and zero-terminated and thus potentially erroneously
+ // match a truncated interface if one were to exist.
+ strncpy(ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name));
+
+ if (ioctl(ufd, SIOCGIFHWADDR, &ifr, sizeof(ifr))) return -errno;
+
+ return ifr.ifr_hwaddr.sa_family;
+}
+
} // namespace net
} // namespace android