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