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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
42 #include "wine/test.h"
43 #include <sys/types.h>
45 #include <sys/socket.h>
50 static HMODULE hLibrary = NULL;
52 typedef DWORD (WINAPI *GetNumberOfInterfacesFunc)(PDWORD);
53 typedef DWORD (WINAPI *GetIpAddrTableFunc)(PMIB_IPADDRTABLE,PULONG,BOOL);
54 typedef DWORD (WINAPI *GetIfEntryFunc)(PMIB_IFROW);
55 typedef DWORD (WINAPI *GetFriendlyIfIndexFunc)(DWORD);
56 typedef DWORD (WINAPI *GetIfTableFunc)(PMIB_IFTABLE,PULONG,BOOL);
57 typedef DWORD (WINAPI *GetIpForwardTableFunc)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
58 typedef DWORD (WINAPI *GetIpNetTableFunc)(PMIB_IPNETTABLE,PULONG,BOOL);
59 typedef DWORD (WINAPI *GetInterfaceInfoFunc)(PIP_INTERFACE_INFO,PULONG);
60 typedef DWORD (WINAPI *GetAdaptersInfoFunc)(PIP_ADAPTER_INFO,PULONG);
61 typedef DWORD (WINAPI *GetNetworkParamsFunc)(PFIXED_INFO,PULONG);
62 typedef DWORD (WINAPI *GetIcmpStatisticsFunc)(PMIB_ICMP);
63 typedef DWORD (WINAPI *GetIpStatisticsFunc)(PMIB_IPSTATS);
64 typedef DWORD (WINAPI *GetTcpStatisticsFunc)(PMIB_TCPSTATS);
65 typedef DWORD (WINAPI *GetUdpStatisticsFunc)(PMIB_UDPSTATS);
66 typedef DWORD (WINAPI *GetTcpTableFunc)(PMIB_TCPTABLE,PDWORD,BOOL);
67 typedef DWORD (WINAPI *GetUdpTableFunc)(PMIB_UDPTABLE,PDWORD,BOOL);
69 static GetNumberOfInterfacesFunc gGetNumberOfInterfaces = NULL;
70 static GetIpAddrTableFunc gGetIpAddrTable = NULL;
71 static GetIfEntryFunc gGetIfEntry = NULL;
72 static GetFriendlyIfIndexFunc gGetFriendlyIfIndex = NULL;
73 static GetIfTableFunc gGetIfTable = NULL;
74 static GetIpForwardTableFunc gGetIpForwardTable = NULL;
75 static GetIpNetTableFunc gGetIpNetTable = NULL;
76 static GetInterfaceInfoFunc gGetInterfaceInfo = NULL;
77 static GetAdaptersInfoFunc gGetAdaptersInfo = NULL;
78 static GetNetworkParamsFunc gGetNetworkParams = NULL;
79 static GetIcmpStatisticsFunc gGetIcmpStatistics = NULL;
80 static GetIpStatisticsFunc gGetIpStatistics = NULL;
81 static GetTcpStatisticsFunc gGetTcpStatistics = NULL;
82 static GetUdpStatisticsFunc gGetUdpStatistics = NULL;
83 static GetTcpTableFunc gGetTcpTable = NULL;
84 static GetUdpTableFunc gGetUdpTable = NULL;
86 static void loadIPHlpApi(void)
88 hLibrary = LoadLibraryA("iphlpapi.dll");
90 gGetNumberOfInterfaces = (GetNumberOfInterfacesFunc)GetProcAddress(
91 hLibrary, "GetNumberOfInterfaces");
92 gGetIpAddrTable = (GetIpAddrTableFunc)GetProcAddress(
93 hLibrary, "GetIpAddrTable");
94 gGetIfEntry = (GetIfEntryFunc)GetProcAddress(
95 hLibrary, "GetIfEntry");
96 gGetFriendlyIfIndex = (GetFriendlyIfIndexFunc)GetProcAddress(
97 hLibrary, "GetFriendlyIfIndex");
98 gGetIfTable = (GetIfTableFunc)GetProcAddress(
99 hLibrary, "GetIfTable");
100 gGetIpForwardTable = (GetIpForwardTableFunc)GetProcAddress(
101 hLibrary, "GetIpForwardTable");
102 gGetIpNetTable = (GetIpNetTableFunc)GetProcAddress(
103 hLibrary, "GetIpNetTable");
104 gGetInterfaceInfo = (GetInterfaceInfoFunc)GetProcAddress(
105 hLibrary, "GetInterfaceInfo");
106 gGetAdaptersInfo = (GetAdaptersInfoFunc)GetProcAddress(
107 hLibrary, "GetAdaptersInfo");
108 gGetNetworkParams = (GetNetworkParamsFunc)GetProcAddress(
109 hLibrary, "GetNetworkParams");
110 gGetIcmpStatistics = (GetIcmpStatisticsFunc)GetProcAddress(
111 hLibrary, "GetIcmpStatistics");
112 gGetIpStatistics = (GetIpStatisticsFunc)GetProcAddress(
113 hLibrary, "GetIpStatistics");
114 gGetTcpStatistics = (GetTcpStatisticsFunc)GetProcAddress(
115 hLibrary, "GetTcpStatistics");
116 gGetUdpStatistics = (GetUdpStatisticsFunc)GetProcAddress(
117 hLibrary, "GetUdpStatistics");
118 gGetTcpTable = (GetTcpTableFunc)GetProcAddress(
119 hLibrary, "GetTcpTable");
120 gGetUdpTable = (GetUdpTableFunc)GetProcAddress(
121 hLibrary, "GetUdpTable");
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);
150 still-to-be-tested 98-only functions:
151 GetUniDirectionalAdapterInfo
153 void testWin98OnlyFunctions(void)
157 static void testGetNumberOfInterfaces(void)
159 if (gGetNumberOfInterfaces) {
160 DWORD apiReturn = gGetNumberOfInterfaces(NULL), numInterfaces;
162 if (apiReturn == ERROR_NOT_SUPPORTED)
164 ok(apiReturn == ERROR_INVALID_PARAMETER,
165 "GetNumberOfInterfaces(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
167 apiReturn = gGetNumberOfInterfaces(&numInterfaces);
168 ok(apiReturn == NO_ERROR,
169 "GetNumberOfInterfaces returned %ld, expected 0\n", apiReturn);
173 static void testGetIfEntry(DWORD index)
179 memset(&row, 0, sizeof(row));
180 apiReturn = gGetIfEntry(NULL);
181 if (apiReturn == ERROR_NOT_SUPPORTED)
183 ok(apiReturn == ERROR_INVALID_PARAMETER,
184 "GetIfEntry(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
186 row.dwIndex = -1; /* hope that's always bogus! */
187 apiReturn = gGetIfEntry(&row);
188 ok(apiReturn == ERROR_INVALID_DATA,
189 "GetIfEntry(bogus row) returned %ld, expected ERROR_INVALID_DATA\n",
192 apiReturn = gGetIfEntry(&row);
193 ok(apiReturn == NO_ERROR,
194 "GetIfEntry returned %ld, expected NO_ERROR\n", apiReturn);
198 static void testGetIpAddrTable(void)
200 if (gGetIpAddrTable) {
204 apiReturn = gGetIpAddrTable(NULL, NULL, FALSE);
205 if (apiReturn == ERROR_NOT_SUPPORTED)
207 ok(apiReturn == ERROR_INVALID_PARAMETER,
208 "GetIpAddrTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
210 apiReturn = gGetIpAddrTable(NULL, &dwSize, FALSE);
211 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
212 "GetIpAddrTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
214 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
215 PMIB_IPADDRTABLE buf = (PMIB_IPADDRTABLE)malloc(dwSize);
217 apiReturn = gGetIpAddrTable(buf, &dwSize, FALSE);
218 ok(apiReturn == NO_ERROR,
219 "GetIpAddrTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
221 if (apiReturn == NO_ERROR)
222 testGetIfEntry(buf->table[0].dwIndex);
228 static void testGetIfTable(void)
234 apiReturn = gGetIfTable(NULL, NULL, FALSE);
235 if (apiReturn == ERROR_NOT_SUPPORTED)
237 ok(apiReturn == ERROR_INVALID_PARAMETER,
238 "GetIfTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
240 apiReturn = gGetIfTable(NULL, &dwSize, FALSE);
241 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
242 "GetIfTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
244 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
245 PMIB_IFTABLE buf = (PMIB_IFTABLE)malloc(dwSize);
247 apiReturn = gGetIfTable(buf, &dwSize, FALSE);
248 ok(apiReturn == NO_ERROR,
249 "GetIfTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n\n",
256 static void testGetIpForwardTable(void)
258 if (gGetIpForwardTable) {
262 apiReturn = gGetIpForwardTable(NULL, NULL, FALSE);
263 if (apiReturn == ERROR_NOT_SUPPORTED)
265 ok(apiReturn == ERROR_INVALID_PARAMETER,
266 "GetIpForwardTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
268 apiReturn = gGetIpForwardTable(NULL, &dwSize, FALSE);
269 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
270 "GetIpForwardTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
272 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
273 PMIB_IPFORWARDTABLE buf = (PMIB_IPFORWARDTABLE)malloc(dwSize);
275 apiReturn = gGetIpForwardTable(buf, &dwSize, FALSE);
276 ok(apiReturn == NO_ERROR,
277 "GetIpForwardTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
279 if (apiReturn == NO_ERROR)
280 ok(buf->dwNumEntries > 0,
281 "Got 0 IP forward table entries, expect at least 1\n");
287 void testGetIpNetTable(void)
289 if (gGetIpNetTable) {
293 apiReturn = gGetIpNetTable(NULL, NULL, FALSE);
294 if (apiReturn == ERROR_NOT_SUPPORTED)
296 ok(apiReturn == ERROR_INVALID_PARAMETER,
297 "GetIpNetTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
299 apiReturn = gGetIpNetTable(NULL, &dwSize, FALSE);
300 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
301 "GetIpNetTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
303 if (apiReturn == ERROR_NO_DATA)
304 ; /* empty ARP table's okay */
305 else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
306 PMIB_IPNETTABLE buf = (PMIB_IPNETTABLE)malloc(dwSize);
308 apiReturn = gGetIpNetTable(buf, &dwSize, FALSE);
309 ok(apiReturn == NO_ERROR,
310 "GetIpNetTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
317 void testGetIcmpStatistics(void)
319 if (gGetIcmpStatistics) {
323 apiReturn = gGetIcmpStatistics(NULL);
324 if (apiReturn == ERROR_NOT_SUPPORTED)
326 ok(apiReturn == ERROR_INVALID_PARAMETER,
327 "GetIcmpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
329 apiReturn = gGetIcmpStatistics(&stats);
330 ok(apiReturn == NO_ERROR,
331 "GetIcmpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
335 void testGetIpStatistics(void)
337 if (gGetIpStatistics) {
341 apiReturn = gGetIpStatistics(NULL);
342 if (apiReturn == ERROR_NOT_SUPPORTED)
344 ok(apiReturn == ERROR_INVALID_PARAMETER,
345 "GetIpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
347 apiReturn = gGetIpStatistics(&stats);
348 ok(apiReturn == NO_ERROR,
349 "GetIpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
353 void testGetTcpStatistics(void)
355 if (gGetTcpStatistics) {
359 apiReturn = gGetTcpStatistics(NULL);
360 if (apiReturn == ERROR_NOT_SUPPORTED)
362 ok(apiReturn == ERROR_INVALID_PARAMETER,
363 "GetTcpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
365 apiReturn = gGetTcpStatistics(&stats);
366 ok(apiReturn == NO_ERROR,
367 "GetTcpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
371 void testGetUdpStatistics(void)
373 if (gGetUdpStatistics) {
377 apiReturn = gGetUdpStatistics(NULL);
378 if (apiReturn == ERROR_NOT_SUPPORTED)
380 ok(apiReturn == ERROR_INVALID_PARAMETER,
381 "GetUdpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
383 apiReturn = gGetUdpStatistics(&stats);
384 ok(apiReturn == NO_ERROR,
385 "GetUdpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
389 void testGetTcpTable(void)
395 apiReturn = gGetTcpTable(NULL, NULL, FALSE);
396 if (apiReturn == ERROR_NOT_SUPPORTED)
398 ok(apiReturn == ERROR_INVALID_PARAMETER,
399 "GetTcpTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
401 apiReturn = gGetTcpTable(NULL, &dwSize, FALSE);
402 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
403 "GetTcpTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
405 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
406 PMIB_TCPTABLE buf = (PMIB_TCPTABLE)malloc(dwSize);
408 apiReturn = gGetTcpTable(buf, &dwSize, FALSE);
409 ok(apiReturn == NO_ERROR,
410 "GetTcpTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
417 void testGetUdpTable(void)
423 apiReturn = gGetUdpTable(NULL, NULL, FALSE);
424 if (apiReturn == ERROR_NOT_SUPPORTED)
426 ok(apiReturn == ERROR_INVALID_PARAMETER,
427 "GetUdpTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
429 apiReturn = gGetUdpTable(NULL, &dwSize, FALSE);
430 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
431 "GetUdpTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
433 if (apiReturn != ERROR_INSUFFICIENT_BUFFER) {
434 PMIB_UDPTABLE buf = (PMIB_UDPTABLE)malloc(dwSize);
436 apiReturn = gGetUdpTable(buf, &dwSize, FALSE);
437 ok(apiReturn == NO_ERROR,
438 "GetUdpTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
446 still-to-be-tested NT4-onward functions:
460 static void testWinNT4Functions(void)
462 testGetNumberOfInterfaces();
463 testGetIpAddrTable();
465 testGetIpForwardTable();
467 testGetIcmpStatistics();
468 testGetIpStatistics();
469 testGetTcpStatistics();
470 testGetUdpStatistics();
475 static void testGetInterfaceInfo(void)
477 if (gGetInterfaceInfo) {
481 apiReturn = gGetInterfaceInfo(NULL, NULL);
482 if (apiReturn == ERROR_NOT_SUPPORTED)
484 ok(apiReturn == ERROR_INVALID_PARAMETER,
485 "GetInterfaceInfo returned %ld, expected ERROR_INVALID_PARAMETER\n",
487 apiReturn = gGetInterfaceInfo(NULL, &len);
488 ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
489 "GetInterfaceInfo returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
491 if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
492 PIP_INTERFACE_INFO buf = (PIP_INTERFACE_INFO)malloc(len);
494 apiReturn = gGetInterfaceInfo(buf, &len);
495 ok(apiReturn == NO_ERROR,
496 "GetInterfaceInfo(buf, &dwSize) returned %ld, expected NO_ERROR\n",
503 static void testGetAdaptersInfo(void)
505 if (gGetAdaptersInfo) {
509 apiReturn = gGetAdaptersInfo(NULL, NULL);
510 if (apiReturn == ERROR_NOT_SUPPORTED)
512 ok(apiReturn == ERROR_INVALID_PARAMETER,
513 "GetAdaptersInfo returned %ld, expected ERROR_INVALID_PARAMETER\n",
515 apiReturn = gGetAdaptersInfo(NULL, &len);
516 ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
517 "GetAdaptersInfo returned %ld, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
519 if (apiReturn == ERROR_NO_DATA)
520 ; /* no adapter's, that's okay */
521 else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
522 PIP_ADAPTER_INFO buf = (PIP_ADAPTER_INFO)malloc(len);
524 apiReturn = gGetAdaptersInfo(buf, &len);
525 ok(apiReturn == NO_ERROR,
526 "GetAdaptersInfo(buf, &dwSize) returned %ld, expected NO_ERROR\n",
533 static void testGetNetworkParams(void)
535 if (gGetNetworkParams) {
539 apiReturn = gGetNetworkParams(NULL, NULL);
540 if (apiReturn == ERROR_NOT_SUPPORTED)
542 ok(apiReturn == ERROR_INVALID_PARAMETER,
543 "GetNetworkParams returned %ld, expected ERROR_INVALID_PARAMETER\n",
545 apiReturn = gGetNetworkParams(NULL, &len);
546 ok(apiReturn == ERROR_BUFFER_OVERFLOW,
547 "GetNetworkParams returned %ld, expected ERROR_BUFFER_OVERFLOW\n",
549 if (apiReturn == ERROR_BUFFER_OVERFLOW) {
550 PFIXED_INFO buf = (PFIXED_INFO)malloc(len);
552 apiReturn = gGetNetworkParams(buf, &len);
553 ok(apiReturn == NO_ERROR,
554 "GetNetworkParams(buf, &dwSize) returned %ld, expected NO_ERROR\n",
562 still-to-be-tested 98-onward functions:
568 static void testWin98Functions(void)
570 testGetInterfaceInfo();
571 testGetAdaptersInfo();
572 testGetNetworkParams();
576 still-to-be-tested 2K-onward functions:
590 static void testWin2KFunctions(void)
599 testWin98OnlyFunctions();
600 testWinNT4Functions();
601 testWin98Functions();
602 testWin2KFunctions();