mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
Rewrite the interface detection code.
Turns out SIOCGIFCONF is rather painful to get working cross-platform. This should work better, and can be used even with ipv6 :)
This commit is contained in:
parent
c1a60551ae
commit
4cec4b9f96
3 changed files with 67 additions and 41 deletions
|
@ -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 \
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -52,6 +52,9 @@ static __attribute__ ((used)) const char rcsid[] =
|
|||
#ifdef HAVE_NETDB_H
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
# include <ifaddrs.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
#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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue