=?UTF-8?Q?Andr=C3=A9=20Hentschel=20?=: iphlpapi: Use the new version of the IP_ADAPTER_UNICAST_ADDRESS structure.
Alexandre Julliard
julliard at winehq.org
Thu Feb 2 15:49:26 CST 2017
Module: wine
Branch: master
Commit: 1bb9db43e1e07bc124975d659a102c0c2d7917ed
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1bb9db43e1e07bc124975d659a102c0c2d7917ed
Author: André Hentschel <nerv at 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 at dawncrow.de>
Signed-off-by: Alexandre Julliard <julliard at 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;
}
More information about the wine-cvs
mailing list