mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 18:02:55 +00:00
275 lines
9.2 KiB
C
275 lines
9.2 KiB
C
/*
|
|
* PROJECT: ReactOS api tests
|
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
|
* PURPOSE: Test for getaddrinfo
|
|
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
|
|
*/
|
|
|
|
#include <apitest.h>
|
|
|
|
#define WIN32_NO_STATUS
|
|
#define _INC_WINDOWS
|
|
#define COM_NO_WINDOWS_H
|
|
#include <stdarg.h>
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
#include <ws2tcpip.h>
|
|
#include <ndk/umtypes.h>
|
|
|
|
#define ok_addrinfo(ai, flags, family, socktype, protocol, addrlen) do \
|
|
{ \
|
|
ok_hex((ai)->ai_flags, flags); \
|
|
ok_dec((ai)->ai_family, family); \
|
|
ok_dec((ai)->ai_socktype, socktype); \
|
|
ok_dec((ai)->ai_protocol, protocol); \
|
|
ok_dec((ai)->ai_addrlen, addrlen); \
|
|
} while (0)
|
|
|
|
#define ok_sockaddr_in(sockaddr, family, port, addr) do \
|
|
{ \
|
|
int _i; \
|
|
ok_dec(((SOCKADDR_IN *)(sockaddr))->sin_family, family); \
|
|
ok_dec(ntohs(((SOCKADDR_IN *)(sockaddr))->sin_port), port); \
|
|
ok_hex(((SOCKADDR_IN *)(sockaddr))->sin_addr.S_un.S_addr, \
|
|
inet_addr(addr)); \
|
|
for (_i = 0; _i < 7; _i++) \
|
|
ok_dec(((SOCKADDR_IN *)(sockaddr))->sin_zero[_i], 0); \
|
|
} while (0)
|
|
|
|
CHAR LocalAddress[sizeof("255.255.255.255")];
|
|
|
|
static
|
|
VOID
|
|
TestNodeName(VOID)
|
|
{
|
|
int Error;
|
|
PADDRINFOA AddrInfo;
|
|
ADDRINFOA Hints;
|
|
struct
|
|
{
|
|
PCSTR NodeName;
|
|
PCSTR ExpectedAddress;
|
|
INT Flags;
|
|
} Tests[] =
|
|
{
|
|
{ "", LocalAddress },
|
|
{ " ", NULL },
|
|
{ "doesntexist.example.com", NULL },
|
|
{ "localhost", "127.0.0.1" },
|
|
{ "localhost:80", NULL },
|
|
{ "7.8.9.10", "7.8.9.10", AI_NUMERICHOST },
|
|
{ "0.0.0.0", "0.0.0.0", AI_NUMERICHOST },
|
|
{ "255.255.255.255", "255.255.255.255", AI_NUMERICHOST },
|
|
{ "0.0.0.0 ", "0.0.0.0", /* no AI_NUMERICHOST */ },
|
|
{ "0.0.0.0:80", NULL },
|
|
{ "0.0.0.0.0", NULL },
|
|
{ "1.1.1.256", NULL },
|
|
{ "1.2.3", NULL },
|
|
{ "1.2.3.0x4", "1.2.3.4", AI_NUMERICHOST },
|
|
{ "1.2.3.010", "1.2.3.8", AI_NUMERICHOST },
|
|
/* let's just assume this one doesn't change any time soon ;) */
|
|
{ "google-public-dns-a.google.com", "8.8.8.8" },
|
|
};
|
|
const INT TestCount = sizeof(Tests) / sizeof(Tests[0]);
|
|
INT i;
|
|
|
|
/* make sure we don't get IPv6 responses */
|
|
ZeroMemory(&Hints, sizeof(Hints));
|
|
Hints.ai_family = AF_INET;
|
|
|
|
trace("Nodes\n");
|
|
for (i = 0; i < TestCount; i++)
|
|
{
|
|
trace("%d: '%s'\n", i, Tests[i].NodeName);
|
|
StartSeh()
|
|
AddrInfo = InvalidPointer;
|
|
Error = getaddrinfo(Tests[i].NodeName, NULL, &Hints, &AddrInfo);
|
|
if (Tests[i].ExpectedAddress)
|
|
{
|
|
ok_dec(Error, 0);
|
|
ok_dec(WSAGetLastError(), 0);
|
|
ok(AddrInfo != NULL && AddrInfo != InvalidPointer,
|
|
"AddrInfo = %p\n", AddrInfo);
|
|
}
|
|
else
|
|
{
|
|
ok_dec(Error, WSAHOST_NOT_FOUND);
|
|
ok_dec(WSAGetLastError(), WSAHOST_NOT_FOUND);
|
|
ok_ptr(AddrInfo, NULL);
|
|
}
|
|
if (!Error && AddrInfo && AddrInfo != InvalidPointer)
|
|
{
|
|
ok_addrinfo(AddrInfo, Tests[i].Flags, AF_INET,
|
|
0, 0, sizeof(SOCKADDR_IN));
|
|
ok_ptr(AddrInfo->ai_canonname, NULL);
|
|
ok_sockaddr_in(AddrInfo->ai_addr, AF_INET,
|
|
0, Tests[i].ExpectedAddress);
|
|
ok_ptr(AddrInfo->ai_next, NULL);
|
|
freeaddrinfo(AddrInfo);
|
|
}
|
|
EndSeh(STATUS_SUCCESS);
|
|
}
|
|
}
|
|
|
|
static
|
|
VOID
|
|
TestServiceName(VOID)
|
|
{
|
|
int Error;
|
|
PADDRINFOA AddrInfo;
|
|
ADDRINFOA Hints;
|
|
struct
|
|
{
|
|
PCSTR ServiceName;
|
|
INT ExpectedPort;
|
|
INT SockType;
|
|
} Tests[] =
|
|
{
|
|
{ "", 0 },
|
|
{ "0", 0 },
|
|
{ "1", 1 },
|
|
{ "a", -1 },
|
|
{ "010", 10 },
|
|
{ "0x1a", -1 },
|
|
{ "http", 80, SOCK_STREAM },
|
|
{ "smtp", 25, SOCK_STREAM },
|
|
{ "mail", 25, SOCK_STREAM }, /* alias for smtp */
|
|
{ "router", 520, SOCK_DGRAM },
|
|
{ "domain", 53, 0 /* DNS supports both UDP and TCP */ },
|
|
{ ":0", -1 },
|
|
{ "123", 123 },
|
|
{ " 123", 123 },
|
|
{ " 123", 123 },
|
|
{ "32767", 32767 },
|
|
{ "32768", 32768 },
|
|
{ "65535", 65535 },
|
|
{ "65536", 0 },
|
|
{ "65537", 1 },
|
|
{ "65540", 4 },
|
|
{ "65536", 0 },
|
|
{ "4294967295", 65535 },
|
|
{ "4294967296", 65535 },
|
|
{ "9999999999", 65535 },
|
|
{ "999999999999999999999999999999999999", 65535 },
|
|
{ "+5", 5 },
|
|
{ "-1", 65535 },
|
|
{ "-4", 65532 },
|
|
{ "-65534", 2 },
|
|
{ "-65535", 1 },
|
|
{ "-65536", 0 },
|
|
{ "-65537", 65535 },
|
|
{ "28a", -1 },
|
|
{ "28 ", -1 },
|
|
{ "a28", -1 },
|
|
};
|
|
const INT TestCount = sizeof(Tests) / sizeof(Tests[0]);
|
|
INT i;
|
|
|
|
/* make sure we don't get IPv6 responses */
|
|
ZeroMemory(&Hints, sizeof(Hints));
|
|
Hints.ai_family = AF_INET;
|
|
|
|
trace("Services\n");
|
|
for (i = 0; i < TestCount; i++)
|
|
{
|
|
trace("%d: '%s'\n", i, Tests[i].ServiceName);
|
|
StartSeh()
|
|
AddrInfo = InvalidPointer;
|
|
Error = getaddrinfo(NULL, Tests[i].ServiceName, &Hints, &AddrInfo);
|
|
if (Tests[i].ExpectedPort != -1)
|
|
{
|
|
ok_dec(Error, 0);
|
|
ok_dec(WSAGetLastError(), 0);
|
|
ok(AddrInfo != NULL && AddrInfo != InvalidPointer,
|
|
"AddrInfo = %p\n", AddrInfo);
|
|
}
|
|
else
|
|
{
|
|
ok_dec(Error, WSATYPE_NOT_FOUND);
|
|
ok_dec(WSAGetLastError(), WSATYPE_NOT_FOUND);
|
|
ok_ptr(AddrInfo, NULL);
|
|
}
|
|
if (!Error && AddrInfo && AddrInfo != InvalidPointer)
|
|
{
|
|
ok_addrinfo(AddrInfo, 0, AF_INET,
|
|
Tests[i].SockType, 0, sizeof(SOCKADDR_IN));
|
|
ok_ptr(AddrInfo->ai_canonname, NULL);
|
|
ok_sockaddr_in(AddrInfo->ai_addr, AF_INET,
|
|
Tests[i].ExpectedPort, "127.0.0.1");
|
|
ok_ptr(AddrInfo->ai_next, NULL);
|
|
freeaddrinfo(AddrInfo);
|
|
}
|
|
EndSeh(STATUS_SUCCESS);
|
|
}
|
|
}
|
|
|
|
START_TEST(getaddrinfo)
|
|
{
|
|
WSADATA WsaData;
|
|
int Error;
|
|
PADDRINFOA AddrInfo;
|
|
ADDRINFOA Hints;
|
|
CHAR LocalHostName[128];
|
|
struct hostent *Hostent;
|
|
|
|
/* not yet initialized */
|
|
StartSeh()
|
|
Error = getaddrinfo(NULL, NULL, NULL, NULL);
|
|
ok_dec(Error, WSANOTINITIALISED);
|
|
EndSeh(STATUS_SUCCESS);
|
|
StartSeh()
|
|
AddrInfo = InvalidPointer;
|
|
Error = getaddrinfo(NULL, NULL, NULL, &AddrInfo);
|
|
ok_dec(Error, WSANOTINITIALISED);
|
|
ok_ptr(AddrInfo, InvalidPointer);
|
|
EndSeh(STATUS_SUCCESS);
|
|
|
|
Error = getaddrinfo("127.0.0.1", "80", NULL, &AddrInfo);
|
|
ok_dec(Error, WSANOTINITIALISED);
|
|
|
|
Error = WSAStartup(MAKEWORD(2, 2), &WsaData);
|
|
ok_dec(Error, 0);
|
|
|
|
/* initialize LocalAddress for tests */
|
|
Error = gethostname(LocalHostName, sizeof(LocalHostName));
|
|
ok_dec(Error, 0);
|
|
ok_dec(WSAGetLastError(), 0);
|
|
trace("Local host name is '%s'\n", LocalHostName);
|
|
Hostent = gethostbyname(LocalHostName);
|
|
ok(Hostent != NULL, "gethostbyname failed with %d\n", WSAGetLastError());
|
|
if (Hostent && Hostent->h_addr_list[0] && Hostent->h_length == sizeof(IN_ADDR))
|
|
{
|
|
IN_ADDR Address;
|
|
memcpy(&Address, Hostent->h_addr_list[0], sizeof(Address));
|
|
strcpy(LocalAddress, inet_ntoa(Address));
|
|
}
|
|
trace("Local address is '%s'\n", LocalAddress);
|
|
ok(LocalAddress[0] != '\0',
|
|
"Could not determine local address. Following test results may be wrong.\n");
|
|
|
|
ZeroMemory(&Hints, sizeof(Hints));
|
|
/* parameter tests */
|
|
StartSeh() getaddrinfo(NULL, NULL, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
|
|
StartSeh() getaddrinfo("", "", &Hints, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
|
|
StartSeh()
|
|
AddrInfo = InvalidPointer;
|
|
Error = getaddrinfo(NULL, NULL, NULL, &AddrInfo);
|
|
ok_dec(Error, WSAHOST_NOT_FOUND);
|
|
ok_dec(WSAGetLastError(), WSAHOST_NOT_FOUND);
|
|
ok_ptr(AddrInfo, NULL);
|
|
EndSeh(STATUS_SUCCESS);
|
|
|
|
TestNodeName();
|
|
TestServiceName();
|
|
/* TODO: test passing both node name and service name */
|
|
/* TODO: test hints */
|
|
/* TODO: test IPv6 */
|
|
|
|
Error = WSACleanup();
|
|
ok_dec(Error, 0);
|
|
|
|
/* not initialized anymore */
|
|
Error = getaddrinfo("127.0.0.1", "80", NULL, &AddrInfo);
|
|
ok_dec(Error, WSANOTINITIALISED);
|
|
}
|