iphlpapi: Implement if_nametoindex.
[wine.git] / dlls / iphlpapi / tests / iphlpapi.c
blob3369f78f55a1c5674a9ddc9f2a6e396fc7d88709
1 /*
2 * iphlpapi dll test
4 * Copyright (C) 2003 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * Some observations that an automated test can't produce:
23 * An adapter index is a key for an adapter. That is, if an index is returned
24 * from one API, that same index may be used successfully in another API, as
25 * long as the adapter remains present.
26 * If the adapter is removed and reinserted, however, the index may change (and
27 * indeed it does change on Win2K).
29 * The Name field of the IP_ADAPTER_INDEX_MAP entries returned by
30 * GetInterfaceInfo is declared as a wide string, but the bytes are actually
31 * an ASCII string on some versions of the IP helper API under Win9x. This was
32 * apparently an MS bug, it's corrected in later versions.
34 * The DomainName field of FIXED_INFO isn't NULL-terminated on Win98.
37 #include <stdarg.h>
38 #include "winsock2.h"
39 #include "windef.h"
40 #include "winbase.h"
41 #include "ws2tcpip.h"
42 #include "iphlpapi.h"
43 #include "iprtrmib.h"
44 #include "netioapi.h"
45 #include "wine/test.h"
46 #include <stdio.h>
47 #include <stdlib.h>
49 #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */
51 static HMODULE hLibrary = NULL;
53 static DWORD (WINAPI *pAllocateAndGetTcpExTableFromStack)(void**,BOOL,HANDLE,DWORD,DWORD);
54 static DWORD (WINAPI *pGetNumberOfInterfaces)(PDWORD);
55 static DWORD (WINAPI *pGetIpAddrTable)(PMIB_IPADDRTABLE,PULONG,BOOL);
56 static DWORD (WINAPI *pGetIfEntry)(PMIB_IFROW);
57 static DWORD (WINAPI *pGetIfEntry2)(PMIB_IF_ROW2);
58 static DWORD (WINAPI *pGetFriendlyIfIndex)(DWORD);
59 static DWORD (WINAPI *pGetIfTable)(PMIB_IFTABLE,PULONG,BOOL);
60 static DWORD (WINAPI *pGetIfTable2)(PMIB_IF_TABLE2*);
61 static DWORD (WINAPI *pGetIpForwardTable)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
62 static DWORD (WINAPI *pGetIpNetTable)(PMIB_IPNETTABLE,PULONG,BOOL);
63 static DWORD (WINAPI *pGetInterfaceInfo)(PIP_INTERFACE_INFO,PULONG);
64 static DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO,PULONG);
65 static DWORD (WINAPI *pGetNetworkParams)(PFIXED_INFO,PULONG);
66 static DWORD (WINAPI *pGetIcmpStatistics)(PMIB_ICMP);
67 static DWORD (WINAPI *pGetIpStatistics)(PMIB_IPSTATS);
68 static DWORD (WINAPI *pGetTcpStatistics)(PMIB_TCPSTATS);
69 static DWORD (WINAPI *pGetUdpStatistics)(PMIB_UDPSTATS);
70 static DWORD (WINAPI *pGetIcmpStatisticsEx)(PMIB_ICMP_EX,DWORD);
71 static DWORD (WINAPI *pGetIpStatisticsEx)(PMIB_IPSTATS,DWORD);
72 static DWORD (WINAPI *pGetTcpStatisticsEx)(PMIB_TCPSTATS,DWORD);
73 static DWORD (WINAPI *pGetUdpStatisticsEx)(PMIB_UDPSTATS,DWORD);
74 static DWORD (WINAPI *pGetTcpTable)(PMIB_TCPTABLE,PDWORD,BOOL);
75 static DWORD (WINAPI *pGetUdpTable)(PMIB_UDPTABLE,PDWORD,BOOL);
76 static DWORD (WINAPI *pGetPerAdapterInfo)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
77 static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
78 static DWORD (WINAPI *pGetUnicastIpAddressEntry)(MIB_UNICASTIPADDRESS_ROW*);
79 static DWORD (WINAPI *pGetUnicastIpAddressTable)(ADDRESS_FAMILY,MIB_UNICASTIPADDRESS_TABLE**);
80 static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED);
81 static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED);
82 static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
83 static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG);
84 static DWORD (WINAPI *pSetTcpEntry)(PMIB_TCPROW);
85 static HANDLE(WINAPI *pIcmpCreateFile)(VOID);
86 static DWORD (WINAPI *pIcmpSendEcho)(HANDLE,IPAddr,LPVOID,WORD,PIP_OPTION_INFORMATION,LPVOID,DWORD,DWORD);
87 static DWORD (WINAPI *pCreateSortedAddressPairs)(const PSOCKADDR_IN6,ULONG,const PSOCKADDR_IN6,ULONG,ULONG,
88 PSOCKADDR_IN6_PAIR*,ULONG*);
89 static void (WINAPI *pFreeMibTable)(void*);
90 static DWORD (WINAPI *pConvertInterfaceGuidToLuid)(const GUID*,NET_LUID*);
91 static DWORD (WINAPI *pConvertInterfaceIndexToLuid)(NET_IFINDEX,NET_LUID*);
92 static DWORD (WINAPI *pConvertInterfaceLuidToGuid)(const NET_LUID*,GUID*);
93 static DWORD (WINAPI *pConvertInterfaceLuidToIndex)(const NET_LUID*,NET_IFINDEX*);
94 static DWORD (WINAPI *pConvertInterfaceLuidToNameW)(const NET_LUID*,WCHAR*,SIZE_T);
95 static DWORD (WINAPI *pConvertInterfaceLuidToNameA)(const NET_LUID*,char*,SIZE_T);
96 static DWORD (WINAPI *pConvertInterfaceNameToLuidA)(const char*,NET_LUID*);
97 static DWORD (WINAPI *pConvertInterfaceNameToLuidW)(const WCHAR*,NET_LUID*);
99 static NET_IFINDEX (WINAPI *pif_nametoindex)(const char*);
101 static void loadIPHlpApi(void)
103 hLibrary = LoadLibraryA("iphlpapi.dll");
104 if (hLibrary) {
105 pAllocateAndGetTcpExTableFromStack = (void *)GetProcAddress(hLibrary, "AllocateAndGetTcpExTableFromStack");
106 pGetNumberOfInterfaces = (void *)GetProcAddress(hLibrary, "GetNumberOfInterfaces");
107 pGetIpAddrTable = (void *)GetProcAddress(hLibrary, "GetIpAddrTable");
108 pGetIfEntry = (void *)GetProcAddress(hLibrary, "GetIfEntry");
109 pGetIfEntry2 = (void *)GetProcAddress(hLibrary, "GetIfEntry2");
110 pGetFriendlyIfIndex = (void *)GetProcAddress(hLibrary, "GetFriendlyIfIndex");
111 pGetIfTable = (void *)GetProcAddress(hLibrary, "GetIfTable");
112 pGetIfTable2 = (void *)GetProcAddress(hLibrary, "GetIfTable2");
113 pGetIpForwardTable = (void *)GetProcAddress(hLibrary, "GetIpForwardTable");
114 pGetIpNetTable = (void *)GetProcAddress(hLibrary, "GetIpNetTable");
115 pGetInterfaceInfo = (void *)GetProcAddress(hLibrary, "GetInterfaceInfo");
116 pGetAdaptersInfo = (void *)GetProcAddress(hLibrary, "GetAdaptersInfo");
117 pGetNetworkParams = (void *)GetProcAddress(hLibrary, "GetNetworkParams");
118 pGetIcmpStatistics = (void *)GetProcAddress(hLibrary, "GetIcmpStatistics");
119 pGetIpStatistics = (void *)GetProcAddress(hLibrary, "GetIpStatistics");
120 pGetTcpStatistics = (void *)GetProcAddress(hLibrary, "GetTcpStatistics");
121 pGetUdpStatistics = (void *)GetProcAddress(hLibrary, "GetUdpStatistics");
122 pGetIcmpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIcmpStatisticsEx");
123 pGetIpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetIpStatisticsEx");
124 pGetTcpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetTcpStatisticsEx");
125 pGetUdpStatisticsEx = (void *)GetProcAddress(hLibrary, "GetUdpStatisticsEx");
126 pGetTcpTable = (void *)GetProcAddress(hLibrary, "GetTcpTable");
127 pGetUdpTable = (void *)GetProcAddress(hLibrary, "GetUdpTable");
128 pGetPerAdapterInfo = (void *)GetProcAddress(hLibrary, "GetPerAdapterInfo");
129 pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses");
130 pGetUnicastIpAddressEntry = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressEntry");
131 pGetUnicastIpAddressTable = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressTable");
132 pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange");
133 pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify");
134 pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
135 pGetExtendedUdpTable = (void *)GetProcAddress(hLibrary, "GetExtendedUdpTable");
136 pSetTcpEntry = (void *)GetProcAddress(hLibrary, "SetTcpEntry");
137 pIcmpCreateFile = (void *)GetProcAddress(hLibrary, "IcmpCreateFile");
138 pIcmpSendEcho = (void *)GetProcAddress(hLibrary, "IcmpSendEcho");
139 pCreateSortedAddressPairs = (void *)GetProcAddress(hLibrary, "CreateSortedAddressPairs");
140 pFreeMibTable = (void *)GetProcAddress(hLibrary, "FreeMibTable");
141 pConvertInterfaceGuidToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceGuidToLuid");
142 pConvertInterfaceIndexToLuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceIndexToLuid");
143 pConvertInterfaceLuidToGuid = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToGuid");
144 pConvertInterfaceLuidToIndex = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToIndex");
145 pConvertInterfaceLuidToNameA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameA");
146 pConvertInterfaceLuidToNameW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceLuidToNameW");
147 pConvertInterfaceNameToLuidA = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidA");
148 pConvertInterfaceNameToLuidW = (void *)GetProcAddress(hLibrary, "ConvertInterfaceNameToLuidW");
149 pif_nametoindex = (void *)GetProcAddress(hLibrary, "if_nametoindex");
153 static void freeIPHlpApi(void)
155 FreeLibrary(hLibrary);
158 /* replacement for inet_ntoa */
159 static const char *ntoa( DWORD ip )
161 static char buffer[40];
163 ip = htonl(ip);
164 sprintf( buffer, "%u.%u.%u.%u", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff );
165 return buffer;
168 static inline const char* debugstr_longlong(ULONGLONG ll)
170 static char string[17];
171 if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
172 sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
173 else
174 sprintf(string, "%lx", (unsigned long)ll);
175 return string;
179 still-to-be-tested 98-only functions:
180 GetUniDirectionalAdapterInfo
182 static void testWin98OnlyFunctions(void)
186 static void testGetNumberOfInterfaces(void)
188 if (pGetNumberOfInterfaces) {
189 DWORD apiReturn, numInterfaces;
191 /* Crashes on Vista */
192 if (0) {
193 apiReturn = pGetNumberOfInterfaces(NULL);
194 if (apiReturn == ERROR_NOT_SUPPORTED)
195 return;
196 ok(apiReturn == ERROR_INVALID_PARAMETER,
197 "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
198 apiReturn);
201 apiReturn = pGetNumberOfInterfaces(&numInterfaces);
202 if (apiReturn == ERROR_NOT_SUPPORTED) {
203 skip("GetNumberOfInterfaces is not supported\n");
204 return;
206 ok(apiReturn == NO_ERROR,
207 "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn);
211 static void testGetIfEntry(DWORD index)
213 if (pGetIfEntry) {
214 DWORD apiReturn;
215 MIB_IFROW row;
217 memset(&row, 0, sizeof(row));
218 apiReturn = pGetIfEntry(NULL);
219 if (apiReturn == ERROR_NOT_SUPPORTED) {
220 skip("GetIfEntry is not supported\n");
221 return;
223 ok(apiReturn == ERROR_INVALID_PARAMETER,
224 "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
225 apiReturn);
226 row.dwIndex = -1; /* hope that's always bogus! */
227 apiReturn = pGetIfEntry(&row);
228 ok(apiReturn == ERROR_INVALID_DATA ||
229 apiReturn == ERROR_FILE_NOT_FOUND /* Vista */,
230 "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
231 apiReturn);
232 row.dwIndex = index;
233 apiReturn = pGetIfEntry(&row);
234 ok(apiReturn == NO_ERROR,
235 "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn);
239 static void testGetIpAddrTable(void)
241 if (pGetIpAddrTable) {
242 DWORD apiReturn;
243 ULONG dwSize = 0;
245 apiReturn = pGetIpAddrTable(NULL, NULL, FALSE);
246 if (apiReturn == ERROR_NOT_SUPPORTED) {
247 skip("GetIpAddrTable is not supported\n");
248 return;
250 ok(apiReturn == ERROR_INVALID_PARAMETER,
251 "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
252 apiReturn);
253 apiReturn = pGetIpAddrTable(NULL, &dwSize, FALSE);
254 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
255 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
256 apiReturn);
257 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
258 PMIB_IPADDRTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
260 apiReturn = pGetIpAddrTable(buf, &dwSize, FALSE);
261 ok(apiReturn == NO_ERROR,
262 "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
263 apiReturn);
264 if (apiReturn == NO_ERROR && buf->dwNumEntries)
266 int i;
267 testGetIfEntry(buf->table[0].dwIndex);
268 for (i = 0; i < buf->dwNumEntries; i++)
270 ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
271 trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i,
272 ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
273 /* loopback must never be the first when more than one interface is found */
274 if (buf->table[i].dwAddr == htonl(INADDR_LOOPBACK))
275 ok(buf->dwNumEntries == 1 || i, "Loopback interface in wrong first position\n");
278 HeapFree(GetProcessHeap(), 0, buf);
283 static void testGetIfTable(void)
285 if (pGetIfTable) {
286 DWORD apiReturn;
287 ULONG dwSize = 0;
289 apiReturn = pGetIfTable(NULL, NULL, FALSE);
290 if (apiReturn == ERROR_NOT_SUPPORTED) {
291 skip("GetIfTable is not supported\n");
292 return;
294 ok(apiReturn == ERROR_INVALID_PARAMETER,
295 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
296 apiReturn);
297 apiReturn = pGetIfTable(NULL, &dwSize, FALSE);
298 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
299 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
300 apiReturn);
301 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
302 PMIB_IFTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
304 apiReturn = pGetIfTable(buf, &dwSize, FALSE);
305 ok(apiReturn == NO_ERROR,
306 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
307 apiReturn);
309 if (apiReturn == NO_ERROR && winetest_debug > 1)
311 DWORD i, j;
312 char name[MAX_INTERFACE_NAME_LEN];
314 trace( "interface table: %u entries\n", buf->dwNumEntries );
315 for (i = 0; i < buf->dwNumEntries; i++)
317 MIB_IFROW *row = &buf->table[i];
318 WideCharToMultiByte( CP_ACP, 0, row->wszName, -1, name, MAX_INTERFACE_NAME_LEN, NULL, NULL );
319 trace( "%u: '%s' type %u mtu %u speed %u phys",
320 row->dwIndex, name, row->dwType, row->dwMtu, row->dwSpeed );
321 for (j = 0; j < row->dwPhysAddrLen; j++)
322 printf( " %02x", row->bPhysAddr[j] );
323 printf( "\n" );
324 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
325 row->dwInOctets, row->dwInUcastPkts, row->dwInNUcastPkts,
326 row->dwInDiscards, row->dwInErrors, row->dwInUnknownProtos );
327 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
328 row->dwOutOctets, row->dwOutUcastPkts, row->dwOutNUcastPkts,
329 row->dwOutDiscards, row->dwOutErrors );
332 HeapFree(GetProcessHeap(), 0, buf);
337 static void testGetIpForwardTable(void)
339 if (pGetIpForwardTable) {
340 DWORD apiReturn;
341 ULONG dwSize = 0;
343 apiReturn = pGetIpForwardTable(NULL, NULL, FALSE);
344 if (apiReturn == ERROR_NOT_SUPPORTED) {
345 skip("GetIpForwardTable is not supported\n");
346 return;
348 ok(apiReturn == ERROR_INVALID_PARAMETER,
349 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
350 apiReturn);
351 apiReturn = pGetIpForwardTable(NULL, &dwSize, FALSE);
352 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
353 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
354 apiReturn);
355 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
356 PMIB_IPFORWARDTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
358 apiReturn = pGetIpForwardTable(buf, &dwSize, FALSE);
359 ok(apiReturn == NO_ERROR,
360 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
361 apiReturn);
363 if (apiReturn == NO_ERROR)
365 DWORD i;
367 trace( "IP forward table: %u entries\n", buf->dwNumEntries );
368 for (i = 0; i < buf->dwNumEntries; i++)
370 char buffer[100];
372 if (!U1(buf->table[i]).dwForwardDest) /* Default route */
374 todo_wine
375 ok (U1(buf->table[i]).dwForwardProto == MIB_IPPROTO_NETMGMT,
376 "Unexpected dwForwardProto %d\n", U1(buf->table[i]).dwForwardProto);
377 ok (U1(buf->table[i]).dwForwardType == MIB_IPROUTE_TYPE_INDIRECT,
378 "Unexpected dwForwardType %d\n", U1(buf->table[i]).dwForwardType);
380 else
382 /* In general we should get MIB_IPPROTO_LOCAL but does not work
383 * for Vista, 2008 and 7. */
384 ok (U1(buf->table[i]).dwForwardProto == MIB_IPPROTO_LOCAL ||
385 broken(U1(buf->table[i]).dwForwardProto == MIB_IPPROTO_NETMGMT),
386 "Unexpected dwForwardProto %d\n", U1(buf->table[i]).dwForwardProto);
387 /* The forward type varies depending on the address and gateway
388 * value so it is not worth testing in this case. */
391 sprintf( buffer, "dest %s", ntoa( buf->table[i].dwForwardDest ));
392 sprintf( buffer + strlen(buffer), " mask %s", ntoa( buf->table[i].dwForwardMask ));
393 trace( "%u: %s gw %s if %u type %u proto %u\n", i, buffer,
394 ntoa( buf->table[i].dwForwardNextHop ), buf->table[i].dwForwardIfIndex,
395 U1(buf->table[i]).dwForwardType, U1(buf->table[i]).dwForwardProto );
398 HeapFree(GetProcessHeap(), 0, buf);
403 static void testGetIpNetTable(void)
405 if (pGetIpNetTable) {
406 DWORD apiReturn;
407 ULONG dwSize = 0;
409 apiReturn = pGetIpNetTable(NULL, NULL, FALSE);
410 if (apiReturn == ERROR_NOT_SUPPORTED) {
411 skip("GetIpNetTable is not supported\n");
412 return;
414 ok(apiReturn == ERROR_INVALID_PARAMETER,
415 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
416 apiReturn);
417 apiReturn = pGetIpNetTable(NULL, &dwSize, FALSE);
418 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
419 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
420 apiReturn);
421 if (apiReturn == ERROR_NO_DATA)
422 ; /* empty ARP table's okay */
423 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
424 PMIB_IPNETTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
426 apiReturn = pGetIpNetTable(buf, &dwSize, FALSE);
427 ok(apiReturn == NO_ERROR ||
428 apiReturn == ERROR_NO_DATA, /* empty ARP table's okay */
429 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
430 apiReturn);
432 if (apiReturn == NO_ERROR && winetest_debug > 1)
434 DWORD i, j;
436 trace( "IP net table: %u entries\n", buf->dwNumEntries );
437 for (i = 0; i < buf->dwNumEntries; i++)
439 trace( "%u: idx %u type %u addr %s phys",
440 i, buf->table[i].dwIndex, U(buf->table[i]).dwType, ntoa( buf->table[i].dwAddr ));
441 for (j = 0; j < buf->table[i].dwPhysAddrLen; j++)
442 printf( " %02x", buf->table[i].bPhysAddr[j] );
443 printf( "\n" );
446 HeapFree(GetProcessHeap(), 0, buf);
451 static void testGetIcmpStatistics(void)
453 if (pGetIcmpStatistics) {
454 DWORD apiReturn;
455 MIB_ICMP stats;
457 /* Crashes on Vista */
458 if (0) {
459 apiReturn = pGetIcmpStatistics(NULL);
460 if (apiReturn == ERROR_NOT_SUPPORTED)
461 return;
462 ok(apiReturn == ERROR_INVALID_PARAMETER,
463 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
464 apiReturn);
467 apiReturn = pGetIcmpStatistics(&stats);
468 if (apiReturn == ERROR_NOT_SUPPORTED)
470 skip("GetIcmpStatistics is not supported\n");
471 return;
473 ok(apiReturn == NO_ERROR,
474 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn);
475 if (apiReturn == NO_ERROR && winetest_debug > 1)
477 trace( "ICMP stats: %8s %8s\n", "in", "out" );
478 trace( " dwMsgs: %8u %8u\n", stats.stats.icmpInStats.dwMsgs, stats.stats.icmpOutStats.dwMsgs );
479 trace( " dwErrors: %8u %8u\n", stats.stats.icmpInStats.dwErrors, stats.stats.icmpOutStats.dwErrors );
480 trace( " dwDestUnreachs: %8u %8u\n", stats.stats.icmpInStats.dwDestUnreachs, stats.stats.icmpOutStats.dwDestUnreachs );
481 trace( " dwTimeExcds: %8u %8u\n", stats.stats.icmpInStats.dwTimeExcds, stats.stats.icmpOutStats.dwTimeExcds );
482 trace( " dwParmProbs: %8u %8u\n", stats.stats.icmpInStats.dwParmProbs, stats.stats.icmpOutStats.dwParmProbs );
483 trace( " dwSrcQuenchs: %8u %8u\n", stats.stats.icmpInStats.dwSrcQuenchs, stats.stats.icmpOutStats.dwSrcQuenchs );
484 trace( " dwRedirects: %8u %8u\n", stats.stats.icmpInStats.dwRedirects, stats.stats.icmpOutStats.dwRedirects );
485 trace( " dwEchos: %8u %8u\n", stats.stats.icmpInStats.dwEchos, stats.stats.icmpOutStats.dwEchos );
486 trace( " dwEchoReps: %8u %8u\n", stats.stats.icmpInStats.dwEchoReps, stats.stats.icmpOutStats.dwEchoReps );
487 trace( " dwTimestamps: %8u %8u\n", stats.stats.icmpInStats.dwTimestamps, stats.stats.icmpOutStats.dwTimestamps );
488 trace( " dwTimestampReps: %8u %8u\n", stats.stats.icmpInStats.dwTimestampReps, stats.stats.icmpOutStats.dwTimestampReps );
489 trace( " dwAddrMasks: %8u %8u\n", stats.stats.icmpInStats.dwAddrMasks, stats.stats.icmpOutStats.dwAddrMasks );
490 trace( " dwAddrMaskReps: %8u %8u\n", stats.stats.icmpInStats.dwAddrMaskReps, stats.stats.icmpOutStats.dwAddrMaskReps );
495 static void testGetIpStatistics(void)
497 if (pGetIpStatistics) {
498 DWORD apiReturn;
499 MIB_IPSTATS stats;
501 apiReturn = pGetIpStatistics(NULL);
502 if (apiReturn == ERROR_NOT_SUPPORTED) {
503 skip("GetIpStatistics is not supported\n");
504 return;
506 ok(apiReturn == ERROR_INVALID_PARAMETER,
507 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
508 apiReturn);
509 apiReturn = pGetIpStatistics(&stats);
510 ok(apiReturn == NO_ERROR,
511 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn);
512 if (apiReturn == NO_ERROR && winetest_debug > 1)
514 trace( "IP stats:\n" );
515 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
516 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
517 trace( " dwInReceives: %u\n", stats.dwInReceives );
518 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
519 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
520 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
521 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
522 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
523 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
524 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
525 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
526 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
527 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
528 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
529 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
530 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
531 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
532 trace( " dwFragOks: %u\n", stats.dwFragOks );
533 trace( " dwFragFails: %u\n", stats.dwFragFails );
534 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
535 trace( " dwNumIf: %u\n", stats.dwNumIf );
536 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
537 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
542 static void testGetTcpStatistics(void)
544 if (pGetTcpStatistics) {
545 DWORD apiReturn;
546 MIB_TCPSTATS stats;
548 apiReturn = pGetTcpStatistics(NULL);
549 if (apiReturn == ERROR_NOT_SUPPORTED) {
550 skip("GetTcpStatistics is not supported\n");
551 return;
553 ok(apiReturn == ERROR_INVALID_PARAMETER,
554 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
555 apiReturn);
556 apiReturn = pGetTcpStatistics(&stats);
557 ok(apiReturn == NO_ERROR,
558 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn);
559 if (apiReturn == NO_ERROR && winetest_debug > 1)
561 trace( "TCP stats:\n" );
562 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
563 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
564 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
565 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
566 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
567 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
568 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
569 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
570 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
571 trace( " dwInSegs: %u\n", stats.dwInSegs );
572 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
573 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
574 trace( " dwInErrs: %u\n", stats.dwInErrs );
575 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
576 trace( " dwNumConns: %u\n", stats.dwNumConns );
581 static void testGetUdpStatistics(void)
583 if (pGetUdpStatistics) {
584 DWORD apiReturn;
585 MIB_UDPSTATS stats;
587 apiReturn = pGetUdpStatistics(NULL);
588 if (apiReturn == ERROR_NOT_SUPPORTED) {
589 skip("GetUdpStatistics is not supported\n");
590 return;
592 ok(apiReturn == ERROR_INVALID_PARAMETER,
593 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
594 apiReturn);
595 apiReturn = pGetUdpStatistics(&stats);
596 ok(apiReturn == NO_ERROR,
597 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn);
598 if (apiReturn == NO_ERROR && winetest_debug > 1)
600 trace( "UDP stats:\n" );
601 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
602 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
603 trace( " dwInErrors: %u\n", stats.dwInErrors );
604 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
605 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
610 static void testGetIcmpStatisticsEx(void)
612 DWORD apiReturn;
613 MIB_ICMP_EX stats;
615 if (!pGetIcmpStatisticsEx)
617 win_skip( "GetIcmpStatisticsEx not available\n" );
618 return;
621 /* Crashes on Vista */
622 if (1) {
623 apiReturn = pGetIcmpStatisticsEx(NULL, AF_INET);
624 ok(apiReturn == ERROR_INVALID_PARAMETER,
625 "GetIcmpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
628 apiReturn = pGetIcmpStatisticsEx(&stats, AF_BAN);
629 ok(apiReturn == ERROR_INVALID_PARAMETER,
630 "GetIcmpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
632 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET);
633 ok(apiReturn == NO_ERROR, "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
634 if (apiReturn == NO_ERROR && winetest_debug > 1)
636 INT i;
637 trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" );
638 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
639 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
640 for (i = 0; i < 256; i++)
641 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
644 apiReturn = pGetIcmpStatisticsEx(&stats, AF_INET6);
645 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
646 "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
647 if (apiReturn == NO_ERROR && winetest_debug > 1)
649 INT i;
650 trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
651 trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
652 trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
653 for (i = 0; i < 256; i++)
654 trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
658 static void testGetIpStatisticsEx(void)
660 DWORD apiReturn;
661 MIB_IPSTATS stats;
663 if (!pGetIpStatisticsEx)
665 win_skip( "GetIpStatisticsEx not available\n" );
666 return;
669 apiReturn = pGetIpStatisticsEx(NULL, AF_INET);
670 ok(apiReturn == ERROR_INVALID_PARAMETER,
671 "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
673 apiReturn = pGetIpStatisticsEx(&stats, AF_BAN);
674 ok(apiReturn == ERROR_INVALID_PARAMETER,
675 "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
677 apiReturn = pGetIpStatisticsEx(&stats, AF_INET);
678 ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
679 if (apiReturn == NO_ERROR && winetest_debug > 1)
681 trace( "IP IPv4 Ex stats:\n" );
682 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
683 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
684 trace( " dwInReceives: %u\n", stats.dwInReceives );
685 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
686 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
687 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
688 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
689 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
690 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
691 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
692 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
693 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
694 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
695 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
696 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
697 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
698 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
699 trace( " dwFragOks: %u\n", stats.dwFragOks );
700 trace( " dwFragFails: %u\n", stats.dwFragFails );
701 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
702 trace( " dwNumIf: %u\n", stats.dwNumIf );
703 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
704 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
707 apiReturn = pGetIpStatisticsEx(&stats, AF_INET6);
708 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
709 "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
710 if (apiReturn == NO_ERROR && winetest_debug > 1)
712 trace( "IP IPv6 Ex stats:\n" );
713 trace( " dwForwarding: %u\n", U(stats).dwForwarding );
714 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
715 trace( " dwInReceives: %u\n", stats.dwInReceives );
716 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
717 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
718 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
719 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
720 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
721 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
722 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
723 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
724 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
725 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
726 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
727 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
728 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
729 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
730 trace( " dwFragOks: %u\n", stats.dwFragOks );
731 trace( " dwFragFails: %u\n", stats.dwFragFails );
732 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
733 trace( " dwNumIf: %u\n", stats.dwNumIf );
734 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
735 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
739 static void testGetTcpStatisticsEx(void)
741 DWORD apiReturn;
742 MIB_TCPSTATS stats;
744 if (!pGetTcpStatisticsEx)
746 win_skip( "GetTcpStatisticsEx not available\n" );
747 return;
750 apiReturn = pGetTcpStatisticsEx(NULL, AF_INET);
751 ok(apiReturn == ERROR_INVALID_PARAMETER,
752 "GetTcpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
754 apiReturn = pGetTcpStatisticsEx(&stats, AF_BAN);
755 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
756 "GetTcpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
758 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET);
759 ok(apiReturn == NO_ERROR, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
760 if (apiReturn == NO_ERROR && winetest_debug > 1)
762 trace( "TCP IPv4 Ex stats:\n" );
763 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
764 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
765 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
766 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
767 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
768 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
769 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
770 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
771 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
772 trace( " dwInSegs: %u\n", stats.dwInSegs );
773 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
774 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
775 trace( " dwInErrs: %u\n", stats.dwInErrs );
776 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
777 trace( " dwNumConns: %u\n", stats.dwNumConns );
780 apiReturn = pGetTcpStatisticsEx(&stats, AF_INET6);
781 todo_wine ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
782 "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
783 if (apiReturn == NO_ERROR && winetest_debug > 1)
785 trace( "TCP IPv6 Ex stats:\n" );
786 trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm );
787 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
788 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
789 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
790 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
791 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
792 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
793 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
794 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
795 trace( " dwInSegs: %u\n", stats.dwInSegs );
796 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
797 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
798 trace( " dwInErrs: %u\n", stats.dwInErrs );
799 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
800 trace( " dwNumConns: %u\n", stats.dwNumConns );
804 static void testGetUdpStatisticsEx(void)
806 DWORD apiReturn;
807 MIB_UDPSTATS stats;
809 if (!pGetUdpStatisticsEx)
811 win_skip( "GetUdpStatisticsEx not available\n" );
812 return;
815 apiReturn = pGetUdpStatisticsEx(NULL, AF_INET);
816 ok(apiReturn == ERROR_INVALID_PARAMETER,
817 "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
819 apiReturn = pGetUdpStatisticsEx(&stats, AF_BAN);
820 ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED,
821 "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
823 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET);
824 ok(apiReturn == NO_ERROR, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
825 if (apiReturn == NO_ERROR && winetest_debug > 1)
827 trace( "UDP IPv4 Ex stats:\n" );
828 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
829 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
830 trace( " dwInErrors: %u\n", stats.dwInErrors );
831 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
832 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
835 apiReturn = pGetUdpStatisticsEx(&stats, AF_INET6);
836 ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
837 "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
838 if (apiReturn == NO_ERROR && winetest_debug > 1)
840 trace( "UDP IPv6 Ex stats:\n" );
841 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
842 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
843 trace( " dwInErrors: %u\n", stats.dwInErrors );
844 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
845 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
849 static void testGetTcpTable(void)
851 if (pGetTcpTable) {
852 DWORD apiReturn;
853 ULONG dwSize = 0;
855 apiReturn = pGetTcpTable(NULL, &dwSize, FALSE);
856 if (apiReturn == ERROR_NOT_SUPPORTED) {
857 skip("GetTcpTable is not supported\n");
858 return;
860 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER ||
861 broken(apiReturn == ERROR_NO_DATA), /* win95 */
862 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
863 apiReturn);
864 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
865 PMIB_TCPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
867 apiReturn = pGetTcpTable(buf, &dwSize, FALSE);
868 ok(apiReturn == NO_ERROR,
869 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
870 apiReturn);
872 if (apiReturn == NO_ERROR && winetest_debug > 1)
874 DWORD i;
875 trace( "TCP table: %u entries\n", buf->dwNumEntries );
876 for (i = 0; i < buf->dwNumEntries; i++)
878 char buffer[40];
879 sprintf( buffer, "local %s:%u",
880 ntoa(buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalPort) );
881 trace( "%u: %s remote %s:%u state %u\n",
882 i, buffer, ntoa( buf->table[i].dwRemoteAddr ),
883 ntohs(buf->table[i].dwRemotePort), U(buf->table[i]).dwState );
886 HeapFree(GetProcessHeap(), 0, buf);
891 static void testGetUdpTable(void)
893 if (pGetUdpTable) {
894 DWORD apiReturn;
895 ULONG dwSize = 0;
897 apiReturn = pGetUdpTable(NULL, &dwSize, FALSE);
898 if (apiReturn == ERROR_NOT_SUPPORTED) {
899 skip("GetUdpTable is not supported\n");
900 return;
902 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
903 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
904 apiReturn);
905 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
906 PMIB_UDPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
908 apiReturn = pGetUdpTable(buf, &dwSize, FALSE);
909 ok(apiReturn == NO_ERROR,
910 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
911 apiReturn);
913 if (apiReturn == NO_ERROR && winetest_debug > 1)
915 DWORD i;
916 trace( "UDP table: %u entries\n", buf->dwNumEntries );
917 for (i = 0; i < buf->dwNumEntries; i++)
918 trace( "%u: %s:%u\n",
919 i, ntoa( buf->table[i].dwLocalAddr ), ntohs(buf->table[i].dwLocalPort) );
921 HeapFree(GetProcessHeap(), 0, buf);
926 static void testSetTcpEntry(void)
928 DWORD ret;
929 MIB_TCPROW row;
931 memset(&row, 0, sizeof(row));
932 if(0) /* This test crashes in OS >= VISTA */
934 ret = pSetTcpEntry(NULL);
935 ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
938 ret = pSetTcpEntry(&row);
939 if (ret == ERROR_NETWORK_ACCESS_DENIED)
941 win_skip("SetTcpEntry failed with access error. Skipping test.\n");
942 return;
944 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %u, expected %u\n", ret, ERROR_INVALID_PARAMETER);
946 U(row).dwState = MIB_TCP_STATE_DELETE_TCB;
947 ret = pSetTcpEntry(&row);
948 todo_wine ok( ret == ERROR_MR_MID_NOT_FOUND || broken(ret == ERROR_INVALID_PARAMETER),
949 "got %u, expected %u\n", ret, ERROR_MR_MID_NOT_FOUND);
952 static void testIcmpSendEcho(void)
954 HANDLE icmp;
955 char senddata[32], replydata[sizeof(senddata) + sizeof(ICMP_ECHO_REPLY)];
956 DWORD ret, error, replysz = sizeof(replydata);
957 IPAddr address;
959 if (!pIcmpSendEcho || !pIcmpCreateFile)
961 win_skip( "IcmpSendEcho or IcmpCreateFile not available\n" );
962 return;
964 memset(senddata, 0, sizeof(senddata));
966 address = htonl(INADDR_LOOPBACK);
967 SetLastError(0xdeadbeef);
968 ret = pIcmpSendEcho(INVALID_HANDLE_VALUE, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
969 error = GetLastError();
970 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
971 todo_wine
972 ok (error == ERROR_INVALID_PARAMETER
973 || broken(error == ERROR_INVALID_HANDLE) /* <= 2003 */,
974 "expected 87, got %d\n", error);
976 icmp = pIcmpCreateFile();
977 if (icmp == INVALID_HANDLE_VALUE)
979 error = GetLastError();
980 if (error == ERROR_ACCESS_DENIED)
982 skip ("ICMP is not available.\n");
983 return;
986 ok (icmp != INVALID_HANDLE_VALUE, "IcmpCreateFile failed unexpectedly with error %d\n", GetLastError());
988 address = 0;
989 SetLastError(0xdeadbeef);
990 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
991 error = GetLastError();
992 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
993 ok (error == ERROR_INVALID_NETNAME
994 || broken(error == IP_BAD_DESTINATION) /* <= 2003 */,
995 "expected 1214, got %d\n", error);
997 address = htonl(INADDR_LOOPBACK);
998 if (0) /* crashes in XP */
1000 ret = pIcmpSendEcho(icmp, address, NULL, sizeof(senddata), NULL, replydata, replysz, 1000);
1001 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1004 SetLastError(0xdeadbeef);
1005 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
1006 error = GetLastError();
1007 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1009 SetLastError(0xdeadbeef);
1010 ret = pIcmpSendEcho(icmp, address, NULL, 0, NULL, replydata, replysz, 1000);
1011 error = GetLastError();
1012 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1014 if (0) /* crashes in wine, remove IF when fixed */
1016 SetLastError(0xdeadbeef);
1017 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, replysz, 1000);
1018 error = GetLastError();
1019 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1020 ok (error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1023 SetLastError(0xdeadbeef);
1024 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, 0, 1000);
1025 error = GetLastError();
1026 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1027 todo_wine
1028 ok (error == ERROR_INVALID_PARAMETER
1029 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1030 "expected 87, got %d\n", error);
1032 SetLastError(0xdeadbeef);
1033 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, NULL, 0, 1000);
1034 error = GetLastError();
1035 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1036 todo_wine
1037 ok (error == ERROR_INVALID_PARAMETER
1038 || broken(error == ERROR_INSUFFICIENT_BUFFER) /* <= 2003 */,
1039 "expected 87, got %d\n", error);
1041 SetLastError(0xdeadbeef);
1042 replysz = sizeof(replydata) - 1;
1043 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1044 error = GetLastError();
1045 todo_wine {
1046 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1047 ok (error == IP_GENERAL_FAILURE
1048 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1049 "expected 11050, got %d\n", error);
1052 SetLastError(0xdeadbeef);
1053 replysz = sizeof(ICMP_ECHO_REPLY);
1054 ret = pIcmpSendEcho(icmp, address, senddata, 0, NULL, replydata, replysz, 1000);
1055 error = GetLastError();
1056 todo_wine
1057 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1059 SetLastError(0xdeadbeef);
1060 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1061 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz, 1000);
1062 error = GetLastError();
1063 todo_wine
1064 ok (ret, "IcmpSendEcho failed unexpectedly with error %d\n", error);
1066 SetLastError(0xdeadbeef);
1067 replysz = sizeof(ICMP_ECHO_REPLY) + ICMP_MINLEN;
1068 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN + 1, NULL, replydata, replysz, 1000);
1069 error = GetLastError();
1070 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1071 todo_wine
1072 ok (error == IP_GENERAL_FAILURE
1073 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1074 "expected 11050, got %d\n", error);
1076 SetLastError(0xdeadbeef);
1077 ret = pIcmpSendEcho(icmp, address, senddata, ICMP_MINLEN, NULL, replydata, replysz - 1, 1000);
1078 error = GetLastError();
1079 ok (!ret, "IcmpSendEcho succeeded unexpectedly\n");
1080 todo_wine
1081 ok (error == IP_GENERAL_FAILURE
1082 || broken(error == IP_BUF_TOO_SMALL) /* <= 2003 */,
1083 "expected 11050, got %d\n", error);
1085 /* in windows >= vista the timeout can't be invalid */
1086 SetLastError(0xdeadbeef);
1087 replysz = sizeof(replydata);
1088 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 0);
1089 error = GetLastError();
1090 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1092 SetLastError(0xdeadbeef);
1093 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, -1);
1094 error = GetLastError();
1095 if (!ret) ok(error == ERROR_INVALID_PARAMETER, "expected 87, got %d\n", error);
1097 /* real ping test */
1098 SetLastError(0xdeadbeef);
1099 address = htonl(INADDR_LOOPBACK);
1100 ret = pIcmpSendEcho(icmp, address, senddata, sizeof(senddata), NULL, replydata, replysz, 1000);
1101 error = GetLastError();
1102 if (ret)
1104 PICMP_ECHO_REPLY pong = (PICMP_ECHO_REPLY) replydata;
1105 trace ("send addr : %s\n", ntoa(address));
1106 trace ("reply addr : %s\n", ntoa(pong->Address));
1107 trace ("reply size : %u\n", replysz);
1108 trace ("roundtrip : %u ms\n", pong->RoundTripTime);
1109 trace ("status : %u\n", pong->Status);
1110 trace ("recv size : %u\n", pong->DataSize);
1111 trace ("ttl : %u\n", pong->Options.Ttl);
1112 trace ("flags : 0x%x\n", pong->Options.Flags);
1114 else
1116 skip ("Failed to ping with error %d, is lo interface down?.\n", error);
1121 still-to-be-tested NT4-onward functions:
1122 CreateIpForwardEntry
1123 DeleteIpForwardEntry
1124 CreateIpNetEntry
1125 DeleteIpNetEntry
1126 GetFriendlyIfIndex
1127 GetRTTAndHopCount
1128 SetIfEntry
1129 SetIpForwardEntry
1130 SetIpNetEntry
1131 SetIpStatistics
1132 SetIpTTL
1134 static void testWinNT4Functions(void)
1136 testGetNumberOfInterfaces();
1137 testGetIpAddrTable();
1138 testGetIfTable();
1139 testGetIpForwardTable();
1140 testGetIpNetTable();
1141 testGetIcmpStatistics();
1142 testGetIpStatistics();
1143 testGetTcpStatistics();
1144 testGetUdpStatistics();
1145 testGetIcmpStatisticsEx();
1146 testGetIpStatisticsEx();
1147 testGetTcpStatisticsEx();
1148 testGetUdpStatisticsEx();
1149 testGetTcpTable();
1150 testGetUdpTable();
1151 testSetTcpEntry();
1152 testIcmpSendEcho();
1155 static void testGetInterfaceInfo(void)
1157 if (pGetInterfaceInfo) {
1158 DWORD apiReturn;
1159 ULONG len = 0;
1161 apiReturn = pGetInterfaceInfo(NULL, NULL);
1162 if (apiReturn == ERROR_NOT_SUPPORTED) {
1163 skip("GetInterfaceInfo is not supported\n");
1164 return;
1166 ok(apiReturn == ERROR_INVALID_PARAMETER,
1167 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1168 apiReturn);
1169 apiReturn = pGetInterfaceInfo(NULL, &len);
1170 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
1171 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
1172 apiReturn);
1173 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
1174 PIP_INTERFACE_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1176 apiReturn = pGetInterfaceInfo(buf, &len);
1177 ok(apiReturn == NO_ERROR,
1178 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1179 apiReturn);
1180 HeapFree(GetProcessHeap(), 0, buf);
1185 static void testGetAdaptersInfo(void)
1187 if (pGetAdaptersInfo) {
1188 DWORD apiReturn;
1189 ULONG len = 0;
1191 apiReturn = pGetAdaptersInfo(NULL, NULL);
1192 if (apiReturn == ERROR_NOT_SUPPORTED) {
1193 skip("GetAdaptersInfo is not supported\n");
1194 return;
1196 ok(apiReturn == ERROR_INVALID_PARAMETER,
1197 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
1198 apiReturn);
1199 apiReturn = pGetAdaptersInfo(NULL, &len);
1200 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
1201 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
1202 apiReturn);
1203 if (apiReturn == ERROR_NO_DATA)
1204 ; /* no adapter's, that's okay */
1205 else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1206 PIP_ADAPTER_INFO ptr, buf = HeapAlloc(GetProcessHeap(), 0, len);
1208 apiReturn = pGetAdaptersInfo(buf, &len);
1209 ok(apiReturn == NO_ERROR,
1210 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
1211 apiReturn);
1212 ptr = buf;
1213 while (ptr) {
1214 ok(ptr->IpAddressList.IpAddress.String[0], "A valid IP must be present\n");
1215 ok(ptr->IpAddressList.IpMask.String[0], "A valid mask must be present\n");
1216 trace("Adapter '%s', IP %s, Mask %s\n", ptr->AdapterName,
1217 ptr->IpAddressList.IpAddress.String, ptr->IpAddressList.IpMask.String);
1218 ptr = ptr->Next;
1220 HeapFree(GetProcessHeap(), 0, buf);
1225 static void testGetNetworkParams(void)
1227 if (pGetNetworkParams) {
1228 DWORD apiReturn;
1229 ULONG len = 0;
1231 apiReturn = pGetNetworkParams(NULL, NULL);
1232 if (apiReturn == ERROR_NOT_SUPPORTED) {
1233 skip("GetNetworkParams is not supported\n");
1234 return;
1236 ok(apiReturn == ERROR_INVALID_PARAMETER,
1237 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
1238 apiReturn);
1239 apiReturn = pGetNetworkParams(NULL, &len);
1240 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
1241 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
1242 apiReturn);
1243 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
1244 PFIXED_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
1246 apiReturn = pGetNetworkParams(buf, &len);
1247 ok(apiReturn == NO_ERROR,
1248 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
1249 apiReturn);
1250 HeapFree(GetProcessHeap(), 0, buf);
1256 still-to-be-tested 98-onward functions:
1257 GetBestInterface
1258 GetBestRoute
1259 IpReleaseAddress
1260 IpRenewAddress
1262 static DWORD CALLBACK testWin98Functions(void *p)
1264 testGetInterfaceInfo();
1265 testGetAdaptersInfo();
1266 testGetNetworkParams();
1267 return 0;
1270 static void testGetPerAdapterInfo(void)
1272 DWORD ret, needed;
1273 void *buffer;
1275 if (!pGetPerAdapterInfo) return;
1276 ret = pGetPerAdapterInfo(1, NULL, NULL);
1277 if (ret == ERROR_NOT_SUPPORTED) {
1278 skip("GetPerAdapterInfo is not supported\n");
1279 return;
1281 ok( ret == ERROR_INVALID_PARAMETER, "got %u instead of ERROR_INVALID_PARAMETER\n", ret );
1282 needed = 0xdeadbeef;
1283 ret = pGetPerAdapterInfo(1, NULL, &needed);
1284 if (ret == ERROR_NO_DATA) return; /* no such adapter */
1285 ok( ret == ERROR_BUFFER_OVERFLOW, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret );
1286 ok( needed != 0xdeadbeef, "needed not set\n" );
1287 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
1288 ret = pGetPerAdapterInfo(1, buffer, &needed);
1289 ok( ret == NO_ERROR, "got %u instead of NO_ERROR\n", ret );
1290 HeapFree( GetProcessHeap(), 0, buffer );
1293 static void testNotifyAddrChange(void)
1295 DWORD ret, bytes;
1296 OVERLAPPED overlapped;
1297 HANDLE handle;
1298 BOOL success;
1300 if (!pNotifyAddrChange)
1302 win_skip("NotifyAddrChange not present\n");
1303 return;
1305 if (!pCancelIPChangeNotify)
1307 win_skip("CancelIPChangeNotify not present\n");
1308 return;
1311 handle = NULL;
1312 ZeroMemory(&overlapped, sizeof(overlapped));
1313 ret = pNotifyAddrChange(&handle, &overlapped);
1314 if (ret == ERROR_NOT_SUPPORTED)
1316 win_skip("NotifyAddrChange is not supported\n");
1317 return;
1319 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1320 ret = GetLastError();
1321 todo_wine ok(ret == ERROR_IO_PENDING, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret);
1322 success = pCancelIPChangeNotify(&overlapped);
1323 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1325 ZeroMemory(&overlapped, sizeof(overlapped));
1326 success = pCancelIPChangeNotify(&overlapped);
1327 ok(success == FALSE, "CancelIPChangeNotify returned TRUE, expected FALSE\n");
1329 handle = NULL;
1330 ZeroMemory(&overlapped, sizeof(overlapped));
1331 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1332 ret = pNotifyAddrChange(&handle, &overlapped);
1333 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret);
1334 todo_wine ok(handle != INVALID_HANDLE_VALUE, "NotifyAddrChange returned invalid file handle\n");
1335 success = GetOverlappedResult(handle, &overlapped, &bytes, FALSE);
1336 ok(success == FALSE, "GetOverlappedResult returned TRUE, expected FALSE\n");
1337 ret = GetLastError();
1338 ok(ret == ERROR_IO_INCOMPLETE, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret);
1339 success = pCancelIPChangeNotify(&overlapped);
1340 todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n");
1342 if (winetest_interactive)
1344 handle = NULL;
1345 ZeroMemory(&overlapped, sizeof(overlapped));
1346 overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1347 trace("Testing asynchronous ipv4 address change notification. Please "
1348 "change the ipv4 address of one of your network interfaces\n");
1349 ret = pNotifyAddrChange(&handle, &overlapped);
1350 ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1351 success = GetOverlappedResult(handle, &overlapped, &bytes, TRUE);
1352 ok(success == TRUE, "GetOverlappedResult returned FALSE, expected TRUE\n");
1355 /* test synchronous functionality */
1356 if (winetest_interactive)
1358 trace("Testing synchronous ipv4 address change notification. Please "
1359 "change the ipv4 address of one of your network interfaces\n");
1360 ret = pNotifyAddrChange(NULL, NULL);
1361 todo_wine ok(ret == NO_ERROR, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret);
1366 still-to-be-tested 2K-onward functions:
1367 AddIPAddress
1368 CreateProxyArpEntry
1369 DeleteIPAddress
1370 DeleteProxyArpEntry
1371 EnableRouter
1372 FlushIpNetTable
1373 GetAdapterIndex
1374 NotifyRouteChange + CancelIPChangeNotify
1375 SendARP
1376 UnenableRouter
1378 static void testWin2KFunctions(void)
1380 testGetPerAdapterInfo();
1381 testNotifyAddrChange();
1384 static void test_GetAdaptersAddresses(void)
1386 ULONG ret, size, osize, i;
1387 IP_ADAPTER_ADDRESSES *aa, *ptr;
1388 IP_ADAPTER_UNICAST_ADDRESS *ua;
1390 if (!pGetAdaptersAddresses)
1392 win_skip("GetAdaptersAddresses not present\n");
1393 return;
1396 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, NULL);
1397 ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", ret);
1399 /* size should be ignored and overwritten if buffer is NULL */
1400 size = 0x7fffffff;
1401 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
1402 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret);
1403 if (ret != ERROR_BUFFER_OVERFLOW) return;
1405 ptr = HeapAlloc(GetProcessHeap(), 0, size);
1406 ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, ptr, &size);
1407 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1408 HeapFree(GetProcessHeap(), 0, ptr);
1410 /* higher size must not be changed to lower size */
1411 size *= 2;
1412 osize = size;
1413 ptr = HeapAlloc(GetProcessHeap(), 0, osize);
1414 ret = pGetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, ptr, &osize);
1415 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
1416 ok(osize == size, "expected %d, got %d\n", size, osize);
1418 for (aa = ptr; !ret && aa; aa = aa->Next)
1420 char temp[128], buf[39];
1421 IP_ADAPTER_PREFIX *prefix;
1422 DWORD status;
1423 GUID guid;
1425 ok(S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_LH) ||
1426 S(U(*aa)).Length == sizeof(IP_ADAPTER_ADDRESSES_XP),
1427 "Unknown structure size of %u bytes\n", S(U(*aa)).Length);
1428 ok(aa->DnsSuffix != NULL, "DnsSuffix is not a valid pointer\n");
1429 ok(aa->Description != NULL, "Description is not a valid pointer\n");
1430 ok(aa->FriendlyName != NULL, "FriendlyName is not a valid pointer\n");
1432 trace("\n");
1433 trace("Length: %u\n", S(U(*aa)).Length);
1434 trace("IfIndex: %u\n", S(U(*aa)).IfIndex);
1435 trace("Next: %p\n", aa->Next);
1436 trace("AdapterName: %s\n", aa->AdapterName);
1437 trace("FirstUnicastAddress: %p\n", aa->FirstUnicastAddress);
1438 ua = aa->FirstUnicastAddress;
1439 while (ua)
1441 ok(S(U(*ua)).Length == sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH) ||
1442 S(U(*ua)).Length == sizeof(IP_ADAPTER_UNICAST_ADDRESS_XP),
1443 "Unknown structure size of %u bytes\n", S(U(*ua)).Length);
1444 ok(ua->PrefixOrigin != IpPrefixOriginOther,
1445 "bad address config value %d\n", ua->PrefixOrigin);
1446 ok(ua->SuffixOrigin != IpSuffixOriginOther,
1447 "bad address config value %d\n", ua->PrefixOrigin);
1448 /* Address configured manually or from DHCP server? */
1449 if (ua->PrefixOrigin == IpPrefixOriginManual ||
1450 ua->PrefixOrigin == IpPrefixOriginDhcp)
1452 ok(ua->ValidLifetime, "expected non-zero value\n");
1453 ok(ua->PreferredLifetime, "expected non-zero value\n");
1454 ok(ua->LeaseLifetime, "expected non-zero\n");
1456 /* Is the address ok in the network (not duplicated)? */
1457 ok(ua->DadState != IpDadStateInvalid && ua->DadState != IpDadStateDuplicate,
1458 "bad address duplication value %d\n", ua->DadState);
1459 trace("\tLength: %u\n", S(U(*ua)).Length);
1460 trace("\tFlags: 0x%08x\n", S(U(*ua)).Flags);
1461 trace("\tNext: %p\n", ua->Next);
1462 trace("\tAddress.lpSockaddr: %p\n", ua->Address.lpSockaddr);
1463 trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength);
1464 trace("\tPrefixOrigin: %u\n", ua->PrefixOrigin);
1465 trace("\tSuffixOrigin: %u\n", ua->SuffixOrigin);
1466 trace("\tDadState: %u\n", ua->DadState);
1467 trace("\tValidLifetime: %u seconds\n", ua->ValidLifetime);
1468 trace("\tPreferredLifetime: %u seconds\n", ua->PreferredLifetime);
1469 trace("\tLeaseLifetime: %u seconds\n", ua->LeaseLifetime);
1470 if (S(U(*ua)).Length < sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH))
1472 trace("\n");
1473 ua = ua->Next;
1474 continue;
1476 trace("\tOnLinkPrefixLength: %u\n", ua->OnLinkPrefixLength);
1477 trace("\n");
1478 ua = ua->Next;
1480 trace("FirstAnycastAddress: %p\n", aa->FirstAnycastAddress);
1481 trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress);
1482 trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress);
1483 trace("DnsSuffix: %s %p\n", wine_dbgstr_w(aa->DnsSuffix), aa->DnsSuffix);
1484 trace("Description: %s %p\n", wine_dbgstr_w(aa->Description), aa->Description);
1485 trace("FriendlyName: %s %p\n", wine_dbgstr_w(aa->FriendlyName), aa->FriendlyName);
1486 trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength);
1487 for (i = 0; i < aa->PhysicalAddressLength; i++)
1488 sprintf(temp + i * 3, "%02X-", aa->PhysicalAddress[i]);
1489 temp[i ? i * 3 - 1 : 0] = '\0';
1490 trace("PhysicalAddress: %s\n", temp);
1491 trace("Flags: 0x%08x\n", aa->Flags);
1492 trace("Mtu: %u\n", aa->Mtu);
1493 trace("IfType: %u\n", aa->IfType);
1494 trace("OperStatus: %u\n", aa->OperStatus);
1495 trace("Ipv6IfIndex: %u\n", aa->Ipv6IfIndex);
1496 for (i = 0, temp[0] = '\0'; i < sizeof(aa->ZoneIndices) / sizeof(aa->ZoneIndices[0]); i++)
1497 sprintf(temp + strlen(temp), "%d ", aa->ZoneIndices[i]);
1498 trace("ZoneIndices: %s\n", temp);
1499 trace("FirstPrefix: %p\n", aa->FirstPrefix);
1500 prefix = aa->FirstPrefix;
1501 while (prefix)
1503 trace("\tLength: %u\n", S(U(*prefix)).Length);
1504 trace("\tFlags: 0x%08x\n", S(U(*prefix)).Flags);
1505 trace("\tNext: %p\n", prefix->Next);
1506 trace("\tAddress.lpSockaddr: %p\n", prefix->Address.lpSockaddr);
1507 trace("\tAddress.iSockaddrLength: %d\n", prefix->Address.iSockaddrLength);
1508 trace("\tPrefixLength: %u\n", prefix->PrefixLength);
1509 trace("\n");
1510 prefix = prefix->Next;
1513 if (S(U(*aa)).Length < sizeof(IP_ADAPTER_ADDRESSES_LH)) continue;
1514 trace("TransmitLinkSpeed: %s\n", debugstr_longlong(aa->TransmitLinkSpeed));
1515 trace("ReceiveLinkSpeed: %s\n", debugstr_longlong(aa->ReceiveLinkSpeed));
1516 trace("FirstWinsServerAddress:%p\n", aa->FirstWinsServerAddress);
1517 trace("FirstGatewayAddress: %p\n", aa->FirstGatewayAddress);
1518 trace("Ipv4Metric: %u\n", aa->Ipv4Metric);
1519 trace("Ipv6Metric: %u\n", aa->Ipv6Metric);
1520 trace("Luid: %p\n", &aa->Luid);
1521 trace("Dhcpv4Server: %p\n", &aa->Dhcpv4Server);
1522 trace("CompartmentId: %u\n", aa->CompartmentId);
1523 trace("NetworkGuid: %s\n", wine_dbgstr_guid((GUID*) &aa->NetworkGuid));
1524 trace("ConnectionType: %u\n", aa->ConnectionType);
1525 trace("TunnelType: %u\n", aa->TunnelType);
1526 trace("Dhcpv6Server: %p\n", &aa->Dhcpv6Server);
1527 trace("Dhcpv6ClientDuidLength:%u\n", aa->Dhcpv6ClientDuidLength);
1528 trace("Dhcpv6ClientDuid: %p\n", aa->Dhcpv6ClientDuid);
1529 trace("Dhcpv6Iaid: %u\n", aa->Dhcpv6Iaid);
1530 trace("FirstDnsSuffix: %p\n", aa->FirstDnsSuffix);
1531 trace("\n");
1533 if (pConvertInterfaceLuidToGuid)
1535 status = pConvertInterfaceLuidToGuid(&aa->Luid, &guid);
1536 ok(!status, "got %u\n", status);
1537 sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1538 guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1],
1539 guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5],
1540 guid.Data4[6], guid.Data4[7]);
1541 ok(!strcasecmp(aa->AdapterName, buf), "expected '%s' got '%s'\n", aa->AdapterName, buf);
1544 HeapFree(GetProcessHeap(), 0, ptr);
1547 static void test_GetExtendedTcpTable(void)
1549 DWORD ret, size;
1550 MIB_TCPTABLE *table;
1551 MIB_TCPTABLE_OWNER_PID *table_pid;
1552 MIB_TCPTABLE_OWNER_MODULE *table_module;
1554 if (!pGetExtendedTcpTable)
1556 win_skip("GetExtendedTcpTable not available\n");
1557 return;
1559 ret = pGetExtendedTcpTable( NULL, NULL, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1560 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1562 size = 0;
1563 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1564 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1566 table = HeapAlloc( GetProcessHeap(), 0, size );
1567 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_ALL, 0 );
1568 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1569 HeapFree( GetProcessHeap(), 0, table );
1571 size = 0;
1572 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1573 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1575 table = HeapAlloc( GetProcessHeap(), 0, size );
1576 ret = pGetExtendedTcpTable( table, &size, TRUE, AF_INET, TCP_TABLE_BASIC_LISTENER, 0 );
1577 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1578 HeapFree( GetProcessHeap(), 0, table );
1580 size = 0;
1581 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1582 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1584 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1585 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0 );
1586 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1587 HeapFree( GetProcessHeap(), 0, table_pid );
1589 size = 0;
1590 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1591 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1593 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1594 ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 );
1595 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1596 HeapFree( GetProcessHeap(), 0, table_pid );
1598 size = 0;
1599 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1600 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1602 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1603 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
1604 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1605 HeapFree( GetProcessHeap(), 0, table_module );
1607 size = 0;
1608 ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1609 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1611 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1612 ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 );
1613 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1614 HeapFree( GetProcessHeap(), 0, table_module );
1617 static void test_AllocateAndGetTcpExTableFromStack(void)
1619 DWORD ret;
1620 MIB_TCPTABLE_OWNER_PID *table_ex = NULL;
1622 if (!pAllocateAndGetTcpExTableFromStack)
1624 skip("AllocateAndGetTcpExTableFromStack not available\n");
1625 return;
1628 if (0)
1630 /* crashes on native */
1631 ret = pAllocateAndGetTcpExTableFromStack( NULL, FALSE, INVALID_HANDLE_VALUE, 0, 0 );
1632 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1633 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, INVALID_HANDLE_VALUE, 0, AF_INET );
1634 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1635 ret = pAllocateAndGetTcpExTableFromStack( NULL, FALSE, GetProcessHeap(), 0, AF_INET );
1636 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1639 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, GetProcessHeap(), 0, 0 );
1640 ok( ret == ERROR_INVALID_PARAMETER || broken(ret == ERROR_NOT_SUPPORTED) /* win2k */, "got %u\n", ret );
1642 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, GetProcessHeap(), 0, AF_INET );
1643 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1645 if (ret == NO_ERROR && winetest_debug > 1)
1647 DWORD i;
1648 trace( "AllocateAndGetTcpExTableFromStack table: %u entries\n", table_ex->dwNumEntries );
1649 for (i = 0; i < table_ex->dwNumEntries; i++)
1651 char remote_ip[16];
1653 strcpy(remote_ip, ntoa(table_ex->table[i].dwRemoteAddr));
1654 trace( "%u: local %s:%u remote %s:%u state %u pid %u\n", i,
1655 ntoa(table_ex->table[i].dwLocalAddr), ntohs(table_ex->table[i].dwLocalPort),
1656 remote_ip, ntohs(table_ex->table[i].dwRemotePort),
1657 U(table_ex->table[i]).dwState, table_ex->table[i].dwOwningPid );
1660 HeapFree(GetProcessHeap(), 0, table_ex);
1662 ret = pAllocateAndGetTcpExTableFromStack( (void **)&table_ex, FALSE, GetProcessHeap(), 0, AF_INET6 );
1663 ok( ret == ERROR_NOT_SUPPORTED, "got %u\n", ret );
1666 static void test_GetExtendedUdpTable(void)
1668 DWORD ret, size;
1669 MIB_UDPTABLE *table;
1670 MIB_UDPTABLE_OWNER_PID *table_pid;
1671 MIB_UDPTABLE_OWNER_MODULE *table_module;
1673 if (!pGetExtendedUdpTable)
1675 win_skip("GetExtendedUdpTable not available\n");
1676 return;
1678 ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1679 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1681 size = 0;
1682 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1683 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1685 table = HeapAlloc( GetProcessHeap(), 0, size );
1686 ret = pGetExtendedUdpTable( table, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 );
1687 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1688 HeapFree( GetProcessHeap(), 0, table );
1690 size = 0;
1691 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1692 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1694 table_pid = HeapAlloc( GetProcessHeap(), 0, size );
1695 ret = pGetExtendedUdpTable( table_pid, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 );
1696 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1697 HeapFree( GetProcessHeap(), 0, table_pid );
1699 size = 0;
1700 ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1701 ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret );
1703 table_module = HeapAlloc( GetProcessHeap(), 0, size );
1704 ret = pGetExtendedUdpTable( table_module, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
1705 ok( ret == ERROR_SUCCESS, "got %u\n", ret );
1706 HeapFree( GetProcessHeap(), 0, table_module );
1709 static void test_CreateSortedAddressPairs(void)
1711 SOCKADDR_IN6 dst[2];
1712 SOCKADDR_IN6_PAIR *pair;
1713 ULONG pair_count;
1714 DWORD ret;
1716 if (!pCreateSortedAddressPairs)
1718 win_skip( "CreateSortedAddressPairs not available\n" );
1719 return;
1722 memset( dst, 0, sizeof(dst) );
1723 dst[0].sin6_family = AF_INET6;
1724 dst[0].sin6_addr.u.Word[5] = 0xffff;
1725 dst[0].sin6_addr.u.Word[6] = 0x0808;
1726 dst[0].sin6_addr.u.Word[7] = 0x0808;
1728 pair_count = 0xdeadbeef;
1729 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, NULL, &pair_count );
1730 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1731 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
1733 pair = (SOCKADDR_IN6_PAIR *)0xdeadbeef;
1734 pair_count = 0xdeadbeef;
1735 ret = pCreateSortedAddressPairs( NULL, 0, NULL, 1, 0, &pair, &pair_count );
1736 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1737 ok( pair == (SOCKADDR_IN6_PAIR *)0xdeadbeef, "got %p\n", pair );
1738 ok( pair_count == 0xdeadbeef, "got %u\n", pair_count );
1740 pair = NULL;
1741 pair_count = 0xdeadbeef;
1742 ret = pCreateSortedAddressPairs( NULL, 0, dst, 1, 0, &pair, &pair_count );
1743 ok( ret == NO_ERROR, "got %u\n", ret );
1744 ok( pair != NULL, "pair not set\n" );
1745 ok( pair_count >= 1, "got %u\n", pair_count );
1746 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
1747 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
1748 pFreeMibTable( pair );
1750 dst[1].sin6_family = AF_INET6;
1751 dst[1].sin6_addr.u.Word[5] = 0xffff;
1752 dst[1].sin6_addr.u.Word[6] = 0x0404;
1753 dst[1].sin6_addr.u.Word[7] = 0x0808;
1755 pair = NULL;
1756 pair_count = 0xdeadbeef;
1757 ret = pCreateSortedAddressPairs( NULL, 0, dst, 2, 0, &pair, &pair_count );
1758 ok( ret == NO_ERROR, "got %u\n", ret );
1759 ok( pair != NULL, "pair not set\n" );
1760 ok( pair_count >= 2, "got %u\n", pair_count );
1761 ok( pair[0].SourceAddress != NULL, "src address not set\n" );
1762 ok( pair[0].DestinationAddress != NULL, "dst address not set\n" );
1763 ok( pair[1].SourceAddress != NULL, "src address not set\n" );
1764 ok( pair[1].DestinationAddress != NULL, "dst address not set\n" );
1765 pFreeMibTable( pair );
1768 static DWORD get_interface_index(void)
1770 DWORD size = 0, ret = 0;
1771 IP_ADAPTER_ADDRESSES *buf, *aa;
1773 if (pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ) != ERROR_BUFFER_OVERFLOW)
1774 return 0;
1776 buf = HeapAlloc( GetProcessHeap(), 0, size );
1777 pGetAdaptersAddresses( AF_UNSPEC, 0, NULL, buf, &size );
1778 for (aa = buf; aa; aa = aa->Next)
1780 if (aa->IfType == IF_TYPE_ETHERNET_CSMACD)
1782 ret = aa->IfIndex;
1783 break;
1786 HeapFree( GetProcessHeap(), 0, buf );
1787 return ret;
1790 static void test_interface_identifier_conversion(void)
1792 DWORD ret;
1793 NET_LUID luid;
1794 GUID guid;
1795 SIZE_T len;
1796 WCHAR nameW[IF_MAX_STRING_SIZE + 1];
1797 char nameA[IF_MAX_STRING_SIZE + 1];
1798 NET_IFINDEX index, index2;
1800 if (!pConvertInterfaceIndexToLuid)
1802 win_skip( "ConvertInterfaceIndexToLuid not available\n" );
1803 return;
1805 if (!(index = get_interface_index()))
1807 skip( "no suitable interface found\n" );
1808 return;
1811 /* ConvertInterfaceIndexToLuid */
1812 ret = pConvertInterfaceIndexToLuid( 0, NULL );
1813 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1815 memset( &luid, 0xff, sizeof(luid) );
1816 ret = pConvertInterfaceIndexToLuid( 0, &luid );
1817 ok( ret == ERROR_FILE_NOT_FOUND, "got %u\n", ret );
1818 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1819 ok( !luid.Info.NetLuidIndex, "got %u\n", luid.Info.NetLuidIndex );
1820 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
1822 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1823 ret = pConvertInterfaceIndexToLuid( index, &luid );
1824 ok( !ret, "got %u\n", ret );
1825 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1826 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1827 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1829 /* ConvertInterfaceLuidToIndex */
1830 ret = pConvertInterfaceLuidToIndex( NULL, NULL );
1831 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1833 ret = pConvertInterfaceLuidToIndex( NULL, &index );
1834 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1836 ret = pConvertInterfaceLuidToIndex( &luid, NULL );
1837 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1839 ret = pConvertInterfaceLuidToIndex( &luid, &index );
1840 ok( !ret, "got %u\n", ret );
1842 /* ConvertInterfaceLuidToGuid */
1843 ret = pConvertInterfaceLuidToGuid( NULL, NULL );
1844 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1846 memset( &guid, 0xff, sizeof(guid) );
1847 ret = pConvertInterfaceLuidToGuid( NULL, &guid );
1848 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1849 ok( guid.Data1 == 0xffffffff, "got %x\n", guid.Data1 );
1851 ret = pConvertInterfaceLuidToGuid( &luid, NULL );
1852 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1854 memset( &guid, 0, sizeof(guid) );
1855 ret = pConvertInterfaceLuidToGuid( &luid, &guid );
1856 ok( !ret, "got %u\n", ret );
1857 ok( guid.Data1, "got %x\n", guid.Data1 );
1859 /* ConvertInterfaceGuidToLuid */
1860 ret = pConvertInterfaceGuidToLuid( NULL, NULL );
1861 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1863 luid.Info.NetLuidIndex = 1;
1864 ret = pConvertInterfaceGuidToLuid( NULL, &luid );
1865 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1866 ok( luid.Info.NetLuidIndex == 1, "got %u\n", luid.Info.NetLuidIndex );
1868 ret = pConvertInterfaceGuidToLuid( &guid, NULL );
1869 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1871 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1872 ret = pConvertInterfaceGuidToLuid( &guid, &luid );
1873 ok( !ret, "got %u\n", ret );
1874 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1875 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1876 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1878 /* ConvertInterfaceLuidToNameW */
1879 ret = pConvertInterfaceLuidToNameW( NULL, NULL, 0 );
1880 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1882 ret = pConvertInterfaceLuidToNameW( &luid, NULL, 0 );
1883 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1885 ret = pConvertInterfaceLuidToNameW( NULL, nameW, 0 );
1886 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1888 ret = pConvertInterfaceLuidToNameW( &luid, nameW, 0 );
1889 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1891 nameW[0] = 0;
1892 len = sizeof(nameW)/sizeof(nameW[0]);
1893 ret = pConvertInterfaceLuidToNameW( &luid, nameW, len );
1894 ok( !ret, "got %u\n", ret );
1895 ok( nameW[0], "name not set\n" );
1897 /* ConvertInterfaceLuidToNameA */
1898 ret = pConvertInterfaceLuidToNameA( NULL, NULL, 0 );
1899 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1901 ret = pConvertInterfaceLuidToNameA( &luid, NULL, 0 );
1902 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1904 ret = pConvertInterfaceLuidToNameA( NULL, nameA, 0 );
1905 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1907 ret = pConvertInterfaceLuidToNameA( &luid, nameA, 0 );
1908 ok( ret == ERROR_NOT_ENOUGH_MEMORY, "got %u\n", ret );
1910 nameA[0] = 0;
1911 len = sizeof(nameA)/sizeof(nameA[0]);
1912 ret = pConvertInterfaceLuidToNameA( &luid, nameA, len );
1913 ok( !ret, "got %u\n", ret );
1914 ok( nameA[0], "name not set\n" );
1916 /* ConvertInterfaceNameToLuidW */
1917 ret = pConvertInterfaceNameToLuidW( NULL, NULL );
1918 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1920 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1921 ret = pConvertInterfaceNameToLuidW( NULL, &luid );
1922 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1923 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1924 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1925 ok( !luid.Info.IfType, "got %u\n", luid.Info.IfType );
1927 ret = pConvertInterfaceNameToLuidW( nameW, NULL );
1928 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1930 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1931 ret = pConvertInterfaceNameToLuidW( nameW, &luid );
1932 ok( !ret, "got %u\n", ret );
1933 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1934 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1935 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1937 /* ConvertInterfaceNameToLuidA */
1938 ret = pConvertInterfaceNameToLuidA( NULL, NULL );
1939 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1941 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1942 ret = pConvertInterfaceNameToLuidA( NULL, &luid );
1943 ok( ret == ERROR_INVALID_NAME, "got %u\n", ret );
1944 ok( luid.Info.Reserved == 0xdead, "reserved set\n" );
1945 ok( luid.Info.NetLuidIndex == 0xdead, "index set\n" );
1946 ok( luid.Info.IfType == 0xdead, "type set\n" );
1948 ret = pConvertInterfaceNameToLuidA( nameA, NULL );
1949 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1951 luid.Info.Reserved = luid.Info.NetLuidIndex = luid.Info.IfType = 0xdead;
1952 ret = pConvertInterfaceNameToLuidA( nameA, &luid );
1953 ok( !ret, "got %u\n", ret );
1954 ok( !luid.Info.Reserved, "got %x\n", luid.Info.Reserved );
1955 ok( luid.Info.NetLuidIndex != 0xdead, "index not set\n" );
1956 ok( luid.Info.IfType == IF_TYPE_ETHERNET_CSMACD, "got %u\n", luid.Info.IfType );
1958 /* if_nametoindex */
1959 if (pif_nametoindex)
1961 index2 = pif_nametoindex( NULL );
1962 ok( !index2, "Got unexpected index %u\n", index2 );
1963 index2 = pif_nametoindex( nameA );
1964 ok( index2 == index, "Got index %u for %s, expected %u\n", index2, nameA, index );
1965 /* Wargaming.net Game Center passes a GUID-like string. */
1966 index2 = pif_nametoindex( "{00000001-0000-0000-0000-000000000000}" );
1967 ok( !index2, "Got unexpected index %u\n", index2 );
1968 index2 = pif_nametoindex( wine_dbgstr_guid( &guid ) );
1969 ok( !index2, "Got unexpected index %u for input %s\n", index2, wine_dbgstr_guid( &guid ) );
1971 else
1973 skip("if_nametoindex not supported\n");
1977 static void test_GetIfEntry2(void)
1979 DWORD ret;
1980 MIB_IF_ROW2 row;
1981 NET_IFINDEX index;
1983 if (!pGetIfEntry2)
1985 win_skip( "GetIfEntry2 not available\n" );
1986 return;
1988 if (!(index = get_interface_index()))
1990 skip( "no suitable interface found\n" );
1991 return;
1994 ret = pGetIfEntry2( NULL );
1995 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
1997 memset( &row, 0, sizeof(row) );
1998 ret = pGetIfEntry2( &row );
1999 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
2001 memset( &row, 0, sizeof(row) );
2002 row.InterfaceIndex = index;
2003 ret = pGetIfEntry2( &row );
2004 ok( ret == NO_ERROR, "got %u\n", ret );
2005 ok( row.InterfaceIndex == index, "got %u\n", index );
2008 static void test_GetIfTable2(void)
2010 DWORD ret;
2011 MIB_IF_TABLE2 *table;
2013 if (!pGetIfTable2)
2015 win_skip( "GetIfTable2 not available\n" );
2016 return;
2019 table = NULL;
2020 ret = pGetIfTable2( &table );
2021 ok( ret == NO_ERROR, "got %u\n", ret );
2022 ok( table != NULL, "table not set\n" );
2023 pFreeMibTable( table );
2026 static void test_GetUnicastIpAddressEntry(void)
2028 IP_ADAPTER_ADDRESSES *aa, *ptr;
2029 MIB_UNICASTIPADDRESS_ROW row;
2030 DWORD ret, size;
2032 if (!pGetUnicastIpAddressEntry)
2034 win_skip( "GetUnicastIpAddressEntry not available\n" );
2035 return;
2038 ret = pGetUnicastIpAddressEntry( NULL );
2039 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
2041 memset( &row, 0, sizeof(row) );
2042 ret = pGetUnicastIpAddressEntry( &row );
2043 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
2045 memset( &row, 0, sizeof(row) );
2046 row.Address.Ipv4.sin_family = AF_INET;
2047 row.Address.Ipv4.sin_port = 0;
2048 row.Address.Ipv4.sin_addr.S_un.S_addr = 0x01020304;
2049 ret = pGetUnicastIpAddressEntry( &row );
2050 ok( ret == ERROR_FILE_NOT_FOUND, "got %u\n", ret );
2052 memset( &row, 0, sizeof(row) );
2053 row.InterfaceIndex = 123;
2054 ret = pGetUnicastIpAddressEntry( &row );
2055 todo_wine ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
2057 memset( &row, 0, sizeof(row) );
2058 row.InterfaceIndex = get_interface_index();
2059 row.Address.Ipv4.sin_family = AF_INET;
2060 row.Address.Ipv4.sin_port = 0;
2061 row.Address.Ipv4.sin_addr.S_un.S_addr = 0x01020304;
2062 ret = pGetUnicastIpAddressEntry( &row );
2063 ok( ret == ERROR_NOT_FOUND, "got %u\n", ret );
2065 memset( &row, 0, sizeof(row) );
2066 row.InterfaceIndex = 123;
2067 row.Address.Ipv4.sin_family = AF_INET;
2068 row.Address.Ipv4.sin_port = 0;
2069 row.Address.Ipv4.sin_addr.S_un.S_addr = 0x01020304;
2070 ret = pGetUnicastIpAddressEntry( &row );
2071 ok( ret == ERROR_FILE_NOT_FOUND, "got %u\n", ret );
2073 ret = pGetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_INTERFACES, NULL, NULL, &size);
2074 ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret);
2075 if (ret != ERROR_BUFFER_OVERFLOW) return;
2077 ptr = HeapAlloc(GetProcessHeap(), 0, size);
2078 ret = pGetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_INTERFACES, NULL, ptr, &size);
2079 ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
2081 for (aa = ptr; !ret && aa; aa = aa->Next)
2083 IP_ADAPTER_UNICAST_ADDRESS *ua;
2085 ua = aa->FirstUnicastAddress;
2086 while (ua)
2088 /* test with luid */
2089 memset( &row, 0, sizeof(row) );
2090 memcpy(&row.InterfaceLuid, &aa->Luid, sizeof(aa->Luid));
2091 memcpy(&row.Address, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
2092 ret = pGetUnicastIpAddressEntry( &row );
2093 ok( ret == NO_ERROR, "got %u\n", ret );
2095 /* test with index */
2096 memset( &row, 0, sizeof(row) );
2097 row.InterfaceIndex = S(U(*aa)).IfIndex;
2098 memcpy(&row.Address, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
2099 ret = pGetUnicastIpAddressEntry( &row );
2100 ok( ret == NO_ERROR, "got %u\n", ret );
2101 if (ret == NO_ERROR)
2103 ok(row.InterfaceLuid.Info.Reserved == aa->Luid.Info.Reserved, "Expected %d, got %d\n",
2104 aa->Luid.Info.Reserved, row.InterfaceLuid.Info.Reserved);
2105 ok(row.InterfaceLuid.Info.NetLuidIndex == aa->Luid.Info.NetLuidIndex, "Expected %d, got %d\n",
2106 aa->Luid.Info.NetLuidIndex, row.InterfaceLuid.Info.NetLuidIndex);
2107 ok(row.InterfaceLuid.Info.IfType == aa->Luid.Info.IfType, "Expected %d, got %d\n",
2108 aa->Luid.Info.IfType, row.InterfaceLuid.Info.IfType);
2109 ok(row.InterfaceIndex == S(U(*aa)).IfIndex, "Expected %d, got %d\n",
2110 S(U(*aa)).IfIndex, row.InterfaceIndex);
2111 ok(row.PrefixOrigin == ua->PrefixOrigin, "Expected %d, got %d\n",
2112 ua->PrefixOrigin, row.PrefixOrigin);
2113 ok(row.SuffixOrigin == ua->SuffixOrigin, "Expected %d, got %d\n",
2114 ua->SuffixOrigin, row.SuffixOrigin);
2115 ok(row.ValidLifetime == ua->ValidLifetime, "Expected %d, got %d\n",
2116 ua->ValidLifetime, row.ValidLifetime);
2117 ok(row.PreferredLifetime == ua->PreferredLifetime, "Expected %d, got %d\n",
2118 ua->PreferredLifetime, row.PreferredLifetime);
2119 ok(row.OnLinkPrefixLength == ua->OnLinkPrefixLength, "Expected %d, got %d\n",
2120 ua->OnLinkPrefixLength, row.OnLinkPrefixLength);
2121 ok(row.SkipAsSource == 0, "Expected 0, got %d\n", row.SkipAsSource);
2122 ok(row.DadState == ua->DadState, "Expected %d, got %d\n", ua->DadState, row.DadState);
2123 if (row.Address.si_family == AF_INET6)
2124 ok(row.ScopeId.Value == row.Address.Ipv6.sin6_scope_id, "Expected %d, got %d\n",
2125 row.Address.Ipv6.sin6_scope_id, row.ScopeId.Value);
2126 ok(row.CreationTimeStamp.QuadPart, "CreationTimeStamp is 0\n");
2128 ua = ua->Next;
2131 HeapFree(GetProcessHeap(), 0, ptr);
2134 static void test_GetUnicastIpAddressTable(void)
2136 MIB_UNICASTIPADDRESS_TABLE *table;
2137 DWORD ret;
2138 ULONG i;
2140 if (!pGetUnicastIpAddressTable)
2142 win_skip( "GetUnicastIpAddressTable not available\n" );
2143 return;
2146 ret = pGetUnicastIpAddressTable(AF_UNSPEC, NULL);
2147 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
2149 ret = pGetUnicastIpAddressTable(AF_BAN, &table);
2150 ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
2152 ret = pGetUnicastIpAddressTable(AF_INET, &table);
2153 ok( ret == NO_ERROR, "got %u\n", ret );
2154 trace("GetUnicastIpAddressTable(AF_INET): NumEntries %u\n", table->NumEntries);
2155 pFreeMibTable(table);
2157 ret = pGetUnicastIpAddressTable(AF_INET6, &table);
2158 ok( ret == NO_ERROR, "got %u\n", ret );
2159 trace("GetUnicastIpAddressTable(AF_INET6): NumEntries %u\n", table->NumEntries);
2160 pFreeMibTable(table);
2162 ret = pGetUnicastIpAddressTable(AF_UNSPEC, &table);
2163 ok( ret == NO_ERROR, "got %u\n", ret );
2164 trace("GetUnicastIpAddressTable(AF_UNSPEC): NumEntries %u\n", table->NumEntries);
2165 for (i = 0; i < table->NumEntries && winetest_debug > 1; i++)
2167 trace("Index %u:\n", i);
2168 trace("Address.si_family: %u\n", table->Table[i].Address.si_family);
2169 trace("InterfaceLuid.Info.Reserved: %u\n", table->Table[i].InterfaceLuid.Info.Reserved);
2170 trace("InterfaceLuid.Info.NetLuidIndex: %u\n", table->Table[i].InterfaceLuid.Info.NetLuidIndex);
2171 trace("InterfaceLuid.Info.IfType: %u\n", table->Table[i].InterfaceLuid.Info.IfType);
2172 trace("InterfaceIndex: %u\n", table->Table[i].InterfaceIndex);
2173 trace("PrefixOrigin: %u\n", table->Table[i].PrefixOrigin);
2174 trace("SuffixOrigin: %u\n", table->Table[i].SuffixOrigin);
2175 trace("ValidLifetime: %u seconds\n", table->Table[i].ValidLifetime);
2176 trace("PreferredLifetime: %u seconds\n", table->Table[i].PreferredLifetime);
2177 trace("OnLinkPrefixLength: %u\n", table->Table[i].OnLinkPrefixLength);
2178 trace("SkipAsSource: %u\n", table->Table[i].SkipAsSource);
2179 trace("DadState: %u\n", table->Table[i].DadState);
2180 trace("ScopeId.Value: %u\n", table->Table[i].ScopeId.Value);
2181 trace("CreationTimeStamp: %08x%08x\n", table->Table[i].CreationTimeStamp.HighPart, table->Table[i].CreationTimeStamp.LowPart);
2184 pFreeMibTable(table);
2187 START_TEST(iphlpapi)
2190 loadIPHlpApi();
2191 if (hLibrary) {
2192 HANDLE thread;
2194 testWin98OnlyFunctions();
2195 testWinNT4Functions();
2197 /* run testGetXXXX in two threads at once to make sure we don't crash in that case */
2198 thread = CreateThread(NULL, 0, testWin98Functions, NULL, 0, NULL);
2199 testWin98Functions(NULL);
2200 WaitForSingleObject(thread, INFINITE);
2202 testWin2KFunctions();
2203 test_GetAdaptersAddresses();
2204 test_GetExtendedTcpTable();
2205 test_GetExtendedUdpTable();
2206 test_AllocateAndGetTcpExTableFromStack();
2207 test_CreateSortedAddressPairs();
2208 test_interface_identifier_conversion();
2209 test_GetIfEntry2();
2210 test_GetIfTable2();
2211 test_GetUnicastIpAddressEntry();
2212 test_GetUnicastIpAddressTable();
2213 freeIPHlpApi();