#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
-#include <net/if.h>
+#include <ifaddrs.h>
/*----- Data structures ---------------------------------------------------*/
*/
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. */