1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Tests for TCP connections enumeration functions
5  * COPYRIGHT:   Copyright 2018 Pierre Schweitzer
6  */
7 
8 #include <apitest.h>
9 
10 #define WIN32_NO_STATUS
11 #include <iphlpapi.h>
12 #include <winsock2.h>
13 
14 static DWORD GetExtendedTcpTableWithAlloc(PVOID *TcpTable, BOOL Order, DWORD Family, TCP_TABLE_CLASS Class)
15 {
16     DWORD ret;
17     DWORD Size = 0;
18 
19     *TcpTable = NULL;
20 
21     ret = GetExtendedTcpTable(*TcpTable, &Size, Order, Family, Class, 0);
22     if (ret == ERROR_INSUFFICIENT_BUFFER)
23     {
24         *TcpTable = HeapAlloc(GetProcessHeap(), 0, Size);
25         if (*TcpTable == NULL)
26         {
27             return ERROR_OUTOFMEMORY;
28         }
29 
30         ret = GetExtendedTcpTable(*TcpTable, &Size, Order, Family, Class, 0);
31         if (ret != NO_ERROR)
32         {
33             HeapFree(GetProcessHeap(), 0, *TcpTable);
34             *TcpTable = NULL;
35         }
36     }
37 
38     return ret;
39 }
40 
41 START_TEST(GetExtendedTcpTable)
42 {
43     WSADATA wsaData;
44     SOCKET sock;
45     SOCKADDR_IN server;
46     PMIB_TCPTABLE TcpTable;
47     PMIB_TCPTABLE_OWNER_PID TcpTableOwner;
48     PMIB_TCPTABLE_OWNER_MODULE TcpTableOwnerMod;
49     DWORD i;
50     BOOLEAN Found;
51     FILETIME Creation;
52     LARGE_INTEGER CreationTime;
53     DWORD Pid = GetCurrentProcessId();
54 
55     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
56     {
57         skip("Failed to init WS2\n");
58         return;
59     }
60 
61     GetSystemTimeAsFileTime(&Creation);
62     CreationTime.LowPart = Creation.dwLowDateTime;
63     CreationTime.HighPart = Creation.dwHighDateTime;
64 
65     sock = socket(AF_INET, SOCK_STREAM, 0);
66     if (sock == INVALID_SOCKET)
67     {
68         skip("Cannot create socket\n");
69         goto quit;
70     }
71 
72     ZeroMemory(&server, sizeof(SOCKADDR_IN));
73     server.sin_family = AF_INET;
74     server.sin_addr.s_addr = htonl(INADDR_ANY);
75     server.sin_port = htons(9876);
76 
77     if (bind(sock, (SOCKADDR*)&server, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
78     {
79         skip("Cannot bind socket\n");
80         goto quit2;
81     }
82 
83     if (listen(sock, SOMAXCONN) == SOCKET_ERROR)
84     {
85         skip("Cannot listen on socket\n");
86         goto quit2;
87     }
88 
89     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTable, TRUE, AF_INET, TCP_TABLE_BASIC_ALL) == ERROR_SUCCESS)
90     {
91         ok(TcpTable->dwNumEntries > 0, "No TCP connections?!\n");
92 
93         Found = FALSE;
94         for (i = 0; i < TcpTable->dwNumEntries; ++i)
95         {
96             if (TcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN &&
97                 TcpTable->table[i].dwLocalAddr == 0 &&
98                 TcpTable->table[i].dwLocalPort == htons(9876) &&
99                 TcpTable->table[i].dwRemoteAddr == 0)
100             {
101                 Found = TRUE;
102                 break;
103             }
104         }
105         ok(Found, "Our socket wasn't found!\n");
106 
107         HeapFree(GetProcessHeap(), 0, TcpTable);
108     }
109     else
110     {
111         skip("GetExtendedTcpTableWithAlloc failure\n");
112     }
113 
114     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTable, TRUE, AF_INET, TCP_TABLE_BASIC_CONNECTIONS) == ERROR_SUCCESS)
115     {
116         Found = FALSE;
117         for (i = 0; i < TcpTable->dwNumEntries; ++i)
118         {
119             if (TcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN &&
120                 TcpTable->table[i].dwLocalAddr == 0 &&
121                 TcpTable->table[i].dwLocalPort == htons(9876) &&
122                 TcpTable->table[i].dwRemoteAddr == 0)
123             {
124                 Found = TRUE;
125                 break;
126             }
127         }
128         ok(Found == FALSE, "Our socket was found!\n");
129 
130         HeapFree(GetProcessHeap(), 0, TcpTable);
131     }
132     else
133     {
134         skip("GetExtendedTcpTableWithAlloc failure\n");
135     }
136 
137     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTable, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER) == ERROR_SUCCESS)
138     {
139         ok(TcpTable->dwNumEntries > 0, "No TCP connections?!\n");
140 
141         Found = FALSE;
142         for (i = 0; i < TcpTable->dwNumEntries; ++i)
143         {
144             if (TcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN &&
145                 TcpTable->table[i].dwLocalAddr == 0 &&
146                 TcpTable->table[i].dwLocalPort == htons(9876) &&
147                 TcpTable->table[i].dwRemoteAddr == 0)
148             {
149                 Found = TRUE;
150                 break;
151             }
152         }
153         ok(Found, "Our socket wasn't found!\n");
154 
155         HeapFree(GetProcessHeap(), 0, TcpTable);
156     }
157     else
158     {
159         skip("GetExtendedTcpTableWithAlloc failure\n");
160     }
161 
162     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTableOwner, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL) == ERROR_SUCCESS)
163     {
164         ok(TcpTableOwner->dwNumEntries > 0, "No TCP connections?!\n");
165 
166         Found = FALSE;
167         for (i = 0; i < TcpTableOwner->dwNumEntries; ++i)
168         {
169             if (TcpTableOwner->table[i].dwState == MIB_TCP_STATE_LISTEN &&
170                 TcpTableOwner->table[i].dwLocalAddr == 0 &&
171                 TcpTableOwner->table[i].dwLocalPort == htons(9876) &&
172                 TcpTableOwner->table[i].dwRemoteAddr == 0)
173             {
174                 Found = TRUE;
175                 break;
176             }
177         }
178 
179         if (!Found)
180         {
181             skip("Our socket wasn't found!\n");
182         }
183         else
184         {
185             ok(TcpTableOwner->table[i].dwOwningPid == Pid, "Invalid owner\n");
186         }
187 
188         HeapFree(GetProcessHeap(), 0, TcpTableOwner);
189     }
190     else
191     {
192         skip("GetExtendedTcpTableWithAlloc failure\n");
193     }
194 
195     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTableOwner, TRUE, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS) == ERROR_SUCCESS)
196     {
197         Found = FALSE;
198         for (i = 0; i < TcpTableOwner->dwNumEntries; ++i)
199         {
200             if (TcpTableOwner->table[i].dwState == MIB_TCP_STATE_LISTEN &&
201                 TcpTableOwner->table[i].dwLocalAddr == 0 &&
202                 TcpTableOwner->table[i].dwLocalPort == htons(9876) &&
203                 TcpTableOwner->table[i].dwRemoteAddr == 0)
204             {
205                 Found = TRUE;
206                 break;
207             }
208         }
209         ok(Found == FALSE, "Our socket was found!\n");
210 
211         HeapFree(GetProcessHeap(), 0, TcpTableOwner);
212     }
213     else
214     {
215         skip("GetExtendedTcpTableWithAlloc failure\n");
216     }
217 
218     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTableOwner, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER) == ERROR_SUCCESS)
219     {
220         ok(TcpTableOwner->dwNumEntries > 0, "No TCP connections?!\n");
221 
222         Found = FALSE;
223         for (i = 0; i < TcpTableOwner->dwNumEntries; ++i)
224         {
225             if (TcpTableOwner->table[i].dwState == MIB_TCP_STATE_LISTEN &&
226                 TcpTableOwner->table[i].dwLocalAddr == 0 &&
227                 TcpTableOwner->table[i].dwLocalPort == htons(9876) &&
228                 TcpTableOwner->table[i].dwRemoteAddr == 0)
229             {
230                 Found = TRUE;
231                 break;
232             }
233         }
234 
235         if (!Found)
236         {
237             skip("Our socket wasn't found!\n");
238         }
239         else
240         {
241             ok(TcpTableOwner->table[i].dwOwningPid == Pid, "Invalid owner\n");
242         }
243 
244         HeapFree(GetProcessHeap(), 0, TcpTableOwner);
245     }
246     else
247     {
248         skip("GetExtendedTcpTableWithAlloc failure\n");
249     }
250 
251     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTableOwnerMod, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL) == ERROR_SUCCESS)
252     {
253         ok(TcpTableOwnerMod->dwNumEntries > 0, "No TCP connections?!\n");
254 
255         Found = FALSE;
256         for (i = 0; i < TcpTableOwnerMod->dwNumEntries; ++i)
257         {
258             if (TcpTableOwnerMod->table[i].dwState == MIB_TCP_STATE_LISTEN &&
259                 TcpTableOwnerMod->table[i].dwLocalAddr == 0 &&
260                 TcpTableOwnerMod->table[i].dwLocalPort == htons(9876) &&
261                 TcpTableOwnerMod->table[i].dwRemoteAddr == 0)
262             {
263                 Found = TRUE;
264                 break;
265             }
266         }
267 
268         if (!Found)
269         {
270             skip("Our socket wasn't found!\n");
271         }
272         else
273         {
274             ok(TcpTableOwnerMod->table[i].dwOwningPid == Pid, "Invalid owner\n");
275 
276             ok(TcpTableOwnerMod->table[i].liCreateTimestamp.QuadPart >= CreationTime.QuadPart, "Invalid time\n");
277             ok(TcpTableOwnerMod->table[i].liCreateTimestamp.QuadPart <= CreationTime.QuadPart + 60000000000LL, "Invalid time\n");
278         }
279 
280         HeapFree(GetProcessHeap(), 0, TcpTableOwnerMod);
281     }
282     else
283     {
284         skip("GetExtendedTcpTableWithAlloc failure\n");
285     }
286 
287     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTableOwnerMod, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_CONNECTIONS) == ERROR_SUCCESS)
288     {
289         Found = FALSE;
290         for (i = 0; i < TcpTableOwnerMod->dwNumEntries; ++i)
291         {
292             if (TcpTableOwnerMod->table[i].dwState == MIB_TCP_STATE_LISTEN &&
293                 TcpTableOwnerMod->table[i].dwLocalAddr == 0 &&
294                 TcpTableOwnerMod->table[i].dwLocalPort == htons(9876) &&
295                 TcpTableOwnerMod->table[i].dwRemoteAddr == 0)
296             {
297                 Found = TRUE;
298                 break;
299             }
300         }
301         ok(Found == FALSE, "Our socket was found!\n");
302 
303         HeapFree(GetProcessHeap(), 0, TcpTableOwnerMod);
304     }
305     else
306     {
307         skip("GetExtendedTcpTableWithAlloc failure\n");
308     }
309 
310     if (GetExtendedTcpTableWithAlloc((PVOID *)&TcpTableOwnerMod, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER) == ERROR_SUCCESS)
311     {
312         ok(TcpTableOwnerMod->dwNumEntries > 0, "No TCP connections?!\n");
313 
314         Found = FALSE;
315         for (i = 0; i < TcpTableOwnerMod->dwNumEntries; ++i)
316         {
317             if (TcpTableOwnerMod->table[i].dwState == MIB_TCP_STATE_LISTEN &&
318                 TcpTableOwnerMod->table[i].dwLocalAddr == 0 &&
319                 TcpTableOwnerMod->table[i].dwLocalPort == htons(9876) &&
320                 TcpTableOwnerMod->table[i].dwRemoteAddr == 0)
321             {
322                 Found = TRUE;
323                 break;
324             }
325         }
326 
327         if (!Found)
328         {
329             skip("Our socket wasn't found!\n");
330         }
331         else
332         {
333             ok(TcpTableOwnerMod->table[i].dwOwningPid == Pid, "Invalid owner\n");
334 
335             ok(TcpTableOwnerMod->table[i].liCreateTimestamp.QuadPart >= CreationTime.QuadPart, "Invalid time\n");
336             ok(TcpTableOwnerMod->table[i].liCreateTimestamp.QuadPart <= CreationTime.QuadPart + 60000000000LL, "Invalid time\n");
337         }
338 
339         HeapFree(GetProcessHeap(), 0, TcpTableOwnerMod);
340     }
341     else
342     {
343         skip("GetExtendedTcpTableWithAlloc failure\n");
344     }
345 
346 quit2:
347     closesocket(sock);
348 quit:
349     WSACleanup();
350 }
351