From 9f1396d9c6c68d36ade0895148a15c963d014473 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 25 Apr 2014 09:49:26 +0100 Subject: [PATCH] noip.c (get_local_ipaddrs): Rewrite to use getifaddrs(3). This is a much better function to use because it actually gives us all of the addresses on each interface rather than just the first. Also, discard duplicate addresses, because they're more likely now. We should have done this already, but unaccountably neglected to. --- noip.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/noip.c b/noip.c index 804fc8a..aaf21b4 100644 --- a/noip.c +++ b/noip.c @@ -51,7 +51,7 @@ #include #include #include -#include +#include /*----- 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. */ -- 2.11.0