* REVISIONS:
* CSH 01/09-2000 Created
*/
-#define __NO_CTYPE_INLINES
#include <ctype.h>
#include <ws2_32.h>
#include <winbase.h>
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
{
UNIMPLEMENTED
- return 0;
+ WSASetLastError(WSASYSCALLFAILURE);
+ return SOCKET_ERROR;
}
/*
- * @implement
+ * @implemented
*/
INT
EXPORT
int res=0;
LONG inetaddr = 0;
LPWSTR *bp=NULL;
+ SOCKADDR_IN *sockaddr;
- SOCKADDR_IN *sockaddr = (SOCKADDR_IN *) lpAddress;
-
- if (!lpAddressLength || !lpAddress)
+ if (!lpAddressLength || !lpAddress || !AddressString)
+ {
+ WSASetLastError(WSAEINVAL);
return SOCKET_ERROR;
+ }
- if (AddressString==NULL)
- return WSAEINVAL;
+ sockaddr = (SOCKADDR_IN *) lpAddress;
/* Set right adress family */
if (lpProtocolInfo!=NULL)
}
else
{
- if (!lpAddress)
- res = WSAEINVAL;
- else
- {
- // translate now ip string to ip
+ // translate ip string to ip
- /* rest sockaddr.sin_addr.s_addr
+ /* rest sockaddr.sin_addr.s_addr
for we need to be sure it is zero when we come to while */
- memset(lpAddress,0,sizeof(SOCKADDR_IN));
+ memset(lpAddress,0,sizeof(SOCKADDR_IN));
- /* Set right adress family */
- sockaddr->sin_family = AF_INET;
+ /* Set right adress family */
+ sockaddr->sin_family = AF_INET;
- /* Get port number */
- pos = wcscspn(AddressString,L":") + 1;
+ /* Get port number */
+ pos = wcscspn(AddressString,L":") + 1;
- if (pos < (int)wcslen(AddressString))
- sockaddr->sin_port = wcstol(&AddressString[pos],
- bp,
- 10);
+ if (pos < (int)wcslen(AddressString))
+ sockaddr->sin_port = wcstol(&AddressString[pos],
+ bp,
+ 10);
- else
- sockaddr->sin_port = 0;
-
- /* Get ip number */
- pos=0;
- inetaddr=0;
+ else
+ sockaddr->sin_port = 0;
- while (pos < (int)wcslen(AddressString))
- {
- inetaddr = (inetaddr<<8) + ((UCHAR)wcstol(&AddressString[pos],
- bp,
- 10));
- pos += wcscspn( &AddressString[pos],L".") +1 ;
- }
+ /* Get ip number */
+ pos=0;
+ inetaddr=0;
- res = 0;
- sockaddr->sin_addr.s_addr = inetaddr;
+ while (pos < (int)wcslen(AddressString))
+ {
+ inetaddr = (inetaddr<<8) + ((UCHAR)wcstol(&AddressString[pos],
+ bp,
+ 10));
+ pos += wcscspn( &AddressString[pos],L".") +1 ;
}
+ res = 0;
+ sockaddr->sin_addr.s_addr = inetaddr;
+
}
}
void free_servent(struct servent* s)
{
+ char* next;
HFREE(s->s_name);
- char* next = s->s_aliases[0];
+ next = s->s_aliases[0];
while(next) { HFREE(next); next++; }
s->s_port = 0;
HFREE(s->s_proto);
DNS_STATUS dns_status = {0};
/* include/WinDNS.h -- look up DNS_RECORD on MSDN */
PDNS_RECORD dp = 0;
+ PWINSOCK_THREAD_BLOCK p;
addr = GH_INVALID;
- PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
+ p = NtCurrentTeb()->WinSockData;
if( !p )
{
*
* @unimplemented
*/
+
+static CHAR *no_aliases = 0;
+static PROTOENT protocols[] =
+{
+ {"icmp",&no_aliases, IPPROTO_ICMP},
+ {"tcp", &no_aliases, IPPROTO_TCP},
+ {"udp", &no_aliases, IPPROTO_UDP},
+ {NULL, NULL, 0}
+};
+
LPPROTOENT
EXPORT
getprotobyname(IN CONST CHAR FAR* name)
{
- static CHAR *udp_aliases = 0;
- static PROTOENT udp = { "udp", &udp_aliases, 17 };
- static CHAR *tcp_aliases = 0;
- static PROTOENT tcp = { "tcp", &tcp_aliases, 6 };
-
- if(!_stricmp(name, "udp"))
- {
- return &udp;
- }
- else if (!_stricmp( name, "tcp"))
+ UINT i;
+ for (i = 0; protocols[i].p_name; i++)
{
- return &tcp;
+ if (_stricmp(protocols[i].p_name, name) == 0)
+ return &protocols[i];
}
-
- return 0;
+ return NULL;
}
/*
EXPORT
getprotobynumber(IN INT number)
{
- UNIMPLEMENTED
-
- return (LPPROTOENT)NULL;
+ UINT i;
+ for (i = 0; protocols[i].p_name; i++)
+ {
+ if (protocols[i].p_proto == number)
+ return &protocols[i];
+ }
+ return NULL;
}
#define SKIPWS(ptr,act) \
p = (PCHAR)cp;
+ if (!p)
+ {
+ WSASetLastError(WSAEFAULT);
+ return INADDR_NONE;
+ }
+
if (strlen(p) == 0)
return INADDR_NONE;
}
-/* EOF */
+/*
+ * @implemented
+ */
+VOID
+EXPORT
+freeaddrinfo(struct addrinfo *pAddrInfo)
+{
+ struct addrinfo *next, *cur;
+ cur = pAddrInfo;
+ while (cur)
+ {
+ next = cur->ai_next;
+ if (cur->ai_addr)
+ HeapFree(GetProcessHeap(), 0, cur->ai_addr);
+ if (cur->ai_canonname)
+ HeapFree(GetProcessHeap(), 0, cur->ai_canonname);
+ HeapFree(GetProcessHeap(), 0, cur);
+ cur = next;
+ }
+}
+
+
+struct addrinfo *
+new_addrinfo(struct addrinfo *prev)
+{
+ struct addrinfo *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct addrinfo));
+ if (prev)
+ prev->ai_next = ret;
+ return ret;
+}
+
+/*
+ * @implemented
+ */
+INT
+EXPORT
+getaddrinfo(const char FAR * nodename,
+ const char FAR * servname,
+ const struct addrinfo FAR * hints,
+ struct addrinfo FAR * FAR * res)
+{
+ struct addrinfo *ret = NULL, *ai;
+ ULONG addr;
+ USHORT port;
+ struct servent *se;
+ char *proto;
+ LPPROTOENT pent;
+ DNS_STATUS dns_status;
+ PDNS_RECORD dp, currdns;
+ struct sockaddr_in *sin;
+
+ if (res == NULL)
+ return WSAEINVAL;
+ if (nodename == NULL && servname == NULL)
+ return WSAHOST_NOT_FOUND;
+
+ if (!WSAINITIALIZED)
+ return WSANOTINITIALISED;
+
+ if (servname)
+ {
+ /* converting port number */
+ port = strtoul(servname, NULL, 10);
+ /* service name was specified? */
+ if (port == 0)
+ {
+ /* protocol was specified? */
+ if (hints && hints->ai_protocol)
+ {
+ pent = getprotobynumber(hints->ai_protocol);
+ if (pent == NULL)
+ return WSAEINVAL;
+ proto = pent->p_name;
+ }
+ else
+ proto = NULL;
+ se = getservbyname(servname, proto);
+ if (se == NULL)
+ return WSATYPE_NOT_FOUND;
+ port = se->s_port;
+ }
+ else
+ port = htons(port);
+ }
+ else
+ port = 0;
+
+ if (nodename)
+ {
+ /* Is it an IPv6 address? */
+ if (strstr(nodename, ":"))
+ return WSAHOST_NOT_FOUND;
+
+ /* Is it an IPv4 address? */
+ addr = inet_addr(nodename);
+ if (addr != INADDR_NONE)
+ {
+ ai = new_addrinfo(NULL);
+ ai->ai_family = PF_INET;
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen);
+ sin = (struct sockaddr_in *)ai->ai_addr;
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ RtlCopyMemory(&sin->sin_addr, &addr, sizeof(sin->sin_addr));
+ if (hints)
+ {
+ if (ai->ai_socktype == 0)
+ ai->ai_socktype = hints->ai_socktype;
+ if (ai->ai_protocol == 0)
+ ai->ai_protocol = hints->ai_protocol;
+ }
+ ret = ai;
+ }
+ else
+ {
+ /* resolving host name */
+ dns_status = DnsQuery_A(nodename,
+ DNS_TYPE_A,
+ DNS_QUERY_STANDARD,
+ 0,
+ /* extra dns servers */ &dp,
+ 0);
+
+ if (dns_status == 0)
+ {
+ ai = NULL;
+ for (currdns = dp; currdns; currdns = currdns->pNext )
+ {
+ /* accept only A records */
+ if (currdns->wType != DNS_TYPE_A) continue;
+
+ ai = new_addrinfo(ai);
+ if (ret == NULL)
+ ret = ai;
+ ai->ai_family = PF_INET;
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen);
+ sin = (struct sockaddr_in *)ret->ai_addr;
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ RtlCopyMemory(&sin->sin_addr, &currdns->Data.A.IpAddress, sizeof(sin->sin_addr));
+ if (hints)
+ {
+ if (ai->ai_socktype == 0)
+ ai->ai_socktype = hints->ai_socktype;
+ if (ai->ai_protocol == 0)
+ ai->ai_protocol = hints->ai_protocol;
+ }
+ }
+ DnsRecordListFree(dp, DnsFreeRecordList);
+ }
+ }
+ }
+ else
+ {
+ ai = new_addrinfo(NULL);
+ ai->ai_family = PF_INET;
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen);
+ sin = (struct sockaddr_in *)ai->ai_addr;
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ if (hints)
+ {
+ if (!(hints->ai_flags & AI_PASSIVE))
+ {
+ sin->sin_addr.S_un.S_un_b.s_b1 = 127;
+ sin->sin_addr.S_un.S_un_b.s_b2 = 0;
+ sin->sin_addr.S_un.S_un_b.s_b3 = 0;
+ sin->sin_addr.S_un.S_un_b.s_b4 = 1;
+ }
+ if (ai->ai_socktype == 0)
+ ai->ai_socktype = hints->ai_socktype;
+ if (ai->ai_protocol == 0)
+ ai->ai_protocol = hints->ai_protocol;
+ }
+ ret = ai;
+ }
+ if (ret == NULL)
+ return WSAHOST_NOT_FOUND;
+
+ if (hints && hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET)
+ {
+ freeaddrinfo(ret);
+ return WSAEAFNOSUPPORT;
+ }
+
+ *res = ret;
+ return 0;
+}
+
+/* EOF */