phobos/std/c/windows/winsock.d
2011-05-01 12:11:46 -05:00

540 lines
11 KiB
D

/*
Written by Christopher E. Miller
Placed into public domain.
*/
module std.c.windows.winsock;
private import std.stdint;
private import std.c.windows.windows;
extern(Windows):
alias int SOCKET;
alias uint socklen_t;
const SOCKET INVALID_SOCKET = cast(SOCKET)~0;
const int SOCKET_ERROR = -1;
const int WSADESCRIPTION_LEN = 256;
const int WSASYS_STATUS_LEN = 128;
struct WSADATA
{
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN + 1];
char szSystemStatus[WSASYS_STATUS_LEN + 1];
USHORT iMaxSockets;
USHORT iMaxUdpDg;
char* lpVendorInfo;
}
alias WSADATA* LPWSADATA;
const int IOCPARM_MASK = 0x7F;
const int IOC_IN = cast(int)0x80000000;
const int FIONBIO = cast(int)(IOC_IN | ((UINT.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126);
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
int WSACleanup();
SOCKET socket(int af, int type, int protocol);
int ioctlsocket(SOCKET s, int cmd, uint* argp);
int bind(SOCKET s, sockaddr* name, socklen_t namelen);
int connect(SOCKET s, sockaddr* name, socklen_t namelen);
int listen(SOCKET s, int backlog);
SOCKET accept(SOCKET s, sockaddr* addr, socklen_t* addrlen);
int closesocket(SOCKET s);
int shutdown(SOCKET s, int how);
int getpeername(SOCKET s, sockaddr* name, socklen_t* namelen);
int getsockname(SOCKET s, sockaddr* name, socklen_t* namelen);
int send(SOCKET s, const(void)* buf, int len, int flags);
int sendto(SOCKET s, const(void)* buf, int len, int flags, sockaddr* to, socklen_t tolen);
int recv(SOCKET s, void* buf, int len, int flags);
int recvfrom(SOCKET s, void* buf, int len, int flags, sockaddr* from, socklen_t* fromlen);
int getsockopt(SOCKET s, int level, int optname, void* optval, socklen_t* optlen);
int setsockopt(SOCKET s, int level, int optname, void* optval, socklen_t optlen);
uint inet_addr(const char* cp);
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout);
char* inet_ntoa(in_addr ina);
hostent* gethostbyname(const char* name);
hostent* gethostbyaddr(void* addr, int len, int type);
protoent* getprotobyname(const char* name);
protoent* getprotobynumber(int number);
servent* getservbyname(const char* name, const char* proto);
servent* getservbyport(int port, const char* proto);
int gethostname(const char* name, int namelen);
int getaddrinfo(char* nodename, char* servname, addrinfo* hints, addrinfo** res);
void freeaddrinfo(addrinfo* ai);
int getnameinfo(sockaddr* sa, socklen_t salen, char* host, DWORD hostlen, char* serv, DWORD servlen, int flags);
enum: int
{
WSAEWOULDBLOCK = 10035,
WSAEINTR = 10004,
WSAHOST_NOT_FOUND = 11001,
}
int WSAGetLastError();
enum: int
{
AF_UNSPEC = 0,
AF_UNIX = 1,
AF_INET = 2,
AF_IMPLINK = 3,
AF_PUP = 4,
AF_CHAOS = 5,
AF_NS = 6,
AF_IPX = AF_NS,
AF_ISO = 7,
AF_OSI = AF_ISO,
AF_ECMA = 8,
AF_DATAKIT = 9,
AF_CCITT = 10,
AF_SNA = 11,
AF_DECnet = 12,
AF_DLI = 13,
AF_LAT = 14,
AF_HYLINK = 15,
AF_APPLETALK = 16,
AF_NETBIOS = 17,
AF_VOICEVIEW = 18,
AF_FIREFOX = 19,
AF_UNKNOWN1 = 20,
AF_BAN = 21,
AF_ATM = 22,
AF_INET6 = 23,
AF_CLUSTER = 24,
AF_12844 = 25,
AF_IRDA = 26,
AF_NETDES = 28,
AF_MAX = 29,
PF_UNSPEC = AF_UNSPEC,
PF_UNIX = AF_UNIX,
PF_INET = AF_INET,
PF_IMPLINK = AF_IMPLINK,
PF_PUP = AF_PUP,
PF_CHAOS = AF_CHAOS,
PF_NS = AF_NS,
PF_IPX = AF_IPX,
PF_ISO = AF_ISO,
PF_OSI = AF_OSI,
PF_ECMA = AF_ECMA,
PF_DATAKIT = AF_DATAKIT,
PF_CCITT = AF_CCITT,
PF_SNA = AF_SNA,
PF_DECnet = AF_DECnet,
PF_DLI = AF_DLI,
PF_LAT = AF_LAT,
PF_HYLINK = AF_HYLINK,
PF_APPLETALK = AF_APPLETALK,
PF_VOICEVIEW = AF_VOICEVIEW,
PF_FIREFOX = AF_FIREFOX,
PF_UNKNOWN1 = AF_UNKNOWN1,
PF_BAN = AF_BAN,
PF_INET6 = AF_INET6,
PF_MAX = AF_MAX,
}
enum: int
{
SOL_SOCKET = 0xFFFF,
}
enum: int
{
SO_DEBUG = 0x0001,
SO_ACCEPTCONN = 0x0002,
SO_REUSEADDR = 0x0004,
SO_KEEPALIVE = 0x0008,
SO_DONTROUTE = 0x0010,
SO_BROADCAST = 0x0020,
SO_USELOOPBACK = 0x0040,
SO_LINGER = 0x0080,
SO_DONTLINGER = ~SO_LINGER,
SO_OOBINLINE = 0x0100,
SO_SNDBUF = 0x1001,
SO_RCVBUF = 0x1002,
SO_SNDLOWAT = 0x1003,
SO_RCVLOWAT = 0x1004,
SO_SNDTIMEO = 0x1005,
SO_RCVTIMEO = 0x1006,
SO_ERROR = 0x1007,
SO_TYPE = 0x1008,
SO_EXCLUSIVEADDRUSE = ~SO_REUSEADDR,
TCP_NODELAY = 1,
IP_MULTICAST_LOOP = 0x4,
IP_ADD_MEMBERSHIP = 0x5,
IP_DROP_MEMBERSHIP = 0x6,
IPV6_UNICAST_HOPS = 4,
IPV6_MULTICAST_IF = 9,
IPV6_MULTICAST_HOPS = 10,
IPV6_MULTICAST_LOOP = 11,
IPV6_ADD_MEMBERSHIP = 12,
IPV6_DROP_MEMBERSHIP = 13,
IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP,
IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP,
}
const uint FD_SETSIZE = 64;
struct fd_set
{
UINT fd_count;
SOCKET[FD_SETSIZE] fd_array;
}
// Removes.
void FD_CLR(SOCKET fd, fd_set* set)
{
uint c = set.fd_count;
SOCKET* start = set.fd_array.ptr;
SOCKET* stop = start + c;
for(; start != stop; start++)
{
if(*start == fd)
goto found;
}
return; //not found
found:
for(++start; start != stop; start++)
{
*(start - 1) = *start;
}
set.fd_count = c - 1;
}
// Tests.
int FD_ISSET(SOCKET fd, fd_set* set)
{
SOCKET* start = set.fd_array.ptr;
SOCKET* stop = start + set.fd_count;
for(; start != stop; start++)
{
if(*start == fd)
return true;
}
return false;
}
// Adds.
void FD_SET(SOCKET fd, fd_set* set)
{
uint c = set.fd_count;
set.fd_array.ptr[c] = fd;
set.fd_count = c + 1;
}
// Resets to zero.
void FD_ZERO(fd_set* set)
{
set.fd_count = 0;
}
struct linger
{
USHORT l_onoff;
USHORT l_linger;
}
struct protoent
{
char* p_name;
char** p_aliases;
SHORT p_proto;
}
struct servent
{
char* s_name;
char** s_aliases;
SHORT s_port;
char* s_proto;
}
/+
union in6_addr
{
private union _u_t
{
BYTE[16] Byte;
WORD[8] Word;
}
_u_t u;
}
struct in_addr6
{
BYTE[16] s6_addr;
}
+/
version(BigEndian)
{
uint16_t htons(uint16_t x)
{
return x;
}
uint32_t htonl(uint32_t x)
{
return x;
}
}
else version(LittleEndian)
{
private import core.bitop;
uint16_t htons(uint16_t x)
{
return cast(uint16_t)((x >> 8) | (x << 8));
}
uint32_t htonl(uint32_t x)
{
return bswap(x);
}
}
else
{
static assert(0);
}
uint16_t ntohs(uint16_t x)
{
return htons(x);
}
uint32_t ntohl(uint32_t x)
{
return htonl(x);
}
enum: int
{
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
}
enum: int
{
IPPROTO_IP = 0,
IPPROTO_ICMP = 1,
IPPROTO_IGMP = 2,
IPPROTO_GGP = 3,
IPPROTO_TCP = 6,
IPPROTO_PUP = 12,
IPPROTO_UDP = 17,
IPPROTO_IDP = 22,
IPPROTO_IPV6 = 41,
IPPROTO_ND = 77,
IPPROTO_RAW = 255,
IPPROTO_MAX = 256,
}
enum: int
{
MSG_OOB = 0x1,
MSG_PEEK = 0x2,
MSG_DONTROUTE = 0x4,
MSG_NOSIGNAL = 0x0, /// not supported on win32, would be 0x4000 if it was
}
enum: int
{
SD_RECEIVE = 0,
SD_SEND = 1,
SD_BOTH = 2,
}
enum: uint
{
INADDR_ANY = 0,
INADDR_LOOPBACK = 0x7F000001,
INADDR_BROADCAST = 0xFFFFFFFF,
INADDR_NONE = 0xFFFFFFFF,
ADDR_ANY = INADDR_ANY,
}
enum: int
{
AI_PASSIVE = 0x1,
AI_CANONNAME = 0x2,
AI_NUMERICHOST = 0x4,
}
struct timeval
{
int32_t tv_sec;
int32_t tv_usec;
}
union in_addr
{
private union _S_un_t
{
private struct _S_un_b_t
{
uint8_t s_b1, s_b2, s_b3, s_b4;
}
_S_un_b_t S_un_b;
private struct _S_un_w_t
{
uint16_t s_w1, s_w2;
}
_S_un_w_t S_un_w;
uint32_t S_addr;
}
_S_un_t S_un;
uint32_t s_addr;
struct
{
uint8_t s_net, s_host;
union
{
uint16_t s_imp;
struct
{
uint8_t s_lh, s_impno;
}
}
}
}
union in6_addr
{
private union _in6_u_t
{
uint8_t[16] u6_addr8;
uint16_t[8] u6_addr16;
uint32_t[4] u6_addr32;
}
_in6_u_t in6_u;
uint8_t[16] s6_addr8;
uint16_t[8] s6_addr16;
uint32_t[4] s6_addr32;
alias s6_addr8 s6_addr;
}
const in6_addr IN6ADDR_ANY = { s6_addr8: [0] };
const in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
//alias IN6ADDR_ANY IN6ADDR_ANY_INIT;
//alias IN6ADDR_LOOPBACK IN6ADDR_LOOPBACK_INIT;
const uint INET_ADDRSTRLEN = 16;
const uint INET6_ADDRSTRLEN = 46;
struct sockaddr
{
int16_t sa_family;
ubyte[14] sa_data;
}
struct sockaddr_in
{
int16_t sin_family = AF_INET;
uint16_t sin_port;
in_addr sin_addr;
ubyte[8] sin_zero;
}
struct sockaddr_in6
{
int16_t sin6_family = AF_INET6;
uint16_t sin6_port;
uint32_t sin6_flowinfo;
in6_addr sin6_addr;
uint32_t sin6_scope_id;
}
struct addrinfo
{
int32_t ai_flags;
int32_t ai_family;
int32_t ai_socktype;
int32_t ai_protocol;
size_t ai_addrlen;
char* ai_canonname;
sockaddr* ai_addr;
addrinfo* ai_next;
}
struct hostent
{
char* h_name;
char** h_aliases;
int16_t h_addrtype;
int16_t h_length;
char** h_addr_list;
char* h_addr()
{
return h_addr_list[0];
}
}