[PATCH 2/3] iphlpapi/tests: Add tests for GetBestRoute2.
Jinoh Kang
wine at gitlab.winehq.org
Fri Jun 17 09:00:14 CDT 2022
From: Jinoh Kang <jinoh.kang.kr at gmail.com>
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
dlls/iphlpapi/tests/iphlpapi.c | 224 +++++++++++++++++++++++++++++++++
1 file changed, 224 insertions(+)
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c
index 29256eb2774..f2148d29b52 100644
--- a/dlls/iphlpapi/tests/iphlpapi.c
+++ b/dlls/iphlpapi/tests/iphlpapi.c
@@ -2391,6 +2391,229 @@ static void test_GetUnicastIpAddressTable(void)
FreeMibTable( table );
}
+static void test_GetBestRoute2(void)
+{
+ DWORD apiReturn;
+ SOCKADDR_INET source, destination, bestaddress, bestaddress_memory;
+ MIB_IPFORWARD_ROW2 bestroute, bestroute_memory;
+ int validmemflags = 0;
+ static const MIB_IPFORWARD_ROW2 route_zero;
+ static const NET_LUID zero_luid, ones_luid = { -1 };
+ static const SOCKADDR_INET unspecaddr;
+ static const SOCKADDR invalidaddr = { -1 };
+ static const SOCKADDR_IN in4any = { AF_INET };
+ static const SOCKADDR_IN in4loopback = { AF_INET, 0, {{{ 127, 0, 0, 1 }}} };
+ static const SOCKADDR_IN in4broadcast = { AF_INET, 0, {{{ 255, 255, 255, 255 }}} };
+ static const SOCKADDR_IN6 in6any = { AF_INET6 };
+ static const SOCKADDR_IN6 in6loopback = { AF_INET6, 0, 0, {{{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ }}} };
+ static const SOCKADDR_IN6 in6broadcast = { AF_INET6, 0, 0, {{{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ }}} };
+ struct sockaddr_ptrlen
+ {
+ const struct sockaddr *ptr;
+ size_t len;
+ };
+ static const struct getbestroute_test
+ {
+ int line;
+ const NET_LUID *luid;
+ NET_IFINDEX ifindex;
+ struct sockaddr_ptrlen source;
+ struct sockaddr_ptrlen destination;
+ ULONG options;
+ DWORD result;
+ BOOL todo;
+ int memload;
+ int memstore;
+ } getbestroute_tests[] = {
+#define SA_PL(x) { ((struct sockaddr *)&(x)), sizeof(x) }
+ { __LINE__, &zero_luid, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, &zero_luid, -1, { NULL }, SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, &ones_luid, 0, { NULL }, SA_PL(in4loopback), 0, ERROR_NOT_FOUND },
+ { __LINE__, NULL, -1, { NULL }, SA_PL(in4loopback), 0, ERROR_FILE_NOT_FOUND },
+ { __LINE__, &zero_luid, 0, SA_PL(unspecaddr), SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, &ones_luid, 0, SA_PL(unspecaddr), SA_PL(in4loopback), 0, ERROR_NOT_FOUND },
+ { __LINE__, NULL, 0, SA_PL(unspecaddr), SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, NULL, 0, SA_PL(in4any), SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, NULL, 0, SA_PL(in4loopback), SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, NULL, 0, SA_PL(in4broadcast), SA_PL(in4loopback), 0, ERROR_INVALID_PARAMETER, TRUE },
+ { __LINE__, NULL, 0, SA_PL(in6any), SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, NULL, 0, SA_PL(in6loopback), SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, NULL, 0, SA_PL(in6broadcast), SA_PL(in4loopback), 0, NO_ERROR },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0, 0xc7 },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc0 },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc2 },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc4 },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc6 },
+#if 0 /* not reliable (fails spuriously) on Wine */
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc1 },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc3 },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc5 },
+ { __LINE__, NULL, 0, { NULL }, SA_PL(in4loopback), 0, NO_ERROR, FALSE, 0xc7 },
+#endif
+#undef SA_PL
+ };
+ UINT i;
+
+ memset( &destination, 0, sizeof(destination) );
+ destination.Ipv4.sin_family = AF_INET;
+ destination.Ipv4.sin_addr.S_un.S_addr = htonl( INADDR_ANY );
+ apiReturn = GetBestRoute2( NULL, 0, NULL, &destination, 0, &bestroute, &bestaddress );
+ trace( "GetBestRoute2(NULL, 0, NULL, [...], 0, [...], [...]) = %lu\n", apiReturn );
+ if (apiReturn == ERROR_NOT_SUPPORTED)
+ {
+ skip("GetBestRoute2 not supported\n");
+ return;
+ }
+
+ apiReturn = GetBestRoute2( NULL, 0, NULL, NULL, 0, NULL, NULL );
+ ok( apiReturn == ERROR_INVALID_PARAMETER,
+ "GetBestRoute2(NULL, 0, NULL, NULL, 0, NULL, NULL) returned %lu, expected %d\n",
+ apiReturn, ERROR_INVALID_PARAMETER );
+
+ apiReturn = GetBestRoute2( NULL, 0, NULL, NULL, 0, &bestroute, NULL );
+ ok( apiReturn == ERROR_INVALID_PARAMETER,
+ "GetBestRoute2(NULL, 0, NULL, NULL, 0, %p, NULL) returned %lu, expected %d\n",
+ &bestroute, apiReturn, ERROR_INVALID_PARAMETER );
+
+ apiReturn = GetBestRoute2( NULL, 0, NULL, NULL, 0, NULL, &bestaddress );
+ memcpy( &bestaddress, &invalidaddr, sizeof(invalidaddr) );
+ ok( apiReturn == ERROR_INVALID_PARAMETER,
+ "GetBestRoute2(NULL, 0, NULL, NULL, 0, NULL, %p) returned %lu, expected %d\n",
+ &bestaddress, apiReturn, ERROR_INVALID_PARAMETER );
+ ok( memcmp(&bestaddress, &invalidaddr, sizeof(invalidaddr)) == 0, "bestaddress(.si_family = %u) has changed\n", bestaddress.si_family );
+
+ apiReturn = GetBestRoute2( NULL, 0, NULL, NULL, 0, &bestroute, &bestaddress );
+ memcpy( &bestaddress, &invalidaddr, sizeof(invalidaddr) );
+ ok( apiReturn == ERROR_INVALID_PARAMETER,
+ "GetBestRoute2(NULL, 0, NULL, NULL, 0, %p, %p) returned %lu, expected %d\n",
+ &bestroute, &bestaddress, apiReturn, ERROR_INVALID_PARAMETER );
+ ok( memcmp(&bestaddress, &invalidaddr, sizeof(invalidaddr)) == 0, "bestaddress(.si_family = %u) has changed\n", bestaddress.si_family );
+
+ memset( &destination, 0, sizeof(destination) );
+ destination.Ipv4.sin_family = AF_INET;
+ destination.Ipv4.sin_addr.S_un.S_addr = htonl( INADDR_LOOPBACK );
+ memcpy( &bestaddress, &invalidaddr, sizeof(invalidaddr) );
+ apiReturn = GetBestRoute2( NULL, 0, NULL, &destination, 0, &bestroute, NULL );
+ ok( apiReturn == ERROR_INVALID_PARAMETER,
+ "GetBestRoute2(NULL, 0, NULL, [127.0.0.1], 0, %p, NULL) returned %lu, expected %d\n",
+ &bestroute, apiReturn, ERROR_INVALID_PARAMETER );
+ ok( memcmp(&bestaddress, &invalidaddr, sizeof(invalidaddr)) == 0, "bestaddress(.si_family = %u) has changed\n", bestaddress.si_family );
+
+ memset( &destination, 0, sizeof(destination) );
+ destination.Ipv4.sin_family = AF_INET;
+ destination.Ipv4.sin_addr.S_un.S_addr = htonl( INADDR_LOOPBACK );
+ memcpy( &bestaddress, &invalidaddr, sizeof(invalidaddr) );
+ apiReturn = GetBestRoute2( NULL, 0, NULL, &destination, 0, NULL, &bestaddress );
+ ok( apiReturn == ERROR_INVALID_PARAMETER,
+ "GetBestRoute2(NULL, 0, NULL, [127.0.0.1], 0, NULL, %p) returned %lu, expected %d\n",
+ &bestaddress, apiReturn, ERROR_INVALID_PARAMETER );
+ ok( memcmp(&bestaddress, &invalidaddr, sizeof(invalidaddr)) == 0, "bestaddress(.si_family = %u) has changed\n", bestaddress.si_family );
+
+ memset( &destination, 0, sizeof(destination) );
+ memcpy( &bestaddress, &invalidaddr, sizeof(invalidaddr) );
+ apiReturn = GetBestRoute2( NULL, 0, NULL, &destination, 0, NULL, &bestaddress );
+ ok( apiReturn == ERROR_INVALID_PARAMETER,
+ "GetBestRoute2(NULL, 0, NULL, <AF_UNSPEC>, 0, NULL, %p) returned %lu, expected %d\n",
+ &bestaddress, apiReturn, ERROR_INVALID_PARAMETER );
+ ok( memcmp(&bestaddress, &invalidaddr, sizeof(invalidaddr)) == 0, "bestaddress(.si_family = %u) has changed\n", bestaddress.si_family );
+
+ for (i = 0; i < ARRAY_SIZE(getbestroute_tests); i++)
+ {
+ const struct getbestroute_test *item = &getbestroute_tests[i];
+ int validflags = item->memload & validmemflags;
+ NET_LUID luid;
+ NET_IFINDEX ifindex = 0;
+
+ winetest_push_context("Subtest #%u (decl at line %d)", i, item->line);
+
+ ok( (item->memload & ~validmemflags) == 0,
+ "current subtest may be incomplete due to previous test failure (memload = %d, validmemflags = %d)\n",
+ item->memload, validmemflags );
+
+ if (item->luid)
+ {
+ memcpy(&luid, item->luid, sizeof(luid));
+ validflags |= 1;
+ }
+ else if (validflags & 1)
+ {
+ memcpy(&luid, &bestroute_memory.InterfaceLuid, sizeof(luid));
+ }
+
+ if (item->ifindex)
+ {
+ ifindex = item->ifindex;
+ validflags |= 2;
+ }
+ else if (validflags & 2)
+ {
+ ifindex = bestroute_memory.InterfaceIndex;
+ }
+
+ if (item->source.len > sizeof(source)) abort(); /* prevent memory corruption */
+ if (item->source.ptr)
+ {
+ memset( &source, 0, sizeof(source) );
+ memcpy( &source, item->source.ptr, item->source.len );
+ validflags |= 4;
+ }
+ else if (validflags & 4)
+ {
+ memcpy( &source, &bestaddress_memory, sizeof(source) );
+ }
+
+ if (item->destination.len > sizeof(destination)) abort(); /* prevent memory corruption */
+ memset( &destination, 0, sizeof(destination) );
+ memcpy( &destination, item->destination.ptr, item->destination.len );
+
+ apiReturn = GetBestRoute2( (validflags & 1) ? &luid : NULL,
+ (validflags & 2) ? ifindex : 0,
+ (validflags & 4) ? &source : NULL,
+ &destination,
+ item->options,
+ &bestroute, &bestaddress );
+ todo_wine_if( item->todo )
+ ok( apiReturn == item->result,
+ "GetBestRoute2 returned %lu, expected %lu\n", apiReturn, item->result );
+ if (apiReturn == NO_ERROR)
+ {
+ ok( bestaddress.si_family == destination.si_family,
+ "bestaddress.si_family (%u) shall equal destination.si_family (%u)\n",
+ bestaddress.si_family, destination.si_family );
+
+ if (validflags & 0x40)
+ {
+ ok( memcmp( &bestroute_memory, &bestroute, sizeof(bestroute) ) == 0,
+ "returned bestroute does not match last cached value\n" );
+ }
+
+ if (validflags & 0x80)
+ {
+ ok( memcmp( &bestaddress_memory, &bestaddress, sizeof(bestaddress) ) == 0,
+ "returned bestaddress does not match last cached value\n" );
+ }
+
+ if (item->memstore)
+ {
+ memcpy( &bestroute_memory, &bestroute, sizeof(bestroute_memory) );
+ memcpy( &bestaddress_memory, &bestaddress, sizeof(bestaddress_memory) );
+ validmemflags = item->memstore;
+ }
+ }
+ else
+ {
+ ok( memcmp( &bestaddress, &unspecaddr, sizeof(bestaddress) ) == 0, "bestaddress shall be zeroed by GetBestRoute2\n" );
+ ok( memcmp( &bestroute, &route_zero, sizeof(bestroute) ) == 0, "bestroute shall be zeroed by GetBestRoute2\n" );
+ }
+
+ winetest_pop_context();
+ }
+}
+
static void test_ConvertLengthToIpv4Mask(void)
{
DWORD ret;
@@ -2703,6 +2926,7 @@ START_TEST(iphlpapi)
test_GetIfTable2Ex();
test_GetUnicastIpAddressEntry();
test_GetUnicastIpAddressTable();
+ test_GetBestRoute2();
test_ConvertLengthToIpv4Mask();
test_GetTcp6Table();
test_GetUdp6Table();
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/263
More information about the wine-devel
mailing list