Time to commit some Work-In-Progress stuff before my diff gets too large..
[reactos.git] / rostests / apitests / ws2_32 / getaddrinfo.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for getaddrinfo
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
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 #define ok_addrinfo(ai, flags, family, socktype, protocol, addrlen) do \
20 { \
21 ok_hex((ai)->ai_flags, flags); \
22 ok_dec((ai)->ai_family, family); \
23 ok_dec((ai)->ai_socktype, socktype); \
24 ok_dec((ai)->ai_protocol, protocol); \
25 ok_dec((ai)->ai_addrlen, addrlen); \
26 } while (0)
27
28 #define ok_sockaddr_in(sockaddr, family, port, addr) do \
29 { \
30 int _i; \
31 ok_dec(((SOCKADDR_IN *)(sockaddr))->sin_family, family); \
32 ok_dec(ntohs(((SOCKADDR_IN *)(sockaddr))->sin_port), port); \
33 ok_hex(((SOCKADDR_IN *)(sockaddr))->sin_addr.S_un.S_addr, \
34 inet_addr(addr)); \
35 for (_i = 0; _i < 7; _i++) \
36 ok_dec(((SOCKADDR_IN *)(sockaddr))->sin_zero[_i], 0); \
37 } while (0)
38
39 CHAR LocalAddress[sizeof("255.255.255.255")];
40
41 static
42 VOID
43 TestNodeName(VOID)
44 {
45 int Error;
46 PADDRINFOA AddrInfo;
47 ADDRINFOA Hints;
48 struct
49 {
50 PCSTR NodeName;
51 PCSTR ExpectedAddress;
52 INT Flags;
53 } Tests[] =
54 {
55 { "", LocalAddress },
56 { " ", NULL },
57 { "doesntexist.reactos.org", NULL },
58 { "localhost", "127.0.0.1" },
59 { "localhost:80", NULL },
60 { "7.8.9.10", "7.8.9.10", AI_NUMERICHOST },
61 { "0.0.0.0", "0.0.0.0", AI_NUMERICHOST },
62 { "255.255.255.255", "255.255.255.255", AI_NUMERICHOST },
63 { "0.0.0.0 ", "0.0.0.0", /* no AI_NUMERICHOST */ },
64 { "0.0.0.0:80", NULL },
65 { "0.0.0.0.0", NULL },
66 { "1.1.1.256", NULL },
67 { "1.2.3", NULL },
68 { "1.2.3.0x4", "1.2.3.4", AI_NUMERICHOST },
69 { "1.2.3.010", "1.2.3.8", AI_NUMERICHOST },
70 /* let's just assume this one doesn't change any time soon ;) */
71 { "google-public-dns-a.google.com", "8.8.8.8" },
72 };
73 const INT TestCount = sizeof(Tests) / sizeof(Tests[0]);
74 INT i;
75
76 /* make sure we don't get IPv6 responses */
77 ZeroMemory(&Hints, sizeof(Hints));
78 Hints.ai_family = AF_INET;
79
80 trace("Nodes\n");
81 for (i = 0; i < TestCount; i++)
82 {
83 trace("%d: '%s'\n", i, Tests[i].NodeName);
84 StartSeh()
85 AddrInfo = InvalidPointer;
86 Error = getaddrinfo(Tests[i].NodeName, NULL, &Hints, &AddrInfo);
87 if (Tests[i].ExpectedAddress)
88 {
89 ok_dec(Error, 0);
90 ok_dec(WSAGetLastError(), 0);
91 ok(AddrInfo != NULL && AddrInfo != InvalidPointer,
92 "AddrInfo = %p\n", AddrInfo);
93 }
94 else
95 {
96 ok_dec(Error, WSAHOST_NOT_FOUND);
97 ok_dec(WSAGetLastError(), WSAHOST_NOT_FOUND);
98 ok_ptr(AddrInfo, NULL);
99 }
100 if (!Error && AddrInfo && AddrInfo != InvalidPointer)
101 {
102 ok_addrinfo(AddrInfo, Tests[i].Flags, AF_INET,
103 0, 0, sizeof(SOCKADDR_IN));
104 ok_ptr(AddrInfo->ai_canonname, NULL);
105 ok_sockaddr_in(AddrInfo->ai_addr, AF_INET,
106 0, Tests[i].ExpectedAddress);
107 ok_ptr(AddrInfo->ai_next, NULL);
108 freeaddrinfo(AddrInfo);
109 }
110 EndSeh(STATUS_SUCCESS);
111 }
112 }
113
114 static
115 VOID
116 TestServiceName(VOID)
117 {
118 int Error;
119 PADDRINFOA AddrInfo;
120 ADDRINFOA Hints;
121 struct
122 {
123 PCSTR ServiceName;
124 INT ExpectedPort;
125 INT SockType;
126 } Tests[] =
127 {
128 { "", 0 },
129 { "0", 0 },
130 { "1", 1 },
131 { "a", -1 },
132 { "010", 10 },
133 { "0x1a", -1 },
134 { "http", 80, SOCK_STREAM },
135 { "smtp", 25, SOCK_STREAM },
136 { "mail", 25, SOCK_STREAM }, /* alias for smtp */
137 { "router", 520, SOCK_DGRAM },
138 { "domain", 53, 0 /* DNS supports both UDP and TCP */ },
139 { ":0", -1 },
140 { "123", 123 },
141 { " 123", 123 },
142 { " 123", 123 },
143 { "32767", 32767 },
144 { "32768", 32768 },
145 { "65535", 65535 },
146 { "65536", 0 },
147 { "65537", 1 },
148 { "65540", 4 },
149 { "65536", 0 },
150 { "4294967295", 65535 },
151 { "4294967296", 65535 },
152 { "9999999999", 65535 },
153 { "999999999999999999999999999999999999", 65535 },
154 { "+5", 5 },
155 { "-1", 65535 },
156 { "-4", 65532 },
157 { "-65534", 2 },
158 { "-65535", 1 },
159 { "-65536", 0 },
160 { "-65537", 65535 },
161 { "28a", -1 },
162 { "28 ", -1 },
163 { "a28", -1 },
164 };
165 const INT TestCount = sizeof(Tests) / sizeof(Tests[0]);
166 INT i;
167
168 /* make sure we don't get IPv6 responses */
169 ZeroMemory(&Hints, sizeof(Hints));
170 Hints.ai_family = AF_INET;
171
172 trace("Services\n");
173 for (i = 0; i < TestCount; i++)
174 {
175 trace("%d: '%s'\n", i, Tests[i].ServiceName);
176 StartSeh()
177 AddrInfo = InvalidPointer;
178 Error = getaddrinfo(NULL, Tests[i].ServiceName, &Hints, &AddrInfo);
179 if (Tests[i].ExpectedPort != -1)
180 {
181 ok_dec(Error, 0);
182 ok_dec(WSAGetLastError(), 0);
183 ok(AddrInfo != NULL && AddrInfo != InvalidPointer,
184 "AddrInfo = %p\n", AddrInfo);
185 }
186 else
187 {
188 ok_dec(Error, WSATYPE_NOT_FOUND);
189 ok_dec(WSAGetLastError(), WSATYPE_NOT_FOUND);
190 ok_ptr(AddrInfo, NULL);
191 }
192 if (!Error && AddrInfo && AddrInfo != InvalidPointer)
193 {
194 ok_addrinfo(AddrInfo, 0, AF_INET,
195 Tests[i].SockType, 0, sizeof(SOCKADDR_IN));
196 ok_ptr(AddrInfo->ai_canonname, NULL);
197 ok_sockaddr_in(AddrInfo->ai_addr, AF_INET,
198 Tests[i].ExpectedPort, "127.0.0.1");
199 ok_ptr(AddrInfo->ai_next, NULL);
200 freeaddrinfo(AddrInfo);
201 }
202 EndSeh(STATUS_SUCCESS);
203 }
204 }
205
206 START_TEST(getaddrinfo)
207 {
208 WSADATA WsaData;
209 int Error;
210 PADDRINFOA AddrInfo;
211 ADDRINFOA Hints;
212 CHAR LocalHostName[128];
213 struct hostent *Hostent;
214
215 /* not yet initialized */
216 StartSeh()
217 Error = getaddrinfo(NULL, NULL, NULL, NULL);
218 ok_dec(Error, WSANOTINITIALISED);
219 EndSeh(STATUS_SUCCESS);
220 StartSeh()
221 AddrInfo = InvalidPointer;
222 Error = getaddrinfo(NULL, NULL, NULL, &AddrInfo);
223 ok_dec(Error, WSANOTINITIALISED);
224 ok_ptr(AddrInfo, InvalidPointer);
225 EndSeh(STATUS_SUCCESS);
226
227 Error = getaddrinfo("127.0.0.1", "80", NULL, &AddrInfo);
228 ok_dec(Error, WSANOTINITIALISED);
229
230 Error = WSAStartup(MAKEWORD(2, 2), &WsaData);
231 ok_dec(Error, 0);
232
233 /* initialize LocalAddress for tests */
234 Error = gethostname(LocalHostName, sizeof(LocalHostName));
235 ok_dec(Error, 0);
236 ok_dec(WSAGetLastError(), 0);
237 trace("Local host name is '%s'\n", LocalHostName);
238 Hostent = gethostbyname(LocalHostName);
239 ok(Hostent != NULL, "gethostbyname failed with %d\n", WSAGetLastError());
240 if (Hostent && Hostent->h_addr_list[0] && Hostent->h_length == sizeof(IN_ADDR))
241 {
242 IN_ADDR Address;
243 memcpy(&Address, Hostent->h_addr_list[0], sizeof(Address));
244 strcpy(LocalAddress, inet_ntoa(Address));
245 }
246 trace("Local address is '%s'\n", LocalAddress);
247 ok(LocalAddress[0] != '\0',
248 "Could not determine local address. Following test results may be wrong.\n");
249
250 ZeroMemory(&Hints, sizeof(Hints));
251 /* parameter tests */
252 StartSeh() getaddrinfo(NULL, NULL, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
253 StartSeh() getaddrinfo("", "", &Hints, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
254 StartSeh()
255 AddrInfo = InvalidPointer;
256 Error = getaddrinfo(NULL, NULL, NULL, &AddrInfo);
257 ok_dec(Error, WSAHOST_NOT_FOUND);
258 ok_dec(WSAGetLastError(), WSAHOST_NOT_FOUND);
259 ok_ptr(AddrInfo, NULL);
260 EndSeh(STATUS_SUCCESS);
261
262 TestNodeName();
263 TestServiceName();
264 /* TODO: test passing both node name and service name */
265 /* TODO: test hints */
266 /* TODO: test IPv6 */
267
268 Error = WSACleanup();
269 ok_dec(Error, 0);
270
271 /* not initialized anymore */
272 Error = getaddrinfo("127.0.0.1", "80", NULL, &AddrInfo);
273 ok_dec(Error, WSANOTINITIALISED);
274 }