2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for WSHIoctl:
5 * - SIO_GET_INTERFACE_LIST
6 * PROGRAMMERS: Andreas Maier
15 void traceaddr(char* txt
, sockaddr_gen a
)
17 trace(" %s.AddressIn.sin_family %x\n", txt
, a
.AddressIn
.sin_family
);
18 trace(" %s.AddressIn.sin_port %x\n", txt
, a
.AddressIn
.sin_port
);
19 trace(" %s.AddressIn.sin_addr.s_addr %lx\n", txt
, a
.AddressIn
.sin_addr
.s_addr
);
22 BOOL
Test_WSAIoctl_InitTest(
23 OUT PMIB_IPADDRTABLE
* ppTable
)
28 PMIB_IPADDRTABLE pTable
;
32 ret
= GetIpAddrTable(NULL
, &TableSize
, FALSE
);
33 if (ret
!= ERROR_INSUFFICIENT_BUFFER
)
35 skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret
);
39 /* get sorted ip-address table. Sort order is the ip-address. */
40 pTable
= (PMIB_IPADDRTABLE
)malloc(TableSize
);
42 ret
= GetIpAddrTable(pTable
, &TableSize
, TRUE
);
45 skip("GetIpAddrTable failed with %ld. Abort Testing.\n", ret
);
49 if (winetest_debug
>= 2)
51 trace("Result of GetIpAddrTable:\n");
52 trace("Count: %ld\n", pTable
->dwNumEntries
);
54 for (i1
= 0; i1
< pTable
->dwNumEntries
; i1
++)
56 trace("** Entry %ld **\n", i1
);
57 trace(" dwAddr %lx\n", pRow
->dwAddr
);
58 trace(" dwIndex %lx\n", pRow
->dwIndex
);
59 trace(" dwMask %lx\n", pRow
->dwMask
);
60 trace(" dwBCastAddr %lx\n", pRow
->dwBCastAddr
);
61 trace(" dwReasmSize %lx\n", pRow
->dwReasmSize
);
62 trace(" wType %x\n", pRow
->wType
);
71 void Test_WSAIoctl_GetInterfaceList()
76 ULONG buflen
, BytesReturned
, BCastAddr
;
77 ULONG infoCount
, i1
, j1
, iiFlagsExpected
;
79 LPINTERFACE_INFO ifInfo
;
80 PMIB_IPADDRTABLE pTable
= NULL
;
83 /* Get PMIB_IPADDRTABE - these results we should get from wshtcpip.dll too. */
84 /* pTable is allocated by Test_WSAIoctl_InitTest! */
85 if (!Test_WSAIoctl_InitTest(&pTable
))
88 /* Start up Winsock */
89 iResult
= WSAStartup(MAKEWORD(2, 2), &wdata
);
90 ok(iResult
== 0, "WSAStartup failed. iResult = %d\n", iResult
);
92 /* Create the socket */
93 sck
= WSASocket(AF_INET
, SOCK_STREAM
, IPPROTO_IP
, 0, 0, 0);
94 ok(sck
!= INVALID_SOCKET
, "WSASocket failed. sck = %d\n", (INT
)sck
);
95 if (sck
== INVALID_SOCKET
)
97 skip("Failed to create socket!\n");
101 /* Do the Ioctl (buffer to small) */
102 buflen
= sizeof(INTERFACE_INFO
)-1;
103 buf
= (BYTE
*)HeapAlloc(GetProcessHeap(), 0, buflen
);
106 skip("Failed to allocate memory!\n");
110 iResult
= WSAIoctl(sck
, SIO_GET_INTERFACE_LIST
, 0, 0,
111 buf
, buflen
, &BytesReturned
, 0, 0);
112 ok(iResult
== -1, "WSAIoctl/SIO_GET_INTERFACE_LIST did not fail! iResult = %d.\n", iResult
);
113 ok_hex(WSAGetLastError(), WSAEFAULT
);
114 ok(BytesReturned
== 0, "WSAIoctl/SIO_GET_INTERFACE_LIST: BytesReturned should be 0, not %ld.\n", BytesReturned
);
115 HeapFree(GetProcessHeap(), 0, buf
);
119 In most cases no loop is done.
120 Only if WSAIoctl fails with WSAEFAULT (buffer to small) we need to retry with a
127 HeapFree(GetProcessHeap(), 0, buf
);
131 buflen
= sizeof(INTERFACE_INFO
) * (i1
+1) * 32;
132 buf
= (BYTE
*)HeapAlloc(GetProcessHeap(), 0, buflen
);
135 skip("Failed to allocate memory!\n");
139 iResult
= WSAIoctl(sck
, SIO_GET_INTERFACE_LIST
, 0, 0,
140 buf
, buflen
, &BytesReturned
, 0, 0);
141 /* we have what we want ... leave loop */
142 if (iResult
== NO_ERROR
)
144 /* only retry if buffer was to small */
145 /* to avoid infinite loop we maximum retry count is 4 */
146 if ((i1
>= 4) || (WSAGetLastError() != WSAEFAULT
))
148 ok_hex(iResult
, NO_ERROR
);
149 skip("WSAIoctl / SIO_GET_INTERFACE_LIST\n");
152 /* buffer to small -> retry */
156 ok_dec(BytesReturned
% sizeof(INTERFACE_INFO
), 0);
158 /* Calculate how many INTERFACE_INFO we got */
159 infoCount
= BytesReturned
/ sizeof(INTERFACE_INFO
);
160 ok(infoCount
== pTable
->dwNumEntries
,
161 "Wrong count of entries! Got %ld, expected %ld.\n", pTable
->dwNumEntries
, infoCount
);
163 if (winetest_debug
>= 2)
166 trace(" BytesReturned %ld - InfoCount %ld\n ", BytesReturned
, infoCount
);
167 ifInfo
= (LPINTERFACE_INFO
)buf
;
168 for (i1
= 0; i1
< infoCount
; i1
++)
170 trace("entry-index %ld\n", i1
);
171 trace(" iiFlags %ld\n", ifInfo
->iiFlags
);
172 traceaddr("ifInfo^.iiAddress", ifInfo
->iiAddress
);
173 traceaddr("ifInfo^.iiBroadcastAddress", ifInfo
->iiBroadcastAddress
);
174 traceaddr("ifInfo^.iiNetmask", ifInfo
->iiNetmask
);
179 /* compare entries */
180 ifInfo
= (LPINTERFACE_INFO
)buf
;
181 for (i1
= 0; i1
< infoCount
; i1
++)
183 if (winetest_debug
>= 2)
184 trace("Entry %ld\n", i1
);
185 for (j1
= 0; j1
< pTable
->dwNumEntries
; j1
++)
187 if (ifInfo
[i1
].iiAddress
.AddressIn
.sin_addr
.s_addr
== pTable
->table
[j1
].dwAddr
)
189 pRow
= &pTable
->table
[j1
];
193 if (j1
== pTable
->dwNumEntries
)
195 skip("Skipping interface\n");
200 * Don't know if this value is fix for SIO_GET_INTERFACE_LIST! */
201 iiFlagsExpected
= IFF_BROADCAST
| IFF_MULTICAST
;
202 if ((pRow
->wType
& MIB_IPADDR_DISCONNECTED
) == 0)
203 iiFlagsExpected
|= IFF_UP
;
204 if (pRow
->dwAddr
== ntohl(INADDR_LOOPBACK
))
206 iiFlagsExpected
|= IFF_LOOPBACK
;
207 /* on Windows 7 loopback has broadcast flag cleared */
208 //iiFlagsExpected &= ~IFF_BROADCAST;
211 ok_hex(ifInfo
[i1
].iiFlags
, iiFlagsExpected
);
212 ok_hex(ifInfo
[i1
].iiAddress
.AddressIn
.sin_addr
.s_addr
, pRow
->dwAddr
);
213 // dwBCastAddr is not the "real" Broadcast-Address.
214 BCastAddr
= (pRow
->dwBCastAddr
== 1 && (iiFlagsExpected
& IFF_BROADCAST
) != 0) ? 0xFFFFFFFF : 0x0;
215 ok_hex(ifInfo
[i1
].iiBroadcastAddress
.AddressIn
.sin_addr
.s_addr
, BCastAddr
);
216 ok_hex(ifInfo
[i1
].iiNetmask
.AddressIn
.sin_addr
.s_addr
, pRow
->dwMask
);
225 HeapFree(GetProcessHeap(), 0, buf
);
231 Test_WSAIoctl_GetInterfaceList();