* 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
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
-#include <net/if.h>
+#include <ifaddrs.h>
/*----- Data structures ---------------------------------------------------*/
pf = PF_UNIX;
proto = 0;
case PF_UNIX:
+#ifdef PF_NETLINK
+ case PF_NETLINK:
+#endif
return real_socket(pf, ty, proto);
default:
errno = EAFNOSUPPORT;
*/
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. */