[PATCH v2 2/4] ws2_32/tests: Add tests for IPv4 control messages

Alex Henrie alexhenrie24 at gmail.com
Tue Sep 28 09:39:41 CDT 2021


IP_PKTINFO already had tests, but it doesn't hurt to add a few more.
IP_RECVTTL and IP_RECVTCLASS didn't have any tests.

Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
---
v2:
- Use %zu and %u instead of casting
- Change comments to clarify that versions of Windows up to and
  including Win10 v1607 have different behavior than later versions
  (the latest Windows versions are more consistent with Linux and OSX)
---
 dlls/ws2_32/tests/sock.c | 120 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 260b07d1665..87d1ec721a5 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -1984,6 +1984,125 @@ static void test_ip_pktinfo(void)
     CloseHandle(ov.hEvent);
 }
 
+static void test_ipv4_cmsg(void)
+{
+    static const DWORD off = 0;
+    static const DWORD on = 1;
+    SOCKADDR_IN localhost = {0};
+    SOCKET client, server;
+    char payload[] = "HELLO";
+    char control[100];
+    WSABUF payload_buf = {sizeof(payload), payload};
+    WSAMSG msg = {NULL, 0, &payload_buf, 1, {sizeof(control), control}, 0};
+    WSACMSGHDR *header = (WSACMSGHDR *)control;
+    LPFN_WSARECVMSG pWSARecvMsg;
+    INT *int_data = (INT *)WSA_CMSG_DATA(header);
+    IN_PKTINFO *pkt_info = (IN_PKTINFO *)WSA_CMSG_DATA(header);
+    DWORD count, state;
+    int rc;
+
+    localhost.sin_family = AF_INET;
+    localhost.sin_port = htons(SERVERPORT);
+    inet_pton(AF_INET, "127.0.0.1", &localhost.sin_addr);
+
+    client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    ok(client != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
+    server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
+
+    rc = bind(server, (SOCKADDR *)&localhost, sizeof(localhost));
+    ok(rc != SOCKET_ERROR, "bind failed, error %u\n", WSAGetLastError());
+    rc = connect(client, (SOCKADDR *)&localhost, sizeof(localhost));
+    ok(rc != SOCKET_ERROR, "connect failed, error %u\n", WSAGetLastError());
+
+    rc = WSAIoctl(server, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
+                  &pWSARecvMsg, sizeof(pWSARecvMsg), &count, NULL, NULL);
+    ok(!rc, "failed to get WSARecvMsg, error %u\n", WSAGetLastError());
+
+    memset(control, 0, sizeof(control));
+    msg.Control.len = sizeof(control);
+    rc = setsockopt(server, IPPROTO_IP, IP_RECVTTL, (const char *)&on, sizeof(on));
+todo_wine
+    ok(!rc, "failed to set IP_RECVTTL, error %u\n", WSAGetLastError());
+    state = 0;
+    count = sizeof(state);
+    rc = getsockopt(server, IPPROTO_IP, IP_RECVTTL, (char *)&state, (INT *)&count);
+todo_wine
+    ok(!rc, "failed to get IP_RECVTTL, error %u\n", WSAGetLastError());
+todo_wine
+    ok(state == 1, "expected 1, got %u\n", state);
+    rc = send(client, payload, sizeof(payload), 0);
+    ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
+    rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
+    ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
+    ok(count == sizeof(payload), "expected length %zu, got %u\n", sizeof(payload), count);
+    ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
+todo_wine
+    ok(header->cmsg_type == IP_TTL || broken(header->cmsg_type == IP_HOPLIMIT) /* <= win10 v1607 */,
+       "expected IP_TTL, got %i\n", header->cmsg_type);
+todo_wine
+    ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
+       "expected length %zu, got %zu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
+todo_wine
+    ok(*int_data >= 32, "expected at least 32, got %i\n", *int_data);
+    setsockopt(server, IPPROTO_IP, IP_RECVTTL, (const char *)&off, sizeof(off));
+    ok(!rc, "failed to clear IP_RECVTTL, error %u\n", WSAGetLastError());
+
+    memset(control, 0, sizeof(control));
+    msg.Control.len = sizeof(control);
+    rc = setsockopt(server, IPPROTO_IP, IP_PKTINFO, (const char *)&on, sizeof(on));
+    ok(!rc, "failed to set IP_PKTINFO, error %u\n", WSAGetLastError());
+    state = 0;
+    count = sizeof(state);
+    rc = getsockopt(server, IPPROTO_IP, IP_PKTINFO, (char *)&state, (INT *)&count);
+    ok(!rc, "failed to get IP_PKTINFO, error %u\n", WSAGetLastError());
+    ok(state == 1, "expected 1, got %u\n", state);
+    rc = send(client, payload, sizeof(payload), 0);
+    ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
+    rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
+    ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
+    ok(count == sizeof(payload), "expected length %zu, got %u\n", sizeof(payload), count);
+    ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
+    ok(header->cmsg_type == IP_PKTINFO, "expected IP_PKTINFO, got %i\n", header->cmsg_type);
+    ok(header->cmsg_len == sizeof(*header) + sizeof(IN_PKTINFO),
+       "expected length %zu, got %zu\n", sizeof(*header) + sizeof(IN_PKTINFO), header->cmsg_len);
+    ok(!memcmp(&pkt_info->ipi_addr, &localhost.sin_addr, sizeof(IN_ADDR)), "expected 127.0.0.1\n");
+    rc = setsockopt(server, IPPROTO_IP, IP_PKTINFO, (const char *)&off, sizeof(off));
+    ok(!rc, "failed to clear IP_PKTINFO, error %u\n", WSAGetLastError());
+
+    memset(control, 0, sizeof(control));
+    msg.Control.len = sizeof(control);
+    rc = setsockopt(server, IPPROTO_IP, IP_RECVTCLASS, (const char *)&on, sizeof(on));
+todo_wine
+    ok(!rc, "failed to set IP_RECVTCLASS, error %u\n", WSAGetLastError());
+    state = 0;
+    count = sizeof(state);
+    rc = getsockopt(server, IPPROTO_IP, IP_RECVTCLASS, (char *)&state, (INT *)&count);
+todo_wine
+    ok(!rc, "failed to get IP_RECVTCLASS, error %u\n", WSAGetLastError());
+todo_wine
+    ok(state == 1, "expected 1, got %u\n", state);
+    rc = send(client, payload, sizeof(payload), 0);
+    ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError());
+    rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
+    ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError());
+    ok(count == sizeof(payload), "expected length %zu, got %u\n", sizeof(payload), count);
+    ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level);
+todo_wine
+    ok(header->cmsg_type == IP_TOS || broken(header->cmsg_type == IP_TCLASS) /* <= win10 v1607 */,
+       "expected IP_TOS, got %i\n", header->cmsg_type);
+todo_wine
+    ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
+       "expected length %zu, got %zu\n", sizeof(*header) + sizeof(INT), header->cmsg_len);
+    ok(*int_data == 0, "expected 0, got %i\n", *int_data);
+    rc = setsockopt(server, IPPROTO_IP, IP_RECVTCLASS, (const char *)&off, sizeof(off));
+todo_wine
+    ok(!rc, "failed to clear IP_RECVTCLASS, error %u\n", WSAGetLastError());
+
+    closesocket(server);
+    closesocket(client);
+}
+
 static void test_ipv6_cmsg(void)
 {
     static const DWORD off = 0;
@@ -11767,6 +11886,7 @@ START_TEST( sock )
     test_set_getsockopt();
     test_so_reuseaddr();
     test_ip_pktinfo();
+    test_ipv4_cmsg();
     test_ipv6_cmsg();
     test_extendedSocketOptions();
     test_so_debug();
-- 
2.33.0




More information about the wine-devel mailing list