aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2019-11-26 19:13:12 +0200
committerEli Zaretskii2019-11-26 19:13:12 +0200
commit094eb04ce5d8c1ccef78113c8cc6791d1d3b6bf8 (patch)
treec9eaab424dacf2b29f3942541bc800c686d04e8d
parent52eca2d3bdef293e9f5d64aa2b9ca36f1e00e817 (diff)
downloademacs-094eb04ce5d8c1ccef78113c8cc6791d1d3b6bf8.tar.gz
emacs-094eb04ce5d8c1ccef78113c8cc6791d1d3b6bf8.zip
Fix MS-Windows build with mingw.org's MinGW
mingw.org's MinGW by default targets Windows 9X, so _WIN32_WINNT is set to a value that bypasses declarations in system headers we need to compile network_interface_list. Also, the code needed a workaround for Windows XP, where some functionality is missing from the GetAdaptersAddresses API. * src/w32.c (_WIN32_WINNT): Define to 0x0501, if the value is lower, temporarily while processing iphlpapi.h. (address_prefix_match): New helper function. (network_interface_list): Work around the fact that the OnLinkPrefixLength member of IP_ADAPTER_UNICAST_ADDRESS is not available when _WIN32_WINNT < 0x0600. On Windows XP use special code that calls address_prefix_match to compute the network prefix length.
-rw-r--r--src/w32.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/src/w32.c b/src/w32.c
index 76c226892a4..cb82d51fb92 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -242,8 +242,22 @@ typedef struct _REPARSE_DATA_BUFFER {
242#undef recvfrom 242#undef recvfrom
243#undef sendto 243#undef sendto
244 244
245/* We need at least XP level for GetAdaptersAddresses stuff. */
246#if _WIN32_WINNT < 0x0501
247# undef ORIG_WIN32_WINNT
248# define ORIG_WIN32_WINNT _WIN32_WINNT
249# undef _WIN32_WINNT
250# define _WIN32_WINNT 0x0501
251#endif
252
245#include <iphlpapi.h> /* should be after winsock2.h */ 253#include <iphlpapi.h> /* should be after winsock2.h */
246 254
255#ifdef ORIG_WIN32_WINNT
256# undef _WIN32_WINNT
257# define _WIN32_WINNT ORIG_WIN32_WINNT
258# undef ORIG_WIN32_WINNT
259#endif
260
247#include <wincrypt.h> 261#include <wincrypt.h>
248 262
249#include <c-strcase.h> 263#include <c-strcase.h>
@@ -9432,6 +9446,40 @@ network_interface_get_info (Lisp_Object ifname)
9432 return res; 9446 return res;
9433} 9447}
9434 9448
9449static bool
9450address_prefix_match (int family, struct sockaddr *address,
9451 struct sockaddr *prefix_address, ULONG prefix_len)
9452{
9453 UINT8 *address_data;
9454 UINT8 *prefix_address_data;
9455 int i;
9456
9457 if (family == AF_INET6)
9458 {
9459 address_data = (UINT8 *) &(((struct sockaddr_in6 *) address)->sin6_addr);
9460 prefix_address_data =
9461 (UINT8 *) &(((struct sockaddr_in6 *) prefix_address)->sin6_addr);
9462 }
9463 else
9464 {
9465 address_data = (UINT8 *) &(((struct sockaddr_in *) address)->sin_addr);
9466 prefix_address_data =
9467 (UINT8 *) &(((struct sockaddr_in *) prefix_address)->sin_addr);
9468 }
9469
9470 for (i = 0; i < prefix_len >> 3; i++)
9471 {
9472 if (address_data[i] != prefix_address_data[i])
9473 return false;
9474 }
9475
9476 if (prefix_len % 8)
9477 return (prefix_address_data[i] ==
9478 (address_data[i] & (0xff << (8 - prefix_len % 8))));
9479
9480 return true;
9481}
9482
9435Lisp_Object 9483Lisp_Object
9436network_interface_list (bool full, unsigned short match) 9484network_interface_list (bool full, unsigned short match)
9437{ 9485{
@@ -9586,7 +9634,37 @@ network_interface_list (bool full, unsigned short match)
9586 byte order, so convert from host to network order 9634 byte order, so convert from host to network order
9587 when generating the netmask. */ 9635 when generating the netmask. */
9588 int i; 9636 int i;
9589 ULONG numbits = address->OnLinkPrefixLength; 9637 ULONG numbits;
9638 if (w32_major_version >= 6) /* Vista or later */
9639 {
9640#if _WIN32_WINNT >= 0x0600
9641 numbits = address->OnLinkPrefixLength;
9642#else
9643 /* Kludge alert! OnLinkPrefixLength is only defined
9644 when compiling for Vista and later. */
9645 numbits = *(UINT8 *) (address->LeaseLifetime
9646 + sizeof (address->LeaseLifetime));
9647#endif
9648 }
9649 else /* Windows XP */
9650 {
9651 IP_ADAPTER_PREFIX *prefix = adapter->FirstPrefix;
9652 numbits = 0;
9653 for ( ; prefix; prefix = prefix->Next)
9654 {
9655 /* We want the longest matching prefix. */
9656 if (prefix->Address.lpSockaddr->sa_family
9657 != ifa_addr->sa_family
9658 || prefix->PrefixLength <= numbits)
9659 continue;
9660 if (address_prefix_match (ifa_addr->sa_family, ifa_addr,
9661 prefix->Address.lpSockaddr,
9662 prefix->PrefixLength))
9663 numbits = prefix->PrefixLength;
9664 }
9665 if (!numbits)
9666 numbits = (ifa_addr->sa_family == AF_INET6) ? 128 : 32;
9667 }
9590 for (i = 0; i < addr_len; i++) 9668 for (i = 0; i < addr_len; i++)
9591 { 9669 {
9592 if (numbits >= 32) 9670 if (numbits >= 32)