Module: wine Branch: master Commit: 1bb9db43e1e07bc124975d659a102c0c2d7917ed URL: http://source.winehq.org/git/wine.git/?a=commit;h=1bb9db43e1e07bc124975d659a...
Author: André Hentschel nerv@dawncrow.de Date: Wed Feb 1 22:58:56 2017 +0100
iphlpapi: Use the new version of the IP_ADAPTER_UNICAST_ADDRESS structure.
Signed-off-by: André Hentschel nerv@dawncrow.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/iphlpapi/iphlpapi_main.c | 46 ++++++++++++++++++++++++++---------------- dlls/iphlpapi/tests/iphlpapi.c | 10 +++++++++ 2 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 54f7a37..1daf54d 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -868,6 +868,27 @@ static ULONG count_v4_gateways(DWORD index, PMIB_IPFORWARDTABLE routeTable) return num_gateways; }
+static DWORD mask_v4_to_prefix(DWORD m) +{ +#ifdef HAVE___BUILTIN_POPCOUNT + return __builtin_popcount(m); +#else + m -= m >> 1 & 0x55555555; + m = (m & 0x33333333) + (m >> 2 & 0x33333333); + return ((m + (m >> 4)) & 0x0f0f0f0f) * 0x01010101 >> 24; +#endif +} + +static DWORD mask_v6_to_prefix(SOCKET_ADDRESS *m) +{ + const IN6_ADDR *mask = &((struct WS_sockaddr_in6 *)m->lpSockaddr)->sin6_addr; + DWORD ret = 0, i; + + for (i = 0; i < 8; i++) + ret += mask_v4_to_prefix(mask->u.Word[i]); + return ret; +} + static PMIB_IPFORWARDROW findIPv4Gateway(DWORD index, PMIB_IPFORWARDTABLE routeTable) { @@ -1065,6 +1086,8 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index debugstr_ipv4(&sa->sin_addr.S_un.S_addr, addr_buf)); fill_unicast_addr_data(aa, ua);
+ ua->OnLinkPrefixLength = mask_v4_to_prefix(v4masks[i]); + ptr += ua->u.s.Length + ua->Address.iSockaddrLength; if (i < num_v4addrs - 1) { @@ -1103,6 +1126,8 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index debugstr_ipv6(sa, addr_buf)); fill_unicast_addr_data(aa, ua);
+ ua->OnLinkPrefixLength = mask_v6_to_prefix(&v6masks[i]); + ptr += ua->u.s.Length + ua->Address.iSockaddrLength; if (i < num_v6addrs - 1) { @@ -1132,12 +1157,8 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index sa->sin_addr.S_un.S_addr = v4addrs[i] & v4masks[i]; sa->sin_port = 0;
- prefix->PrefixLength = 0; - for (j = 0; j < sizeof(*v4masks) * 8; j++) - { - if (v4masks[i] & 1 << j) prefix->PrefixLength++; - else break; - } + prefix->PrefixLength = mask_v4_to_prefix(v4masks[i]); + TRACE("IPv4 network: %s/%u\n", debugstr_ipv4((const in_addr_t *)&sa->sin_addr.S_un.S_addr, addr_buf), prefix->PrefixLength); @@ -1168,8 +1189,6 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index char addr_buf[46]; struct WS_sockaddr_in6 *sa; const IN6_ADDR *addr, *mask; - BOOL done = FALSE; - ULONG k;
prefix->u.s.Length = sizeof(*prefix); prefix->u.s.Flags = 0; @@ -1186,15 +1205,8 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index for (j = 0; j < 8; j++) sa->sin6_addr.u.Word[j] = addr->u.Word[j] & mask->u.Word[j]; sa->sin6_scope_id = 0;
- prefix->PrefixLength = 0; - for (k = 0; k < 8 && !done; k++) - { - for (j = 0; j < sizeof(WORD) * 8 && !done; j++) - { - if (mask->u.Word[k] & 1 << j) prefix->PrefixLength++; - else done = TRUE; - } - } + prefix->PrefixLength = mask_v6_to_prefix(&v6masks[i]); + TRACE("IPv6 network: %s/%u\n", debugstr_ipv6(sa, addr_buf), prefix->PrefixLength);
ptr += prefix->u.s.Length + prefix->Address.iSockaddrLength; diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 64d03cf..e4a5864 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -1409,6 +1409,9 @@ static void test_GetAdaptersAddresses(void) ua = aa->FirstUnicastAddress; while (ua) { + ok(S(U(*ua)).Length == sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH) || + S(U(*ua)).Length == sizeof(IP_ADAPTER_UNICAST_ADDRESS_XP), + "Unknown structure size of %u bytes\n", S(U(*ua)).Length); ok(ua->PrefixOrigin != IpPrefixOriginOther, "bad address config value %d\n", ua->PrefixOrigin); ok(ua->SuffixOrigin != IpSuffixOriginOther, @@ -1435,6 +1438,13 @@ static void test_GetAdaptersAddresses(void) trace("\tValidLifetime: %u seconds\n", ua->ValidLifetime); trace("\tPreferredLifetime: %u seconds\n", ua->PreferredLifetime); trace("\tLeaseLifetime: %u seconds\n", ua->LeaseLifetime); + if (S(U(*ua)).Length < sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH)) + { + trace("\n"); + ua = ua->Next; + continue; + } + trace("\tOnLinkPrefixLength: %u\n", ua->OnLinkPrefixLength); trace("\n"); ua = ua->Next; }