[PATCH 1/5] New function to find hardware address of interface

Daniel M. Weeks weeksd2 at rpi.edu
Fri Apr 17 04:02:01 AEST 2020


Return the hardware address of an interface based on its type. The
address may be truncated if the supplied buffer is too short but the
function will always return the actual length of the address.

Signed-off-by: Daniel M. Weeks <weeksd2 at rpi.edu>
---
 discover/network.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 discover/network.h |  2 ++
 2 files changed, 47 insertions(+)

diff --git a/discover/network.c b/discover/network.c
index 099ca98..ad7eced 100644
--- a/discover/network.c
+++ b/discover/network.c
@@ -5,7 +5,10 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <sys/socket.h>
+#include <ifaddrs.h>
 #include <linux/if.h>
+#include <linux/if_arp.h>
+#include <linux/if_packet.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <i18n/i18n.h>
@@ -239,6 +242,48 @@ static void remove_interface(struct network *network,
 	talloc_free(interface);
 }
 
+int network_get_hwaddr(const char *ifname, uint8_t *dest, size_t dest_len)
+{
+	struct ifaddrs *ifaddr, *ifa;
+	struct sockaddr_ll *sll;
+	int chomp;
+
+	int ret = -1;
+	size_t len;
+
+	if (getifaddrs(&ifaddr) < 0)
+		return -1;
+
+	for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+		if (strcmp(ifname, ifa->ifa_name) == 0) {
+			sll = (struct sockaddr_ll *) ifa->ifa_addr;
+
+			switch (sll->sll_hatype) {
+			case ARPHRD_ETHER:
+				chomp = 0;
+				break;
+			case ARPHRD_INFINIBAND:
+				chomp = 12;
+				break;
+			default:
+				chomp = -1;
+				break;
+			}
+
+			if (chomp >= 0) {
+				len = sll->sll_halen - chomp;
+				memcpy(dest, sll->sll_addr+chomp, dest_len);
+				ret = len;
+			}
+
+			break;
+		}
+	}
+
+	freeifaddrs(ifaddr);
+	return ret;
+}
+
 void network_register_device(struct network *network,
 		struct discover_device *dev)
 {
diff --git a/discover/network.h b/discover/network.h
index 0cea6f2..d802962 100644
--- a/discover/network.h
+++ b/discover/network.h
@@ -6,6 +6,8 @@ struct device_handler;
 struct discover_device;
 struct waitset;
 
+int network_get_hwaddr(const char *ifname, uint8_t *dest, size_t dest_len);
+
 struct network *network_init(struct device_handler *handler,
 		struct waitset *waitset, bool dry_run);
 int network_shutdown(struct network *network);
-- 
Daniel M. Weeks


-- 
Daniel M. Weeks
Lead HPC Developer
Center for Computational Innovations
Rensselaer Polytechnic Institute
Troy, NY 12180
518-276-4458


More information about the Petitboot mailing list