noip.c (get_local_ipaddrs): Rewrite to use getifaddrs(3).
[preload-hacks] / noip.c
diff --git a/noip.c b/noip.c
index 804fc8a..aaf21b4 100644 (file)
--- a/noip.c
+++ b/noip.c
@@ -51,7 +51,7 @@
 #include <arpa/inet.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
-#include <net/if.h>
+#include <ifaddrs.h>
 
 /*----- Data structures ---------------------------------------------------*/
 
@@ -1081,27 +1081,31 @@ static void cleanup_sockdir(void)
  */
 static void get_local_ipaddrs(void)
 {
-  struct if_nameindex *ifn;
-  struct ifreq ifr;
-  int sk;
+  struct ifaddrs *ifa_head, *ifa;
+  const struct in_addr *a;
   int i;
 
-  ifn = if_nameindex();
-  if ((sk = real_socket(PF_INET, SOCK_STREAM, 00)) < 0)
-    return;
-  for (i = n_local_ipaddrs = 0;
-       n_local_ipaddrs < MAX_LOCAL_IPADDRS &&
-        ifn[i].if_name && *ifn[i].if_name;
-       i++) {
-    strcpy(ifr.ifr_name, ifn[i].if_name);
-    if (ioctl(sk, SIOCGIFADDR, &ifr) || ifr.ifr_addr.sa_family != AF_INET)
+  if (getifaddrs(&ifa_head)) { perror("getifaddrs"); return; }
+  for (n_local_ipaddrs = 0, ifa = ifa_head;
+       n_local_ipaddrs < MAX_LOCAL_IPADDRS && ifa;
+       ifa = ifa->ifa_next) {
+    if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
       continue;
-    local_ipaddrs[n_local_ipaddrs++] =
-      SIN(&ifr.ifr_addr)->sin_addr;
-    D( fprintf(stderr, "noip: local addr %s = %s\n", ifn[i].if_name,
-              inet_ntoa(local_ipaddrs[n_local_ipaddrs - 1])); )
+    a = &SIN(ifa->ifa_addr)->sin_addr;
+    D( fprintf(stderr, "noip: local addr %s = %s",
+              ifa->ifa_name, inet_ntoa(*a)); )
+    for (i = 0; i < n_local_ipaddrs; i++) {
+      if (local_ipaddrs[i].s_addr == a->s_addr) {
+       D( fprintf(stderr, " (duplicate)\n"); )
+       goto skip;
+      }
+    }
+    D( fprintf(stderr, "\n"); )
+    local_ipaddrs[n_local_ipaddrs] = *a;
+    n_local_ipaddrs++;
+  skip:;
   }
-  close(sk);
+  freeifaddrs(ifa_head);
 }
 
 /* Print the given message to standard error.  Avoids stdio. */