[WS2_32_APITEST] Make the apitest fully C89-compliant to fix building under MSVC...
[reactos.git] / modules / rostests / apitests / ws2_32 / bind.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for bind
5 * PROGRAMMER: Peter Hater
6 */
7
8 #include <apitest.h>
9
10 #define WIN32_NO_STATUS
11 #define _INC_WINDOWS
12 #define COM_NO_WINDOWS_H
13 #include <stdarg.h>
14 #include <windef.h>
15 #include <winbase.h>
16 #include <ws2tcpip.h>
17 #include <ndk/umtypes.h>
18
19 CHAR LocalAddress[sizeof("255.255.255.255")];
20 #define PORT 58888
21
22 static
23 VOID
24 TestBind(IN_ADDR Address)
25 {
26 const UCHAR b1 = Address.S_un.S_un_b.s_b1;
27 const UCHAR b2 = Address.S_un.S_un_b.s_b2;
28 const UCHAR b3 = Address.S_un.S_un_b.s_b3;
29 const UCHAR b4 = Address.S_un.S_un_b.s_b4;
30
31 int Error;
32 struct
33 {
34 INT Type;
35 INT Proto;
36 struct sockaddr_in Addr;
37 INT ExpectedResult;
38 INT ExpectedWSAResult;
39 struct sockaddr_in ExpectedAddr;
40 } Tests[] =
41 {
42 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
43 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
44 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} }, 0, 0, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} } },
45 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
46 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
47 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
48 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ b1, b2, b3, b4 }}} }, 0, 0, { AF_INET, 0, {{{ b1, b2, b3, b4 }}} } },
49 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
50 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
51 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
52 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} }, 0, 0, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} } },
53 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
54 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
55 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
56 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ b1, b2, b3, b4 }}} }, 0, 0,{ AF_INET, 0, {{{ b1, b2, b3, b4 }}} } },
57 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
58 };
59 const INT TestCount = _countof(Tests);
60 INT i, AddrSize;
61 SOCKET Socket;
62 struct sockaddr_in Addr;
63 BOOL Broadcast = TRUE;
64
65 for (i = 0; i < TestCount; i++)
66 {
67 trace("%d: %s %d.%d.%d.%d:%d\n", i, Tests[i].Type == SOCK_STREAM ? "TCP" : "UDP", Tests[i].Addr.sin_addr.S_un.S_un_b.s_b1, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b2, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b3, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b4, Tests[i].ExpectedAddr.sin_port);
68 Socket = socket(AF_INET, Tests[i].Type, Tests[i].Proto);
69 if (Socket == INVALID_SOCKET)
70 {
71 skip("Failed to create socket with error %d for test %d, skipping\n", WSAGetLastError(), i);
72 continue;
73 }
74 Error = bind(Socket, (const struct sockaddr *) &Tests[i].Addr, sizeof(Tests[i].Addr));
75 ok(Error == Tests[i].ExpectedResult, "Error %d differs from expected %d for test %d\n", Error, Tests[i].ExpectedResult, i);
76 if (Error)
77 {
78 ok(WSAGetLastError() == Tests[i].ExpectedWSAResult, "Error %d differs from expected %d for test %d\n", WSAGetLastError(), Tests[i].ExpectedWSAResult, i);
79 }
80 else
81 {
82 AddrSize = sizeof(Addr);
83 Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize);
84 ok(Error == 0, "Unexpected error %d %d on getsockname for test %d\n", Error, WSAGetLastError(), i);
85 ok(AddrSize == sizeof(Addr), "Returned size %d differs from expected %d for test %d\n", AddrSize, sizeof(Addr), i);
86 ok(Addr.sin_addr.s_addr == Tests[i].ExpectedAddr.sin_addr.s_addr, "Expected address %lx differs from returned address %lx for test %d\n", Tests[i].ExpectedAddr.sin_addr.s_addr, Addr.sin_addr.s_addr, i);
87 if (Tests[i].ExpectedAddr.sin_port)
88 {
89 ok(Addr.sin_port == Tests[i].ExpectedAddr.sin_port, "Returned port %d differs from expected %d for test %d\n", Addr.sin_port, Tests[i].ExpectedAddr.sin_port, i);
90 }
91 else
92 {
93 ok(Addr.sin_port != 0, "Port remained zero for test %d\n", i);
94 }
95 }
96 Error = closesocket(Socket);
97 ok(Error == 0, "Unexpected error %d %d on closesocket for test %d\n", Error, WSAGetLastError(), i);
98 }
99 /* Check double bind */
100 Socket = socket(AF_INET, Tests[0].Type, Tests[0].Proto);
101 ok(Socket != INVALID_SOCKET, "Failed to create socket with error %d for double bind test, next tests might be wrong\n", WSAGetLastError());
102 Error = bind(Socket, (const struct sockaddr *) &Tests[0].Addr, sizeof(Tests[0].Addr));
103 ok(Error == Tests[0].ExpectedResult, "Error %d differs from expected %d for double bind test\n", Error, Tests[0].ExpectedResult);
104 if (Error)
105 {
106 ok(WSAGetLastError() == Tests[i].ExpectedWSAResult, "Error %d differs from expected %d for double bind test\n", WSAGetLastError(), Tests[0].ExpectedWSAResult);
107 }
108 else
109 {
110 AddrSize = sizeof(Addr);
111 Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize);
112 ok(Error == 0, "Unexpected error %d %d on getsockname for double bind test\n", Error, WSAGetLastError());
113 ok(AddrSize == sizeof(Addr), "Returned size %d differs from expected %d for double bind test\n", AddrSize, sizeof(Addr));
114 ok(Addr.sin_addr.s_addr == Tests[0].ExpectedAddr.sin_addr.s_addr, "Expected address %lx differs from returned address %lx for double bind test\n", Tests[0].ExpectedAddr.sin_addr.s_addr, Addr.sin_addr.s_addr);
115 if (Tests[0].ExpectedAddr.sin_port)
116 {
117 ok(Addr.sin_port == Tests[0].ExpectedAddr.sin_port, "Returned port %d differs from expected %d for double bind test\n", Addr.sin_port, Tests[0].ExpectedAddr.sin_port);
118 }
119 else
120 {
121 ok(Addr.sin_port != 0, "Port remained zero for double bind test\n");
122 }
123 Error = bind(Socket, (const struct sockaddr *) &Tests[2].Addr, sizeof(Tests[2].Addr));
124 ok(Error == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL, "Unexpected result %d expected %d and wsa result %d expected %ld for double bind test\n", Error, SOCKET_ERROR, WSAGetLastError(), WSAEINVAL);
125 }
126 Error = closesocket(Socket);
127 ok(Error == 0, "Unexpected error %d %d on closesocket for double bind test\n", Error, WSAGetLastError());
128 /* Check SO_BROADCAST and bind to broadcast address */
129 Socket = socket(AF_INET, Tests[10].Type, Tests[10].Proto);
130 ok(Socket != INVALID_SOCKET, "Failed to create socket with error %d for broadcast test, next tests might be wrong\n", WSAGetLastError());
131 Error = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST, (const char *) &Broadcast, sizeof(Broadcast));
132 ok(Error == 0, "Unexpected error %d %d on setsockopt for broadcast test\n", Error, WSAGetLastError());
133 Error = bind(Socket, (const struct sockaddr *) &Tests[10].Addr, sizeof(Tests[10].Addr));
134 ok(Error == 0, "Unexpected error %d %d on bind for broadcast test\n", Error, WSAGetLastError());
135 Error = closesocket(Socket);
136 ok(Error == 0, "Unexpected error %d %d on closesocket for broadcast test\n", Error, WSAGetLastError());
137 }
138
139 START_TEST(bind)
140 {
141 WSADATA WsaData;
142 int Error;
143 CHAR LocalHostName[128];
144 struct hostent *Hostent;
145 IN_ADDR Address;
146 SOCKET Socket;
147 struct sockaddr_in Addr = { AF_INET };
148
149 /* not yet initialized */
150 StartSeh()
151 Error = bind(INVALID_SOCKET, NULL, 0);
152 ok_dec(Error, -1);
153 EndSeh(STATUS_SUCCESS);
154 StartSeh()
155 Error = bind(INVALID_SOCKET, InvalidPointer, 0);
156 ok_dec(Error, -1);
157 EndSeh(STATUS_SUCCESS);
158
159 Error = WSAStartup(MAKEWORD(2, 2), &WsaData);
160 ok_dec(Error, 0);
161
162 /* initialize LocalAddress for tests */
163 Error = gethostname(LocalHostName, sizeof(LocalHostName));
164 ok_dec(Error, 0);
165 ok_dec(WSAGetLastError(), 0);
166 trace("Local host name is '%s'\n", LocalHostName);
167 Hostent = gethostbyname(LocalHostName);
168 ok(Hostent != NULL, "gethostbyname failed with %d\n", WSAGetLastError());
169 if (Hostent && Hostent->h_addr_list[0] && Hostent->h_length == sizeof(IN_ADDR))
170 {
171 memcpy(&Address, Hostent->h_addr_list[0], sizeof(Address));
172 strcpy(LocalAddress, inet_ntoa(Address));
173 }
174 trace("Local address is '%s'\n", LocalAddress);
175 ok(LocalAddress[0] != '\0',
176 "Could not determine local address. Following test results may be wrong.\n");
177
178 /* parameter tests */
179 StartSeh()
180 Error = bind(INVALID_SOCKET, NULL, 0);
181 ok_dec(Error, SOCKET_ERROR);
182 ok_dec(WSAGetLastError(), WSAENOTSOCK);
183 EndSeh(STATUS_SUCCESS);
184 StartSeh()
185 Error = bind(INVALID_SOCKET, InvalidPointer, 0);
186 ok_dec(Error, SOCKET_ERROR);
187 ok_dec(WSAGetLastError(), WSAENOTSOCK);
188 EndSeh(STATUS_SUCCESS);
189 StartSeh()
190 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
191 Error = bind(Socket, NULL, 0);
192 ok_dec(Error, SOCKET_ERROR);
193 ok_dec(WSAGetLastError(), WSAEFAULT);
194 closesocket(Socket);
195 EndSeh(STATUS_SUCCESS);
196 StartSeh()
197 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
198 Error = bind(Socket, InvalidPointer, 0);
199 ok_dec(Error, SOCKET_ERROR);
200 ok_dec(WSAGetLastError(), WSAEFAULT);
201 closesocket(Socket);
202 EndSeh(STATUS_SUCCESS);
203 StartSeh()
204 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
205 Error = bind(Socket, NULL, sizeof(Addr));
206 ok_dec(Error, SOCKET_ERROR);
207 ok_dec(WSAGetLastError(), WSAEFAULT);
208 closesocket(Socket);
209 EndSeh(STATUS_SUCCESS);
210 StartSeh()
211 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
212 Error = bind(Socket, InvalidPointer, sizeof(Addr));
213 ok_dec(Error, SOCKET_ERROR);
214 ok_dec(WSAGetLastError(), WSAEFAULT);
215 closesocket(Socket);
216 EndSeh(STATUS_SUCCESS);
217 StartSeh()
218 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
219 Error = bind(Socket, (const struct sockaddr *) &Addr, 0);
220 ok_dec(Error, SOCKET_ERROR);
221 ok_dec(WSAGetLastError(), WSAEFAULT);
222 closesocket(Socket);
223 EndSeh(STATUS_SUCCESS);
224 StartSeh()
225 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
226 Error = bind(Socket, (const struct sockaddr *) &Addr, sizeof(Addr)-1);
227 ok_dec(Error, SOCKET_ERROR);
228 ok_dec(WSAGetLastError(), WSAEFAULT);
229 closesocket(Socket);
230 EndSeh(STATUS_SUCCESS);
231
232 TestBind(Address);
233 /* TODO: test IPv6 */
234
235 Error = WSACleanup();
236 ok_dec(Error, 0);
237 }