[OpenPower-Firmware] [PATCH 3/7] udhcpc: Use getifaddrs for udhcp_read_interface

Daniel M. Weeks weeksd2 at rpi.edu
Fri Apr 17 06:19:05 AEST 2020


Use a method to discover hardware addresses that supports non-MAC
interfaces.

Signed-off-by: Daniel M. Weeks <weeksd2 at rpi.edu>
---
 networking/udhcp/socket.c | 68 +++++++++++++++++----------------------
 1 file changed, 29 insertions(+), 39 deletions(-)

diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c
index 34049c3ee..60ec0e3c0 100644
--- a/networking/udhcp/socket.c
+++ b/networking/udhcp/socket.c
@@ -24,54 +24,44 @@
  */
 #include "common.h"
 #include <net/if.h>
+#include <ifaddrs.h>
+#include <netpacket/packet.h>
 
 int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac)
 {
-	/* char buffer instead of bona-fide struct avoids aliasing warning */
-	char ifr_buf[sizeof(struct ifreq)];
-	struct ifreq *const ifr = (void *)ifr_buf;
+	struct ifaddrs *ifap, *ifa;
+	struct sockaddr_ll *sll;
 
-	int fd;
-	struct sockaddr_in *our_ip;
-
-	memset(ifr, 0, sizeof(*ifr));
-	fd = xsocket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-
-	ifr->ifr_addr.sa_family = AF_INET;
-	strncpy_IFNAMSIZ(ifr->ifr_name, interface);
-	if (nip) {
-		if (ioctl_or_perror(fd, SIOCGIFADDR, ifr,
-			"is interface %s up and configured?", interface)
-		) {
-			close(fd);
-			return -1;
-		}
-		our_ip = (struct sockaddr_in *) &ifr->ifr_addr;
-		*nip = our_ip->sin_addr.s_addr;
-		log1("IP %s", inet_ntoa(our_ip->sin_addr));
-	}
+	int retval = -1;
 
-	if (ifindex) {
-		if (ioctl_or_warn(fd, SIOCGIFINDEX, ifr) != 0) {
-			close(fd);
-			return -1;
-		}
-		log2("ifindex %d", ifr->ifr_ifindex);
-		*ifindex = ifr->ifr_ifindex;
-	}
+	getifaddrs(&ifap);
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		struct sockaddr_in *sip;
 
-	if (mac) {
-		if (ioctl_or_warn(fd, SIOCGIFHWADDR, ifr) != 0) {
-			close(fd);
-			return -1;
+		if (!ifa->ifa_addr || (strcmp(ifa->ifa_name, interface) != 0) || ifa->ifa_addr->sa_family != AF_PACKET)
+			continue;
+
+		sip = (struct sockaddr_in*)(ifa->ifa_addr);
+
+		sll = (struct sockaddr_ll*)(ifa->ifa_addr);
+		memcpy(mac, sll->sll_addr, 6);
+		log2("MAC %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+		*ifindex = sll->sll_ifindex;
+		log2("ifindex %d", *ifindex);
+
+		if (nip) {
+			*nip = sip->sin_addr.s_addr;
+			log1("IP %s", inet_ntoa(sip->sin_addr));
 		}
-		memcpy(mac, ifr->ifr_hwaddr.sa_data, 6);
-		log2("MAC %02x:%02x:%02x:%02x:%02x:%02x",
-			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+		retval = sll->sll_hatype;
 	}
+	freeifaddrs(ifap);
+
+	if (retval < 0)
+		bb_error_msg("can't get %s", "MAC");
 
-	close(fd);
-	return 0;
+	return retval;
 }
 
 /* 1. None of the callers expects it to ever fail */
-- 
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 OpenPower-Firmware mailing list