mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +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 \
|
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 \
|
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 \
|
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 \
|
ifaddrs.h libc.h limits.h linux/cdrom.h linux/joystick.h \
|
||||||
machine/soundcard.h malloc.h math.h mgraph.h _mingw.h netdb.h \
|
linux/soundcard.h machine/soundcard.h malloc.h math.h mgraph.h _mingw.h \
|
||||||
netinet/in.h process.h pthread.h pwd.h rpc/types.h setjmp.h signal.h \
|
netdb.h netinet/in.h process.h pthread.h pwd.h rpc/types.h setjmp.h \
|
||||||
stdarg.h stdio.h stdlib.h string.h strings.h sys/asoundlib.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/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/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 \
|
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"
|
LIBS="$SAVELIBS"
|
||||||
fi
|
fi
|
||||||
AC_SUBST(NET_LIBS)
|
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
|
#ifdef HAVE_NETDB_H
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_IFADDRS_H
|
||||||
|
# include <ifaddrs.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
#ifdef HAVE_SYS_PARAM_H
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -114,7 +117,7 @@ static int net_controlsocket;
|
||||||
static int net_broadcastsocket = 0;
|
static int net_broadcastsocket = 0;
|
||||||
static struct qsockaddr broadcastaddr;
|
static struct qsockaddr broadcastaddr;
|
||||||
|
|
||||||
static unsigned myAddr;
|
static uint32_t myAddr;
|
||||||
|
|
||||||
#include "net_udp.h"
|
#include "net_udp.h"
|
||||||
|
|
||||||
|
@ -126,43 +129,53 @@ uint32_t *last_iface;
|
||||||
static int
|
static int
|
||||||
get_iface_list (int sock)
|
get_iface_list (int sock)
|
||||||
{
|
{
|
||||||
int ret;
|
#ifdef HAVE_GETIFADDRS
|
||||||
int buflen;
|
struct ifaddrs *ifa_head;
|
||||||
struct ifconf ifconf;
|
struct ifaddrs *ifa;
|
||||||
|
struct ifreq ifreq;
|
||||||
|
|
||||||
buflen = sizeof (*ifconf.ifc_req) * 4;
|
if (getifaddrs (&ifa_head) < 0)
|
||||||
ifconf.ifc_req = 0;
|
goto no_ifaddrs;
|
||||||
do {
|
for (ifa = ifa_head; ifa; ifa = ifa->ifa_next) {
|
||||||
buflen *= 2;
|
if (!ifa->ifa_flags & IFF_UP)
|
||||||
ifconf.ifc_len = buflen;
|
continue;
|
||||||
ifconf.ifc_req = realloc (ifconf.ifc_req, ifconf.ifc_len);
|
if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
|
||||||
if ((ret = ioctl (sock, SIOCGIFCONF, &ifconf)) < 0) {
|
continue;
|
||||||
Sys_MaskPrintf (SYS_NET, "ioctl: %s", strerror (errno));
|
strncpy (ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ);
|
||||||
break;
|
ifreq.ifr_name[IFNAMSIZ - 1] = 0;
|
||||||
}
|
ioctl (sock, SIOCGIFINDEX, (char*) &ifreq);
|
||||||
} while (ifconf.ifc_len == buflen);
|
if (ifreq.ifr_ifindex > num_ifaces)
|
||||||
|
num_ifaces = ifreq.ifr_ifindex;
|
||||||
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 (default_iface)
|
ifaces = malloc (num_ifaces * sizeof (uint32_t));
|
||||||
myAddr = *default_iface;
|
Sys_MaskPrintf (SYS_NET, "%d interfaces\n", num_ifaces);
|
||||||
free (ifconf.ifc_req);
|
for (ifa = ifa_head; ifa; ifa = ifa->ifa_next) {
|
||||||
return ret;
|
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
|
int
|
||||||
|
@ -187,7 +200,7 @@ UDP_Init (void)
|
||||||
gethostname (buff, MAXHOSTNAMELEN);
|
gethostname (buff, MAXHOSTNAMELEN);
|
||||||
local = gethostbyname (buff);
|
local = gethostbyname (buff);
|
||||||
if (local)
|
if (local)
|
||||||
myAddr = *(int *) local->h_addr_list[0];
|
myAddr = *(uint32_t *) local->h_addr_list[0];
|
||||||
else
|
else
|
||||||
myAddr = 0;
|
myAddr = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue