1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Tests for UDP 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 GetExtendedUdpTableWithAlloc(PVOID *UdpTable, BOOL Order, DWORD Family, UDP_TABLE_CLASS Class)
15 {
16     DWORD ret;
17     DWORD Size = 0;
18 
19     *UdpTable = NULL;
20 
21     ret = GetExtendedUdpTable(*UdpTable, &Size, Order, Family, Class, 0);
22     if (ret == ERROR_INSUFFICIENT_BUFFER)
23     {
24         *UdpTable = HeapAlloc(GetProcessHeap(), 0, Size);
25         if (*UdpTable == NULL)
26         {
27             return ERROR_OUTOFMEMORY;
28         }
29 
30         ret = GetExtendedUdpTable(*UdpTable, &Size, Order, Family, Class, 0);
31         if (ret != NO_ERROR)
32         {
33             HeapFree(GetProcessHeap(), 0, *UdpTable);
34             *UdpTable = NULL;
35         }
36     }
37 
38     return ret;
39 }
40 
41 START_TEST(GetExtendedUdpTable)
42 {
43     WSADATA wsaData;
44     SOCKET sock;
45     SOCKADDR_IN server;
46     PMIB_UDPTABLE UdpTable;
47     PMIB_UDPTABLE_OWNER_PID UdpTableOwner;
48     PMIB_UDPTABLE_OWNER_MODULE UdpTableOwnerMod;
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_DGRAM, IPPROTO_UDP);
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 (GetExtendedUdpTableWithAlloc((PVOID *)&UdpTable, TRUE, AF_INET, UDP_TABLE_BASIC) == ERROR_SUCCESS)
84     {
85         ok(UdpTable->dwNumEntries > 0, "No UDP connections?!\n");
86 
87         Found = FALSE;
88         for (i = 0; i < UdpTable->dwNumEntries; ++i)
89         {
90             if (UdpTable->table[i].dwLocalAddr == 0 &&
91                 UdpTable->table[i].dwLocalPort == htons(9876))
92             {
93                 Found = TRUE;
94                 break;
95             }
96         }
97         ok(Found, "Our socket wasn't found!\n");
98 
99         HeapFree(GetProcessHeap(), 0, UdpTable);
100     }
101     else
102     {
103         skip("GetExtendedUdpTableWithAlloc failure\n");
104     }
105 
106     if (GetExtendedUdpTableWithAlloc((PVOID *)&UdpTableOwner, TRUE, AF_INET, UDP_TABLE_OWNER_PID) == ERROR_SUCCESS)
107     {
108         ok(UdpTableOwner->dwNumEntries > 0, "No UDP connections?!\n");
109 
110         Found = FALSE;
111         for (i = 0; i < UdpTableOwner->dwNumEntries; ++i)
112         {
113             if (UdpTableOwner->table[i].dwLocalAddr == 0 &&
114                 UdpTableOwner->table[i].dwLocalPort == htons(9876))
115             {
116                 Found = TRUE;
117                 break;
118             }
119         }
120 
121         if (!Found)
122         {
123             skip("Our socket wasn't found!\n");
124         }
125         else
126         {
127             ok(UdpTableOwner->table[i].dwOwningPid == Pid, "Invalid owner\n");
128         }
129 
130         HeapFree(GetProcessHeap(), 0, UdpTableOwner);
131     }
132     else
133     {
134         skip("GetExtendedUdpTableWithAlloc failure\n");
135     }
136 
137     if (GetExtendedUdpTableWithAlloc((PVOID *)&UdpTableOwnerMod, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE) == ERROR_SUCCESS)
138     {
139         ok(UdpTableOwnerMod->dwNumEntries > 0, "No TCP connections?!\n");
140 
141         Found = FALSE;
142         for (i = 0; i < UdpTableOwnerMod->dwNumEntries; ++i)
143         {
144             if (UdpTableOwnerMod->table[i].dwLocalAddr == 0 &&
145                 UdpTableOwnerMod->table[i].dwLocalPort == htons(9876))
146             {
147                 Found = TRUE;
148                 break;
149             }
150         }
151 
152         if (!Found)
153         {
154             skip("Our socket wasn't found!\n");
155         }
156         else
157         {
158             ok(UdpTableOwnerMod->table[i].dwOwningPid == Pid, "Invalid owner\n");
159 
160             ok(UdpTableOwnerMod->table[i].liCreateTimestamp.QuadPart >= CreationTime.QuadPart, "Invalid time\n");
161             ok(UdpTableOwnerMod->table[i].liCreateTimestamp.QuadPart <= CreationTime.QuadPart + 60000000000LL, "Invalid time\n");
162         }
163 
164         HeapFree(GetProcessHeap(), 0, UdpTableOwnerMod);
165     }
166     else
167     {
168         skip("GetExtendedUdpTableWithAlloc failure\n");
169     }
170 
171 quit2:
172     closesocket(sock);
173 quit:
174     WSACleanup();
175 }
176