noip.c (get_local_ipaddrs): Rewrite to use getifaddrs(3).
[preload-hacks] / noip.c
diff --git a/noip.c b/noip.c
index 1dac168..aaf21b4 100644 (file)
--- a/noip.c
+++ b/noip.c
  * the Free Software Foundation; either version 2 of the License, or (at
  * your option) any later version.
  *
- * Preload-hacks distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
+ * Preload-hacks are distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with mLib; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307, USA.
+ * with preload-hacks; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
 #define _GNU_SOURCE
@@ -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 ---------------------------------------------------*/
 
@@ -841,6 +841,9 @@ int socket(int pf, int ty, int proto)
       pf = PF_UNIX;
       proto = 0;
     case PF_UNIX:
+#ifdef PF_NETLINK
+    case PF_NETLINK:
+#endif
       return real_socket(pf, ty, proto);
     default:
       errno = EAFNOSUPPORT;
@@ -1078,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. */