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

Signed-off-by: Daniel M. Weeks <[email protected]>
---
 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
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to