[WS2_32_APITESTS] Set the size of addr when calling getsockname ROSTESTS-278
[reactos.git] / 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 int Error;
27 struct
28 {
29 INT Type;
30 INT Proto;
31 struct sockaddr_in Addr;
32 INT ExpectedResult;
33 INT ExpectedWSAResult;
34 struct sockaddr_in ExpectedAddr;
35 } Tests[] =
36 {
37 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
38 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
39 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, Address }, 0, 0, { AF_INET, PORT, Address } },
40 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
41 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
42 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
43 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, Address }, 0, 0, { AF_INET, 0, Address } },
44 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
45 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
46 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
47 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, Address }, 0, 0, { AF_INET, PORT, Address } },
48 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
49 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } },
50 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } },
51 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, Address }, 0, 0,{ AF_INET, 0, Address } },
52 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL },
53 };
54 const INT TestCount = _countof(Tests);
55 INT i, AddrSize;
56 SOCKET Socket;
57 struct sockaddr_in Addr;
58 #if 0
59 BOOL Broadcast = FALSE;
60 #endif
61
62 for (i = 0; i < TestCount; i++)
63 {
64 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);
65 Socket = socket(AF_INET, Tests[i].Type, Tests[i].Proto);
66 if (Socket == INVALID_SOCKET)
67 {
68 skip("Failed to create socket, skipping");
69 continue;
70 }
71 Error = bind(Socket, (const struct sockaddr *) &Tests[i].Addr, sizeof(Tests[i].Addr));
72 ok_dec(Error, Tests[i].ExpectedResult);
73 if (Error)
74 {
75 ok_dec(WSAGetLastError(), Tests[i].ExpectedWSAResult);
76 }
77 else
78 {
79 ok_dec(WSAGetLastError(), 0);
80 AddrSize = sizeof(Addr);
81 Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize);
82 ok(Error == 0, "Error getsockname for test %d, Error %d\n", i, Error);
83 ok_dec(WSAGetLastError(), 0);
84 ok_dec(AddrSize, sizeof(Addr));
85 ok_dec(Addr.sin_addr.s_addr, Tests[i].ExpectedAddr.sin_addr.s_addr);
86 if (Tests[i].ExpectedAddr.sin_port)
87 {
88 ok_dec(Addr.sin_port, Tests[i].ExpectedAddr.sin_port);
89 }
90 else
91 {
92 ok(Addr.sin_port != 0, "Port remained zero\n");
93 }
94 }
95 Error = closesocket(Socket);
96 ok_dec(Error, 0);
97 }
98 #if 0
99 /* Check double bind */
100 Socket = socket(AF_INET, Tests[0].Type, Tests[0].Proto);
101 Error = bind(Socket, (const struct sockaddr *) &Tests[0].Addr, sizeof(Tests[0].Addr));
102 ok_dec(Error, Tests[0].ExpectedResult);
103 if (Error)
104 {
105 ok_dec(WSAGetLastError(), Tests[0].ExpectedWSAResult);
106 }
107 else
108 {
109 ok_dec(WSAGetLastError(), 0);
110 Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize);
111 ok_dec(Error, 0);
112 ok_dec(AddrSize, sizeof(Addr));
113 ok_dec(Addr.sin_addr.s_addr, Tests[0].ExpectedAddr.sin_addr.s_addr);
114 if (Tests[0].ExpectedAddr.sin_port)
115 {
116 ok_dec(Addr.sin_port, Tests[0].ExpectedAddr.sin_port);
117 }
118 else
119 {
120 ok(Addr.sin_port != 0, "Port remained zero\n");
121 }
122 Error = bind(Socket, (const struct sockaddr *) &Tests[2].Addr, sizeof(Tests[2].Addr));
123 ok_dec(Error, SOCKET_ERROR);
124 ok_dec(WSAGetLastError(), WSAEINVAL);
125 }
126 closesocket(Socket);
127 /* Check disabled SO_BROADCAST and bind to broadcast address */
128 Socket = socket(AF_INET, Tests[10].Type, Tests[10].Proto);
129 Error = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST, (const char *) &Broadcast, sizeof(Broadcast));
130 ok_dec(Error, 0);
131 // FIXME: should be made properly broadcast address
132 Tests[10].Addr.sin_addr.S_un.S_un_b.s_b4 = 0xff;
133 Error = bind(Socket, (const struct sockaddr *) &Tests[10].Addr, sizeof(Tests[10].Addr));
134 ok_dec(Error, SOCKET_ERROR);
135 ok_dec(WSAGetLastError(), WSAEACCES);
136 closesocket(Socket);
137 #endif
138 }
139
140 START_TEST(bind)
141 {
142 WSADATA WsaData;
143 int Error;
144 CHAR LocalHostName[128];
145 struct hostent *Hostent;
146 IN_ADDR Address;
147 SOCKET Socket;
148 struct sockaddr_in Addr = { AF_INET };
149
150 /* not yet initialized */
151 StartSeh()
152 Error = bind(INVALID_SOCKET, NULL, 0);
153 ok_dec(Error, -1);
154 EndSeh(STATUS_SUCCESS);
155 StartSeh()
156 Error = bind(INVALID_SOCKET, InvalidPointer, 0);
157 ok_dec(Error, -1);
158 EndSeh(STATUS_SUCCESS);
159
160 Error = WSAStartup(MAKEWORD(2, 2), &WsaData);
161 ok_dec(Error, 0);
162
163 /* initialize LocalAddress for tests */
164 Error = gethostname(LocalHostName, sizeof(LocalHostName));
165 ok_dec(Error, 0);
166 ok_dec(WSAGetLastError(), 0);
167 trace("Local host name is '%s'\n", LocalHostName);
168 Hostent = gethostbyname(LocalHostName);
169 ok(Hostent != NULL, "gethostbyname failed with %d\n", WSAGetLastError());
170 if (Hostent && Hostent->h_addr_list[0] && Hostent->h_length == sizeof(IN_ADDR))
171 {
172 memcpy(&Address, Hostent->h_addr_list[0], sizeof(Address));
173 strcpy(LocalAddress, inet_ntoa(Address));
174 }
175 trace("Local address is '%s'\n", LocalAddress);
176 ok(LocalAddress[0] != '\0',
177 "Could not determine local address. Following test results may be wrong.\n");
178
179 /* parameter tests */
180 StartSeh()
181 Error = bind(INVALID_SOCKET, NULL, 0);
182 ok_dec(Error, SOCKET_ERROR);
183 ok_dec(WSAGetLastError(), WSAENOTSOCK);
184 EndSeh(STATUS_SUCCESS);
185 StartSeh()
186 Error = bind(INVALID_SOCKET, InvalidPointer, 0);
187 ok_dec(Error, SOCKET_ERROR);
188 ok_dec(WSAGetLastError(), WSAENOTSOCK);
189 EndSeh(STATUS_SUCCESS);
190 StartSeh()
191 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
192 Error = bind(Socket, NULL, 0);
193 ok_dec(Error, SOCKET_ERROR);
194 ok_dec(WSAGetLastError(), WSAEFAULT);
195 closesocket(Socket);
196 EndSeh(STATUS_SUCCESS);
197 StartSeh()
198 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
199 Error = bind(Socket, InvalidPointer, 0);
200 ok_dec(Error, SOCKET_ERROR);
201 ok_dec(WSAGetLastError(), WSAEFAULT);
202 closesocket(Socket);
203 EndSeh(STATUS_SUCCESS);
204 StartSeh()
205 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
206 Error = bind(Socket, NULL, sizeof(Addr));
207 ok_dec(Error, SOCKET_ERROR);
208 ok_dec(WSAGetLastError(), WSAEFAULT);
209 closesocket(Socket);
210 EndSeh(STATUS_SUCCESS);
211 StartSeh()
212 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
213 Error = bind(Socket, InvalidPointer, sizeof(Addr));
214 ok_dec(Error, SOCKET_ERROR);
215 ok_dec(WSAGetLastError(), WSAEFAULT);
216 closesocket(Socket);
217 EndSeh(STATUS_ACCESS_VIOLATION);
218 StartSeh()
219 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
220 Error = bind(Socket, (const struct sockaddr *) &Addr, 0);
221 ok_dec(Error, SOCKET_ERROR);
222 ok_dec(WSAGetLastError(), WSAEFAULT);
223 closesocket(Socket);
224 EndSeh(STATUS_SUCCESS);
225 StartSeh()
226 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
227 Error = bind(Socket, (const struct sockaddr *) &Addr, sizeof(Addr)-1);
228 ok_dec(Error, SOCKET_ERROR);
229 ok_dec(WSAGetLastError(), WSAEFAULT);
230 closesocket(Socket);
231 EndSeh(STATUS_SUCCESS);
232
233 TestBind(Address);
234 /* TODO: test IPv6 */
235
236 Error = WSACleanup();
237 ok_dec(Error, 0);
238 }