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.
43 #include "wine/test.h"
47 static HMODULE hLibrary = NULL;
49 typedef DWORD (WINAPI *GetNumberOfInterfacesFunc)(PDWORD);
50 typedef DWORD (WINAPI *GetIpAddrTableFunc)(PMIB_IPADDRTABLE,PULONG,BOOL);
51 typedef DWORD (WINAPI *GetIfEntryFunc)(PMIB_IFROW);
52 typedef DWORD (WINAPI *GetFriendlyIfIndexFunc)(DWORD);
53 typedef DWORD (WINAPI *GetIfTableFunc)(PMIB_IFTABLE,PULONG,BOOL);
54 typedef DWORD (WINAPI *GetIpForwardTableFunc)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
55 typedef DWORD (WINAPI *GetIpNetTableFunc)(PMIB_IPNETTABLE,PULONG,BOOL);
56 typedef DWORD (WINAPI *GetInterfaceInfoFunc)(PIP_INTERFACE_INFO,PULONG);
57 typedef DWORD (WINAPI *GetAdaptersInfoFunc)(PIP_ADAPTER_INFO,PULONG);
58 typedef DWORD (WINAPI *GetNetworkParamsFunc)(PFIXED_INFO,PULONG);
59 typedef DWORD (WINAPI *GetIcmpStatisticsFunc)(PMIB_ICMP);
60 typedef DWORD (WINAPI *GetIpStatisticsFunc)(PMIB_IPSTATS);
61 typedef DWORD (WINAPI *GetTcpStatisticsFunc)(PMIB_TCPSTATS);
62 typedef DWORD (WINAPI *GetUdpStatisticsFunc)(PMIB_UDPSTATS);
63 typedef DWORD (WINAPI *GetTcpTableFunc)(PMIB_TCPTABLE,PDWORD,BOOL);
64 typedef DWORD (WINAPI *GetUdpTableFunc)(PMIB_UDPTABLE,PDWORD,BOOL);
65 typedef DWORD (WINAPI *GetPerAdapterInfoFunc)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
67 static GetNumberOfInterfacesFunc gGetNumberOfInterfaces = NULL;
68 static GetIpAddrTableFunc gGetIpAddrTable = NULL;
69 static GetIfEntryFunc gGetIfEntry = NULL;
70 static GetFriendlyIfIndexFunc gGetFriendlyIfIndex = NULL;
71 static GetIfTableFunc gGetIfTable = NULL;
72 static GetIpForwardTableFunc gGetIpForwardTable = NULL;
73 static GetIpNetTableFunc gGetIpNetTable = NULL;
74 static GetInterfaceInfoFunc gGetInterfaceInfo = NULL;
75 static GetAdaptersInfoFunc gGetAdaptersInfo = NULL;
76 static GetNetworkParamsFunc gGetNetworkParams = NULL;
77 static GetIcmpStatisticsFunc gGetIcmpStatistics = NULL;
78 static GetIpStatisticsFunc gGetIpStatistics = NULL;
79 static GetTcpStatisticsFunc gGetTcpStatistics = NULL;
80 static GetUdpStatisticsFunc gGetUdpStatistics = NULL;
81 static GetTcpTableFunc gGetTcpTable = NULL;
82 static GetUdpTableFunc gGetUdpTable = NULL;
83 static GetPerAdapterInfoFunc gGetPerAdapterInfo = NULL;
85 static void loadIPHlpApi(void)
87 hLibrary = LoadLibraryA("iphlpapi.dll");
89 gGetNumberOfInterfaces = (GetNumberOfInterfacesFunc)GetProcAddress(
90 hLibrary, "GetNumberOfInterfaces");
91 gGetIpAddrTable = (GetIpAddrTableFunc)GetProcAddress(
92 hLibrary, "GetIpAddrTable");
93 gGetIfEntry = (GetIfEntryFunc)GetProcAddress(
94 hLibrary, "GetIfEntry");
95 gGetFriendlyIfIndex = (GetFriendlyIfIndexFunc)GetProcAddress(
96 hLibrary, "GetFriendlyIfIndex");
97 gGetIfTable = (GetIfTableFunc)GetProcAddress(
98 hLibrary, "GetIfTable");
99 gGetIpForwardTable = (GetIpForwardTableFunc)GetProcAddress(
100 hLibrary, "GetIpForwardTable");
101 gGetIpNetTable = (GetIpNetTableFunc)GetProcAddress(
102 hLibrary, "GetIpNetTable");
103 gGetInterfaceInfo = (GetInterfaceInfoFunc)GetProcAddress(
104 hLibrary, "GetInterfaceInfo");
105 gGetAdaptersInfo = (GetAdaptersInfoFunc)GetProcAddress(
106 hLibrary, "GetAdaptersInfo");
107 gGetNetworkParams = (GetNetworkParamsFunc)GetProcAddress(
108 hLibrary, "GetNetworkParams");
109 gGetIcmpStatistics = (GetIcmpStatisticsFunc)GetProcAddress(
110 hLibrary, "GetIcmpStatistics");
111 gGetIpStatistics = (GetIpStatisticsFunc)GetProcAddress(
112 hLibrary, "GetIpStatistics");
113 gGetTcpStatistics = (GetTcpStatisticsFunc)GetProcAddress(
114 hLibrary, "GetTcpStatistics");
115 gGetUdpStatistics = (GetUdpStatisticsFunc)GetProcAddress(
116 hLibrary, "GetUdpStatistics");
117 gGetTcpTable = (GetTcpTableFunc)GetProcAddress(
118 hLibrary, "GetTcpTable");
119 gGetUdpTable = (GetUdpTableFunc)GetProcAddress(
120 hLibrary, "GetUdpTable");
121 gGetPerAdapterInfo = (GetPerAdapterInfoFunc)GetProcAddress(hLibrary, "GetPerAdapterInfo");
125 static void freeIPHlpApi(void)
128 gGetNumberOfInterfaces = NULL;
129 gGetIpAddrTable = NULL;
131 gGetFriendlyIfIndex = NULL;
133 gGetIpForwardTable = NULL;
134 gGetIpNetTable = NULL;
135 gGetInterfaceInfo = NULL;
136 gGetAdaptersInfo = NULL;
137 gGetNetworkParams = NULL;
138 gGetIcmpStatistics = NULL;
139 gGetIpStatistics = NULL;
140 gGetTcpStatistics = NULL;
141 gGetUdpStatistics = NULL;
144 FreeLibrary(hLibrary);
149 /* replacement for inet_ntoa */
150 static const char *ntoa( DWORD ip )
152 static char buffer[40];
155 sprintf( buffer, "%u.%u.%u.%u", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff );
160 still-to-be-tested 98-only functions:
161 GetUniDirectionalAdapterInfo
163 static void testWin98OnlyFunctions(void)
167 static void testGetNumberOfInterfaces(void)
169 if (gGetNumberOfInterfaces) {
170 DWORD apiReturn, numInterfaces;
172 /* Crashes on Vista */
174 apiReturn = gGetNumberOfInterfaces(NULL), numInterfaces;
175 if (apiReturn == ERROR_NOT_SUPPORTED)
177 ok(apiReturn == ERROR_INVALID_PARAMETER,
178 "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
182 apiReturn = gGetNumberOfInterfaces(&numInterfaces);
183 if (apiReturn == ERROR_NOT_SUPPORTED) {
184 skip("GetNumberOfInterfaces is not supported\n");
187 ok(apiReturn == NO_ERROR,
188 "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn);
192 static void testGetIfEntry(DWORD index)
198 memset(&row, 0, sizeof(row));
199 apiReturn = gGetIfEntry(NULL);
200 if (apiReturn == ERROR_NOT_SUPPORTED) {
201 skip("GetIfEntry is not supported\n");
204 ok(apiReturn == ERROR_INVALID_PARAMETER,
205 "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
207 row.dwIndex = -1; /* hope that's always bogus! */
208 apiReturn = gGetIfEntry(&row);
209 ok(apiReturn == ERROR_INVALID_DATA ||
210 apiReturn == ERROR_FILE_NOT_FOUND /* Vista */,
211 "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
214 apiReturn = gGetIfEntry(&row);
215 ok(apiReturn == NO_ERROR,
216 "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn);
220 static void testGetIpAddrTable(void)
222 if (gGetIpAddrTable) {
226 apiReturn = gGetIpAddrTable(NULL, NULL, FALSE);
227 if (apiReturn == ERROR_NOT_SUPPORTED) {
228 skip("GetIpAddrTable is not supported\n");
231 ok(apiReturn == ERROR_INVALID_PARAMETER,
232 "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
234 apiReturn = gGetIpAddrTable(NULL, &dwSize, FALSE);
235 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
236 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
238 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
239 PMIB_IPADDRTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
241 apiReturn = gGetIpAddrTable(buf, &dwSize, FALSE);
242 ok(apiReturn == NO_ERROR,
243 "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
245 if (apiReturn == NO_ERROR && buf->dwNumEntries)
246 testGetIfEntry(buf->table[0].dwIndex);
247 HeapFree(GetProcessHeap(), 0, buf);
252 static void testGetIfTable(void)
258 apiReturn = gGetIfTable(NULL, NULL, FALSE);
259 if (apiReturn == ERROR_NOT_SUPPORTED) {
260 skip("GetIfTable is not supported\n");
263 ok(apiReturn == ERROR_INVALID_PARAMETER,
264 "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
266 apiReturn = gGetIfTable(NULL, &dwSize, FALSE);
267 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
268 "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
270 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
271 PMIB_IFTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
273 apiReturn = gGetIfTable(buf, &dwSize, FALSE);
274 ok(apiReturn == NO_ERROR,
275 "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
278 if (apiReturn == NO_ERROR && winetest_debug > 1)
281 char name[MAX_INTERFACE_NAME_LEN];
283 trace( "interface table: %u entries\n", buf->dwNumEntries );
284 for (i = 0; i < buf->dwNumEntries; i++)
286 MIB_IFROW *row = &buf->table[i];
287 WideCharToMultiByte( CP_ACP, 0, row->wszName, -1, name, MAX_INTERFACE_NAME_LEN, NULL, NULL );
288 trace( "%u: '%s' type %u mtu %u speed %u phys",
289 row->dwIndex, name, row->dwType, row->dwMtu, row->dwSpeed );
290 for (j = 0; j < row->dwPhysAddrLen; j++)
291 printf( " %02x", row->bPhysAddr[j] );
293 trace( " in: bytes %u upkts %u nupkts %u disc %u err %u unk %u\n",
294 row->dwInOctets, row->dwInUcastPkts, row->dwInNUcastPkts,
295 row->dwInDiscards, row->dwInErrors, row->dwInUnknownProtos );
296 trace( " out: bytes %u upkts %u nupkts %u disc %u err %u\n",
297 row->dwOutOctets, row->dwOutUcastPkts, row->dwOutNUcastPkts,
298 row->dwOutDiscards, row->dwOutErrors );
301 HeapFree(GetProcessHeap(), 0, buf);
306 static void testGetIpForwardTable(void)
308 if (gGetIpForwardTable) {
312 apiReturn = gGetIpForwardTable(NULL, NULL, FALSE);
313 if (apiReturn == ERROR_NOT_SUPPORTED) {
314 skip("GetIpForwardTable is not supported\n");
317 ok(apiReturn == ERROR_INVALID_PARAMETER,
318 "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
320 apiReturn = gGetIpForwardTable(NULL, &dwSize, FALSE);
321 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
322 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
324 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
325 PMIB_IPFORWARDTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
327 apiReturn = gGetIpForwardTable(buf, &dwSize, FALSE);
328 ok(apiReturn == NO_ERROR,
329 "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
332 if (apiReturn == NO_ERROR && winetest_debug > 1)
336 trace( "IP forward table: %u entries\n", buf->dwNumEntries );
337 for (i = 0; i < buf->dwNumEntries; i++)
340 sprintf( buffer, "dest %s", ntoa( buf->table[i].dwForwardDest ));
341 sprintf( buffer + strlen(buffer), " mask %s", ntoa( buf->table[i].dwForwardMask ));
342 trace( "%u: %s gw %s if %u type %u\n", i, buffer,
343 ntoa( buf->table[i].dwForwardNextHop ),
344 buf->table[i].dwForwardIfIndex, buf->table[i].dwForwardType );
347 HeapFree(GetProcessHeap(), 0, buf);
352 static void testGetIpNetTable(void)
354 if (gGetIpNetTable) {
358 apiReturn = gGetIpNetTable(NULL, NULL, FALSE);
359 if (apiReturn == ERROR_NOT_SUPPORTED) {
360 skip("GetIpNetTable is not supported\n");
363 ok(apiReturn == ERROR_INVALID_PARAMETER,
364 "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
366 apiReturn = gGetIpNetTable(NULL, &dwSize, FALSE);
367 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
368 "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
370 if (apiReturn == ERROR_NO_DATA)
371 ; /* empty ARP table's okay */
372 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
373 PMIB_IPNETTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
375 apiReturn = gGetIpNetTable(buf, &dwSize, FALSE);
376 ok(apiReturn == NO_ERROR ||
377 apiReturn == ERROR_NO_DATA, /* empty ARP table's okay */
378 "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
381 if (apiReturn == NO_ERROR && winetest_debug > 1)
385 trace( "IP net table: %u entries\n", buf->dwNumEntries );
386 for (i = 0; i < buf->dwNumEntries; i++)
388 trace( "%u: idx %u type %u addr %s phys",
389 i, buf->table[i].dwIndex, buf->table[i].dwType, ntoa( buf->table[i].dwAddr ));
390 for (j = 0; j < buf->table[i].dwPhysAddrLen; j++)
391 printf( " %02x", buf->table[i].bPhysAddr[j] );
395 HeapFree(GetProcessHeap(), 0, buf);
400 static void testGetIcmpStatistics(void)
402 if (gGetIcmpStatistics) {
406 /* Crashes on Vista */
408 apiReturn = gGetIcmpStatistics(NULL);
409 if (apiReturn == ERROR_NOT_SUPPORTED)
411 ok(apiReturn == ERROR_INVALID_PARAMETER,
412 "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
416 apiReturn = gGetIcmpStatistics(&stats);
417 if (apiReturn == ERROR_NOT_SUPPORTED)
419 skip("GetIcmpStatistics is not supported\n");
422 ok(apiReturn == NO_ERROR,
423 "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn);
424 if (apiReturn == NO_ERROR && winetest_debug > 1)
426 trace( "ICMP stats: %8s %8s\n", "in", "out" );
427 trace( " dwMsgs: %8u %8u\n", stats.stats.icmpInStats.dwMsgs, stats.stats.icmpOutStats.dwMsgs );
428 trace( " dwErrors: %8u %8u\n", stats.stats.icmpInStats.dwErrors, stats.stats.icmpOutStats.dwErrors );
429 trace( " dwDestUnreachs: %8u %8u\n", stats.stats.icmpInStats.dwDestUnreachs, stats.stats.icmpOutStats.dwDestUnreachs );
430 trace( " dwTimeExcds: %8u %8u\n", stats.stats.icmpInStats.dwTimeExcds, stats.stats.icmpOutStats.dwTimeExcds );
431 trace( " dwParmProbs: %8u %8u\n", stats.stats.icmpInStats.dwParmProbs, stats.stats.icmpOutStats.dwParmProbs );
432 trace( " dwSrcQuenchs: %8u %8u\n", stats.stats.icmpInStats.dwSrcQuenchs, stats.stats.icmpOutStats.dwSrcQuenchs );
433 trace( " dwRedirects: %8u %8u\n", stats.stats.icmpInStats.dwRedirects, stats.stats.icmpOutStats.dwRedirects );
434 trace( " dwEchos: %8u %8u\n", stats.stats.icmpInStats.dwEchos, stats.stats.icmpOutStats.dwEchos );
435 trace( " dwEchoReps: %8u %8u\n", stats.stats.icmpInStats.dwEchoReps, stats.stats.icmpOutStats.dwEchoReps );
436 trace( " dwTimestamps: %8u %8u\n", stats.stats.icmpInStats.dwTimestamps, stats.stats.icmpOutStats.dwTimestamps );
437 trace( " dwTimestampReps: %8u %8u\n", stats.stats.icmpInStats.dwTimestampReps, stats.stats.icmpOutStats.dwTimestampReps );
438 trace( " dwAddrMasks: %8u %8u\n", stats.stats.icmpInStats.dwAddrMasks, stats.stats.icmpOutStats.dwAddrMasks );
439 trace( " dwAddrMaskReps: %8u %8u\n", stats.stats.icmpInStats.dwAddrMaskReps, stats.stats.icmpOutStats.dwAddrMaskReps );
444 static void testGetIpStatistics(void)
446 if (gGetIpStatistics) {
450 apiReturn = gGetIpStatistics(NULL);
451 if (apiReturn == ERROR_NOT_SUPPORTED) {
452 skip("GetIpStatistics is not supported\n");
455 ok(apiReturn == ERROR_INVALID_PARAMETER,
456 "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
458 apiReturn = gGetIpStatistics(&stats);
459 ok(apiReturn == NO_ERROR,
460 "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn);
461 if (apiReturn == NO_ERROR && winetest_debug > 1)
463 trace( "IP stats:\n" );
464 trace( " dwForwarding: %u\n", stats.dwForwarding );
465 trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
466 trace( " dwInReceives: %u\n", stats.dwInReceives );
467 trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
468 trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
469 trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
470 trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
471 trace( " dwInDiscards: %u\n", stats.dwInDiscards );
472 trace( " dwInDelivers: %u\n", stats.dwInDelivers );
473 trace( " dwOutRequests: %u\n", stats.dwOutRequests );
474 trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
475 trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
476 trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
477 trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
478 trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
479 trace( " dwReasmOks: %u\n", stats.dwReasmOks );
480 trace( " dwReasmFails: %u\n", stats.dwReasmFails );
481 trace( " dwFragOks: %u\n", stats.dwFragOks );
482 trace( " dwFragFails: %u\n", stats.dwFragFails );
483 trace( " dwFragCreates: %u\n", stats.dwFragCreates );
484 trace( " dwNumIf: %u\n", stats.dwNumIf );
485 trace( " dwNumAddr: %u\n", stats.dwNumAddr );
486 trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
491 static void testGetTcpStatistics(void)
493 if (gGetTcpStatistics) {
497 apiReturn = gGetTcpStatistics(NULL);
498 if (apiReturn == ERROR_NOT_SUPPORTED) {
499 skip("GetTcpStatistics is not supported\n");
502 ok(apiReturn == ERROR_INVALID_PARAMETER,
503 "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
505 apiReturn = gGetTcpStatistics(&stats);
506 ok(apiReturn == NO_ERROR,
507 "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn);
508 if (apiReturn == NO_ERROR && winetest_debug > 1)
510 trace( "TCP stats:\n" );
511 trace( " dwRtoAlgorithm: %u\n", stats.dwRtoAlgorithm );
512 trace( " dwRtoMin: %u\n", stats.dwRtoMin );
513 trace( " dwRtoMax: %u\n", stats.dwRtoMax );
514 trace( " dwMaxConn: %u\n", stats.dwMaxConn );
515 trace( " dwActiveOpens: %u\n", stats.dwActiveOpens );
516 trace( " dwPassiveOpens: %u\n", stats.dwPassiveOpens );
517 trace( " dwAttemptFails: %u\n", stats.dwAttemptFails );
518 trace( " dwEstabResets: %u\n", stats.dwEstabResets );
519 trace( " dwCurrEstab: %u\n", stats.dwCurrEstab );
520 trace( " dwInSegs: %u\n", stats.dwInSegs );
521 trace( " dwOutSegs: %u\n", stats.dwOutSegs );
522 trace( " dwRetransSegs: %u\n", stats.dwRetransSegs );
523 trace( " dwInErrs: %u\n", stats.dwInErrs );
524 trace( " dwOutRsts: %u\n", stats.dwOutRsts );
525 trace( " dwNumConns: %u\n", stats.dwNumConns );
530 static void testGetUdpStatistics(void)
532 if (gGetUdpStatistics) {
536 apiReturn = gGetUdpStatistics(NULL);
537 if (apiReturn == ERROR_NOT_SUPPORTED) {
538 skip("GetUdpStatistics is not supported\n");
541 ok(apiReturn == ERROR_INVALID_PARAMETER,
542 "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
544 apiReturn = gGetUdpStatistics(&stats);
545 ok(apiReturn == NO_ERROR,
546 "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn);
547 if (apiReturn == NO_ERROR && winetest_debug > 1)
549 trace( "UDP stats:\n" );
550 trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
551 trace( " dwNoPorts: %u\n", stats.dwNoPorts );
552 trace( " dwInErrors: %u\n", stats.dwInErrors );
553 trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
554 trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
559 static void testGetTcpTable(void)
565 apiReturn = gGetTcpTable(NULL, &dwSize, FALSE);
566 if (apiReturn == ERROR_NOT_SUPPORTED) {
567 skip("GetTcpTable is not supported\n");
570 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER ||
571 broken(apiReturn == ERROR_NO_DATA), /* win95 */
572 "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
574 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
575 PMIB_TCPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
577 apiReturn = gGetTcpTable(buf, &dwSize, FALSE);
578 ok(apiReturn == NO_ERROR,
579 "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
582 if (apiReturn == NO_ERROR && winetest_debug > 1)
585 trace( "TCP table: %u entries\n", buf->dwNumEntries );
586 for (i = 0; i < buf->dwNumEntries; i++)
589 sprintf( buffer, "local %s:%u",
590 ntoa(buf->table[i].dwLocalAddr), ntohs(buf->table[i].dwLocalPort) );
591 trace( "%u: %s remote %s:%u state %u\n",
592 i, buffer, ntoa( buf->table[i].dwRemoteAddr ),
593 ntohs(buf->table[i].dwRemotePort), buf->table[i].dwState );
596 HeapFree(GetProcessHeap(), 0, buf);
601 static void testGetUdpTable(void)
607 apiReturn = gGetUdpTable(NULL, &dwSize, FALSE);
608 if (apiReturn == ERROR_NOT_SUPPORTED) {
609 skip("GetUdpTable is not supported\n");
612 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
613 "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
615 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
616 PMIB_UDPTABLE buf = HeapAlloc(GetProcessHeap(), 0, dwSize);
618 apiReturn = gGetUdpTable(buf, &dwSize, FALSE);
619 ok(apiReturn == NO_ERROR,
620 "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
623 if (apiReturn == NO_ERROR && winetest_debug > 1)
626 trace( "UDP table: %u entries\n", buf->dwNumEntries );
627 for (i = 0; i < buf->dwNumEntries; i++)
628 trace( "%u: %s:%u\n",
629 i, ntoa( buf->table[i].dwLocalAddr ), ntohs(buf->table[i].dwLocalPort) );
631 HeapFree(GetProcessHeap(), 0, buf);
637 still-to-be-tested NT4-onward functions:
651 static void testWinNT4Functions(void)
653 testGetNumberOfInterfaces();
654 testGetIpAddrTable();
656 testGetIpForwardTable();
658 testGetIcmpStatistics();
659 testGetIpStatistics();
660 testGetTcpStatistics();
661 testGetUdpStatistics();
666 static void testGetInterfaceInfo(void)
668 if (gGetInterfaceInfo) {
672 apiReturn = gGetInterfaceInfo(NULL, NULL);
673 if (apiReturn == ERROR_NOT_SUPPORTED) {
674 skip("GetInterfaceInfo is not supported\n");
677 ok(apiReturn == ERROR_INVALID_PARAMETER,
678 "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
680 apiReturn = gGetInterfaceInfo(NULL, &len);
681 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
682 "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
684 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
685 PIP_INTERFACE_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
687 apiReturn = gGetInterfaceInfo(buf, &len);
688 ok(apiReturn == NO_ERROR,
689 "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
691 HeapFree(GetProcessHeap(), 0, buf);
696 static void testGetAdaptersInfo(void)
698 if (gGetAdaptersInfo) {
702 apiReturn = gGetAdaptersInfo(NULL, NULL);
703 if (apiReturn == ERROR_NOT_SUPPORTED) {
704 skip("GetAdaptersInfo is not supported\n");
707 ok(apiReturn == ERROR_INVALID_PARAMETER,
708 "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
710 apiReturn = gGetAdaptersInfo(NULL, &len);
711 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
712 "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
714 if (apiReturn == ERROR_NO_DATA)
715 ; /* no adapter's, that's okay */
716 else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
717 PIP_ADAPTER_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
719 apiReturn = gGetAdaptersInfo(buf, &len);
720 ok(apiReturn == NO_ERROR,
721 "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
723 HeapFree(GetProcessHeap(), 0, buf);
728 static void testGetNetworkParams(void)
730 if (gGetNetworkParams) {
734 apiReturn = gGetNetworkParams(NULL, NULL);
735 if (apiReturn == ERROR_NOT_SUPPORTED) {
736 skip("GetNetworkParams is not supported\n");
739 ok(apiReturn == ERROR_INVALID_PARAMETER,
740 "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
742 apiReturn = gGetNetworkParams(NULL, &len);
743 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
744 "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
746 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
747 PFIXED_INFO buf = HeapAlloc(GetProcessHeap(), 0, len);
749 apiReturn = gGetNetworkParams(buf, &len);
750 ok(apiReturn == NO_ERROR,
751 "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
753 HeapFree(GetProcessHeap(), 0, buf);
759 still-to-be-tested 98-onward functions:
765 static void testWin98Functions(void)
767 testGetInterfaceInfo();
768 testGetAdaptersInfo();
769 testGetNetworkParams();
772 static void testGetPerAdapterInfo(void)
777 if (!gGetPerAdapterInfo) return;
778 ret = gGetPerAdapterInfo(1, NULL, NULL);
779 if (ret == ERROR_NOT_SUPPORTED) {
780 skip("GetPerAdapterInfo is not supported\n");
783 ok( ret == ERROR_INVALID_PARAMETER, "got %u instead of ERROR_INVALID_PARAMETER\n", ret );
785 ret = gGetPerAdapterInfo(1, NULL, &needed);
786 if (ret == ERROR_NO_DATA) return; /* no such adapter */
787 ok( ret == ERROR_BUFFER_OVERFLOW, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret );
788 ok( needed != 0xdeadbeef, "needed not set\n" );
789 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
790 ret = gGetPerAdapterInfo(1, buffer, &needed);
791 ok( ret == NO_ERROR, "got %u instead of NO_ERROR\n", ret );
792 HeapFree( GetProcessHeap(), 0, buffer );
796 still-to-be-tested 2K-onward functions:
809 static void testWin2KFunctions(void)
811 testGetPerAdapterInfo();
819 testWin98OnlyFunctions();
820 testWinNT4Functions();
821 testWin98Functions();
822 testWin2KFunctions();