--- wine.old/configure.ac 2008-03-19 22:56:00.000000000 +0100 +++ wine/configure.ac 2008-03-19 22:56:07.000000000 +0100 @@ -1181,6 +1181,10 @@ WINE_WARNING([No sound system was found. Windows applications will be silent.]) fi + +dnl **** Check for getifaddrs **** +AC_CHECK_FUNC(getifaddrs, [AC_DEFINE(HAVE_GETIFADDRS,1,[Define if you have the getifaddrs() function])]) + dnl **** Check for gcc specific options **** AC_SUBST(EXTRACFLAGS,"") diff -u -r wine.old/dlls/ws2_32/Makefile.in wine/dlls/ws2_32/Makefile.in --- wine.old/dlls/ws2_32/Makefile.in 2008-03-19 22:36:33.000000000 +0100 +++ wine/dlls/ws2_32/Makefile.in 2008-03-19 22:57:02.000000000 +0100 @@ -5,7 +5,7 @@ VPATH = @srcdir@ MODULE = ws2_32.dll IMPORTLIB = ws2_32 -IMPORTS = iphlpapi kernel32 ntdll +IMPORTS = advapi32 iphlpapi kernel32 ntdll DELAYIMPORTS = user32 EXTRALIBS = @LIBPOLL@ diff -u -r wine.old/dlls/ws2_32/socket.c wine/dlls/ws2_32/socket.c --- wine.old/dlls/ws2_32/socket.c 2008-03-19 22:36:33.000000000 +0100 +++ wine/dlls/ws2_32/socket.c 2008-03-19 22:57:02.000000000 +0100 @@ -44,6 +44,10 @@ # include #endif +#ifdef HAVE_GETIFADDRS +#include +#endif + #if defined(__EMX__) # include #endif @@ -142,6 +146,8 @@ # include "wsnwlink.h" #endif +#include "winreg.h" +#include "wtypes.h" #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) # define sipx_network sipx_addr.x_net @@ -1387,6 +1393,43 @@ return INVALID_SOCKET; } +#ifdef HAVE_GETIFADDRS +void FixBindAddress (union generic_unix_sockaddr *uaddr) +{ + struct ifaddrs *ifa, *ifa_curr; + + if (getifaddrs(&ifa) < 0) + { + TRACE("No NICs Found!"); + return; + } + + for (ifa_curr = ifa; ifa_curr != NULL; ifa_curr = ifa_curr->ifa_next) + { + if (!ifa_curr->ifa_addr || !(ifa_curr->ifa_flags & IFF_RUNNING)) + continue; + + // IPv4 + if (uaddr->addr.sa_family == AF_INET && ifa_curr->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in *in_b = (struct sockaddr_in *) uaddr; + struct sockaddr_in *in_i = (struct sockaddr_in *) ifa_curr->ifa_addr; + + TRACE("ifa_name: %s\n", ifa_curr->ifa_name); + + if (in_b->sin_addr.s_addr == in_i->sin_addr.s_addr) + { + FIXME("Tried to bind to local address %s\n", inet_ntoa(in_b->sin_addr)); + in_b->sin_addr.s_addr = INADDR_ANY; + break; + } + } + } + + freeifaddrs(ifa); +} +#endif + /*********************************************************************** * bind (WS2_32.2) */ @@ -1413,6 +1456,27 @@ } else { +#ifdef HAVE_GETIFADDRS + HKEY net_hkey; + if (RegOpenKeyA(HKEY_CURRENT_USER,"Software\\Wine\\Network", &net_hkey) == ERROR_SUCCESS) + { + DWORD hackval_type; + char hackval_buf[15]; + DWORD hackval_buf_size = 15; + + if ( + RegQueryValueExA(net_hkey, "UseBindAddressHack", NULL, &hackval_type, hackval_buf, &hackval_buf_size) == ERROR_SUCCESS && + hackval_type == REG_SZ && + hackval_buf_size > 0 && + hackval_buf[hackval_buf_size-1] == '\0' && + !strcmp(hackval_buf, "enabled") + ) + FixBindAddress(&uaddr); + + RegCloseKey(net_hkey); + } +#endif + #ifdef IPV6_V6ONLY const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) &uaddr; if (name->sa_family == WS_AF_INET6 &&