1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         User mode part of the TcpIp.sys test suite
5  * PROGRAMMER:      Jérôme Gardou <jerome.gardou@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 #include <winsock2.h>
10 
11 #include "tcpip.h"
12 
13 static
14 DWORD
15 LoadTcpIpTestDriver(void)
16 {
17     DWORD Error;
18 
19     /* Start the special-purpose driver */
20     Error = KmtLoadAndOpenDriver(L"TcpIp", FALSE);
21     ok_eq_int(Error, ERROR_SUCCESS);
22     if (Error)
23         return Error;
24 
25     return ERROR_SUCCESS;
26 }
27 
28 static
29 void
30 UnloadTcpIpTestDriver(void)
31 {
32     /* Stop the driver. */
33     KmtCloseDriver();
34     KmtUnloadDriver();
35 }
36 
37 START_TEST(TcpIpTdi)
38 {
39     DWORD Error;
40 
41     Error = LoadTcpIpTestDriver();
42     ok_eq_int(Error, 0);
43     if (Error)
44         return;
45 
46     Error = KmtSendToDriver(IOCTL_TEST_TDI);
47     ok_eq_ulong(Error, ERROR_SUCCESS);
48 
49     UnloadTcpIpTestDriver();
50 }
51 
52 static
53 DWORD
54 WINAPI
55 AcceptProc(
56     _In_ LPVOID Parameter)
57 {
58     WORD WinsockVersion;
59     WSADATA WsaData;
60     int Error;
61     SOCKET ListenSocket, AcceptSocket;
62     struct sockaddr_in ListenAddress, AcceptAddress;
63     int AcceptAddressLength;
64     HANDLE ReadyToConnectEvent = (HANDLE)Parameter;
65 
66     /* Initialize winsock */
67     WinsockVersion = MAKEWORD(2, 0);
68     Error = WSAStartup(WinsockVersion, &WsaData);
69     ok_eq_int(Error, 0);
70 
71     ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
72     ok(ListenSocket != INVALID_SOCKET, "socket failed\n");
73 
74     ZeroMemory(&ListenAddress, sizeof(ListenAddress));
75     ListenAddress.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
76     ListenAddress.sin_port = htons(TEST_CONNECT_SERVER_PORT);
77     ListenAddress.sin_family = AF_INET;
78 
79     Error = bind(ListenSocket, (struct sockaddr*)&ListenAddress, sizeof(ListenAddress));
80     ok_eq_int(Error, 0);
81 
82     Error = listen(ListenSocket, 1);
83     ok_eq_int(Error, 0);
84 
85     SetEvent(ReadyToConnectEvent);
86 
87     AcceptAddressLength = sizeof(AcceptAddress);
88     AcceptSocket = accept(ListenSocket, (struct sockaddr*)&AcceptAddress, &AcceptAddressLength);
89     ok(AcceptSocket != INVALID_SOCKET, "accept failed\n");
90     ok_eq_long(AcceptAddressLength, sizeof(AcceptAddress));
91     ok_eq_hex(AcceptAddress.sin_addr.S_un.S_addr, inet_addr("127.0.0.1"));
92     ok_eq_hex(AcceptAddress.sin_port, htons(TEST_CONNECT_CLIENT_PORT));
93 
94     return 0;
95 }
96 
97 START_TEST(TcpIpConnect)
98 {
99     HANDLE AcceptThread;
100     HANDLE ReadyToConnectEvent;
101     DWORD Error;
102 
103     ReadyToConnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
104     ok(ReadyToConnectEvent != NULL, "CreateEvent failed\n");
105 
106     AcceptThread = CreateThread(NULL, 0, AcceptProc, (PVOID)ReadyToConnectEvent, 0, NULL);
107     ok(AcceptThread != NULL, "CreateThread failed\n");
108 
109     WaitForSingleObject(ReadyToConnectEvent, INFINITE);
110 
111     LoadTcpIpTestDriver();
112 
113     Error = KmtSendToDriver(IOCTL_TEST_CONNECT);
114     ok_eq_ulong(Error, ERROR_SUCCESS);
115 
116     Error = WaitForSingleObject(AcceptThread, 10 * 1000);
117     ok(Error == WAIT_OBJECT_0, "AcceptThread timed out\n");
118 
119     UnloadTcpIpTestDriver();
120 
121     WSACleanup();
122 }
123