diff --git a/config.d/header_files.m4 b/config.d/header_files.m4 index a9cd4da1f..2f8bd6861 100644 --- a/config.d/header_files.m4 +++ b/config.d/header_files.m4 @@ -10,10 +10,10 @@ AC_CHECK_HEADERS( alloca.h arpa/inet.h asm/io.h assert.h conio.h \ ctype.h ddraw.h dinput.h direct.h dirent.h dlfcn.h dmedia/audio.h \ dmedia/cdaudio.h dpmi.h dsound.h errno.h execinfo.h fcntl.h io.h \ - libc.h limits.h linux/cdrom.h linux/joystick.h linux/soundcard.h \ - machine/soundcard.h malloc.h math.h mgraph.h _mingw.h netdb.h \ - netinet/in.h process.h pthread.h pwd.h rpc/types.h setjmp.h signal.h \ - stdarg.h stdio.h stdlib.h string.h strings.h sys/asoundlib.h \ + ifaddrs.h libc.h limits.h linux/cdrom.h linux/joystick.h \ + linux/soundcard.h machine/soundcard.h malloc.h math.h mgraph.h _mingw.h \ + netdb.h netinet/in.h process.h pthread.h pwd.h rpc/types.h setjmp.h \ + signal.h stdarg.h stdio.h stdlib.h string.h strings.h sys/asoundlib.h \ sys/audioio.h sys/filio.h sys/ioctl.h sys/io.h sys/ipc.h sys/mman.h \ sys/param.h sys/poll.h sys/shm.h sys/signal.h sys/socket.h \ sys/soundcard.h sys/stat.h sys/time.h sys/types.h sys/uio.h termios.h \ diff --git a/config.d/networking.m4 b/config.d/networking.m4 index 1ed5a9d52..815bce859 100644 --- a/config.d/networking.m4 +++ b/config.d/networking.m4 @@ -79,3 +79,16 @@ connect (0, NULL, 42); LIBS="$SAVELIBS" fi AC_SUBST(NET_LIBS) + +AC_MSG_CHECKING([for getifaddrs]) +SAVELIBS="$LIBS" +LIBS="$LIBS $NET_LIBS" +AC_TRY_LINK([], + [ +getifaddrs (0); + ], + AC_DEFINE(HAVE_GETIFADDRS, 1, [Define this if you have getifaddrs()]) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no) +) +LIBS="$SAVELIBS" diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 1b9f5a7b8..d705ac04e 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -52,6 +52,9 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_NETDB_H # include #endif +#ifdef HAVE_IFADDRS_H +# include +#endif #ifdef HAVE_SYS_PARAM_H # include #endif @@ -114,7 +117,7 @@ static int net_controlsocket; static int net_broadcastsocket = 0; static struct qsockaddr broadcastaddr; -static unsigned myAddr; +static uint32_t myAddr; #include "net_udp.h" @@ -126,43 +129,53 @@ uint32_t *last_iface; static int get_iface_list (int sock) { - int ret; - int buflen; - struct ifconf ifconf; +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifa_head; + struct ifaddrs *ifa; + struct ifreq ifreq; - buflen = sizeof (*ifconf.ifc_req) * 4; - ifconf.ifc_req = 0; - do { - buflen *= 2; - ifconf.ifc_len = buflen; - ifconf.ifc_req = realloc (ifconf.ifc_req, ifconf.ifc_len); - if ((ret = ioctl (sock, SIOCGIFCONF, &ifconf)) < 0) { - Sys_MaskPrintf (SYS_NET, "ioctl: %s", strerror (errno)); - break; - } - } while (ifconf.ifc_len == buflen); - - if (ret >= 0) { - int i; - num_ifaces = ifconf.ifc_len / sizeof (*ifconf.ifc_req); - ifaces = malloc (num_ifaces * sizeof (int32_t)); - Sys_MaskPrintf (SYS_NET, "Interfaces (count = %d)\n", num_ifaces); - for (i = 0; i < num_ifaces; i++) { - struct sockaddr_in *sa; - - sa = (struct sockaddr_in *) &ifconf.ifc_req[i].ifr_ifru.ifru_addr; - Sys_MaskPrintf (SYS_NET, " %-10s %s\n", - ifconf.ifc_req[i].ifr_name, - inet_ntoa (sa->sin_addr)); - memcpy (&ifaces[i], &sa->sin_addr, sizeof (uint32_t)); - if (!default_iface && ifaces[i] != htonl (0x7f000001)) - default_iface = &ifaces[i]; - } + if (getifaddrs (&ifa_head) < 0) + goto no_ifaddrs; + for (ifa = ifa_head; ifa; ifa = ifa->ifa_next) { + if (!ifa->ifa_flags & IFF_UP) + continue; + if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) + continue; + strncpy (ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ); + ifreq.ifr_name[IFNAMSIZ - 1] = 0; + ioctl (sock, SIOCGIFINDEX, (char*) &ifreq); + if (ifreq.ifr_ifindex > num_ifaces) + num_ifaces = ifreq.ifr_ifindex; } - if (default_iface) - myAddr = *default_iface; - free (ifconf.ifc_req); - return ret; + ifaces = malloc (num_ifaces * sizeof (uint32_t)); + Sys_MaskPrintf (SYS_NET, "%d interfaces\n", num_ifaces); + for (ifa = ifa_head; ifa; ifa = ifa->ifa_next) { + int index; + struct sockaddr_in *sa; + + if (!ifa->ifa_flags & IFF_UP) + continue; + if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) + continue; + strncpy (ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ); + ifreq.ifr_name[IFNAMSIZ - 1] = 0; + ioctl (sock, SIOCGIFINDEX, (char*) &ifreq); + index = ifreq.ifr_ifindex - 1; + sa = (struct sockaddr_in *) ifa->ifa_addr; + memcpy (&ifaces[index], &sa->sin_addr, sizeof (uint32_t)); + Sys_MaskPrintf (SYS_NET, " %-10s %s\n", ifa->ifa_name, + inet_ntoa (sa->sin_addr)); + if (!default_iface && ifaces[index] != htonl (0x7f000001)) + default_iface = &ifaces[index]; + } + freeifaddrs (ifa_head); + return 0; +#endif +no_ifaddrs: + ifaces = &myAddr; + default_iface = &ifaces[0]; + num_ifaces = 1; + return 0; } int @@ -187,7 +200,7 @@ UDP_Init (void) gethostname (buff, MAXHOSTNAMELEN); local = gethostbyname (buff); if (local) - myAddr = *(int *) local->h_addr_list[0]; + myAddr = *(uint32_t *) local->h_addr_list[0]; else myAddr = 0;