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