1 /**
2     Winsock2 Header
3 
4     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
5     Authors: Christopher E. Miller
6 */
7 module nulib.system.win32.winsock2;
8 pragma(lib, "ws2_32");
9 
10 extern (Windows):
11 nothrow:
12 
13 alias SOCKET = size_t;
14 alias socklen_t = int;
15 
16 enum SOCKET INVALID_SOCKET = cast(SOCKET)~0;
17 enum int SOCKET_ERROR = -1;
18 
19 enum WSADESCRIPTION_LEN = 256;
20 enum WSASYS_STATUS_LEN = 128;
21 
22 struct WSADATA {
23     ushort wVersion;
24     ushort wHighVersion;
25     char[WSADESCRIPTION_LEN + 1] szDescription = 0;
26     char[WSASYS_STATUS_LEN + 1] szSystemStatus = 0;
27     ushort iMaxSockets;
28     ushort iMaxUdpDg;
29     char* lpVendorInfo;
30 }
31 
32 alias LPWSADATA = WSADATA*;
33 
34 enum int IOCPARM_MASK = 0x7F;
35 enum int IOC_IN = cast(int) 0x80000000;
36 enum int FIONBIO = cast(int)(IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126);
37 
38 enum NI_MAXHOST = 1025;
39 enum NI_MAXSERV = 32;
40 
41 @nogc {
42     int WSAStartup(ushort wVersionRequested, LPWSADATA lpWSAData);
43     @trusted int WSACleanup();
44     @trusted SOCKET socket(int af, int type, int protocol);
45     int ioctlsocket(SOCKET s, int cmd, uint* argp);
46     int bind(SOCKET s, const(sockaddr)* name, socklen_t namelen);
47     int connect(SOCKET s, const(sockaddr)* name, socklen_t namelen);
48     @trusted int listen(SOCKET s, int backlog);
49     SOCKET accept(SOCKET s, sockaddr* addr, socklen_t* addrlen);
50     @trusted int closesocket(SOCKET s);
51     @trusted int shutdown(SOCKET s, int how);
52     int getpeername(SOCKET s, sockaddr* name, socklen_t* namelen);
53     int getsockname(SOCKET s, sockaddr* name, socklen_t* namelen);
54     int send(SOCKET s, const(void)* buf, int len, int flags);
55     int sendto(SOCKET s, const(void)* buf, int len, int flags, const(sockaddr)* to, socklen_t tolen);
56     int recv(SOCKET s, void* buf, int len, int flags);
57     int recvfrom(SOCKET s, void* buf, int len, int flags, sockaddr* from, socklen_t* fromlen);
58     int getsockopt(SOCKET s, int level, int optname, void* optval, socklen_t* optlen);
59     int setsockopt(SOCKET s, int level, int optname, const(void)* optval, socklen_t optlen);
60     uint inet_addr(const char* cp);
61     int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, const(timeval)* timeout);
62     char* inet_ntoa(in_addr ina);
63     hostent* gethostbyname(const char* name);
64     hostent* gethostbyaddr(const(void)* addr, int len, int type);
65     protoent* getprotobyname(const char* name);
66     protoent* getprotobynumber(int number);
67     servent* getservbyname(const char* name, const char* proto);
68     servent* getservbyport(int port, const char* proto);
69 }
70 
71 enum : int {
72     NI_NOFQDN = 0x01,
73     NI_NUMERICHOST = 0x02,
74     NI_NAMEREQD = 0x04,
75     NI_NUMERICSERV = 0x08,
76     NI_DGRAM = 0x10,
77 }
78 
79 @nogc {
80     int gethostname(const char* name, int namelen);
81     int getaddrinfo(const(char)* nodename, const(char)* servname, const(addrinfo)* hints, addrinfo** res);
82     void freeaddrinfo(addrinfo* ai);
83     int getnameinfo(const(sockaddr)* sa, socklen_t salen, char* host, uint hostlen, char* serv, uint servlen, int flags);
84 }
85 
86 enum WSABASEERR = 10000;
87 
88 enum : int {
89     /*
90      * Windows Sockets definitions of regular Microsoft C error constants
91      */
92     WSAEINTR = (WSABASEERR + 4),
93     WSAEBADF = (WSABASEERR + 9),
94     WSAEACCES = (WSABASEERR + 13),
95     WSAEFAULT = (WSABASEERR + 14),
96     WSAEINVAL = (WSABASEERR + 22),
97     WSAEMFILE = (WSABASEERR + 24),
98 
99     /*
100      * Windows Sockets definitions of regular Berkeley error constants
101      */
102     WSAEWOULDBLOCK = (WSABASEERR + 35),
103     WSAEINPROGRESS = (WSABASEERR + 36),
104     WSAEALREADY = (WSABASEERR + 37),
105     WSAENOTSOCK = (WSABASEERR + 38),
106     WSAEDESTADDRREQ = (WSABASEERR + 39),
107     WSAEMSGSIZE = (WSABASEERR + 40),
108     WSAEPROTOTYPE = (WSABASEERR + 41),
109     WSAENOPROTOOPT = (WSABASEERR + 42),
110     WSAEPROTONOSUPPORT = (WSABASEERR + 43),
111     WSAESOCKTNOSUPPORT = (WSABASEERR + 44),
112     WSAEOPNOTSUPP = (WSABASEERR + 45),
113     WSAEPFNOSUPPORT = (WSABASEERR + 46),
114     WSAEAFNOSUPPORT = (WSABASEERR + 47),
115     WSAEADDRINUSE = (WSABASEERR + 48),
116     WSAEADDRNOTAVAIL = (WSABASEERR + 49),
117     WSAENETDOWN = (WSABASEERR + 50),
118     WSAENETUNREACH = (WSABASEERR + 51),
119     WSAENETRESET = (WSABASEERR + 52),
120     WSAECONNABORTED = (WSABASEERR + 53),
121     WSAECONNRESET = (WSABASEERR + 54),
122     WSAENOBUFS = (WSABASEERR + 55),
123     WSAEISCONN = (WSABASEERR + 56),
124     WSAENOTCONN = (WSABASEERR + 57),
125     WSAESHUTDOWN = (WSABASEERR + 58),
126     WSAETOOMANYREFS = (WSABASEERR + 59),
127     WSAETIMEDOUT = (WSABASEERR + 60),
128     WSAECONNREFUSED = (WSABASEERR + 61),
129     WSAELOOP = (WSABASEERR + 62),
130     WSAENAMETOOLONG = (WSABASEERR + 63),
131     WSAEHOSTDOWN = (WSABASEERR + 64),
132     WSAEHOSTUNREACH = (WSABASEERR + 65),
133     WSAENOTEMPTY = (WSABASEERR + 66),
134     WSAEPROCLIM = (WSABASEERR + 67),
135     WSAEUSERS = (WSABASEERR + 68),
136     WSAEDQUOT = (WSABASEERR + 69),
137     WSAESTALE = (WSABASEERR + 70),
138     WSAEREMOTE = (WSABASEERR + 71),
139 
140     /*
141      * Extended Windows Sockets error constant definitions
142      */
143     WSASYSNOTREADY = (WSABASEERR + 91),
144     WSAVERNOTSUPPORTED = (WSABASEERR + 92),
145     WSANOTINITIALISED = (WSABASEERR + 93),
146 
147     /* Authoritative Answer: Host not found */
148     WSAHOST_NOT_FOUND = (WSABASEERR + 1001),
149     HOST_NOT_FOUND = WSAHOST_NOT_FOUND,
150 
151     /* Non-Authoritative: Host not found, or SERVERFAIL */
152     WSATRY_AGAIN = (WSABASEERR + 1002),
153     TRY_AGAIN = WSATRY_AGAIN,
154 
155     /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
156     WSANO_RECOVERY = (WSABASEERR + 1003),
157     NO_RECOVERY = WSANO_RECOVERY,
158 
159     /* Valid name, no data record of requested type */
160     WSANO_DATA = (WSABASEERR + 1004),
161     NO_DATA = WSANO_DATA,
162 
163     /* no address, look for MX record */
164     WSANO_ADDRESS = WSANO_DATA,
165     NO_ADDRESS = WSANO_ADDRESS
166 }
167 
168 /*
169  * Windows Sockets errors redefined as regular Berkeley error constants
170  */
171 enum : int {
172     EWOULDBLOCK = WSAEWOULDBLOCK,
173     EINPROGRESS = WSAEINPROGRESS,
174     EALREADY = WSAEALREADY,
175     ENOTSOCK = WSAENOTSOCK,
176     EDESTADDRREQ = WSAEDESTADDRREQ,
177     EMSGSIZE = WSAEMSGSIZE,
178     EPROTOTYPE = WSAEPROTOTYPE,
179     ENOPROTOOPT = WSAENOPROTOOPT,
180     EPROTONOSUPPORT = WSAEPROTONOSUPPORT,
181     ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT,
182     EOPNOTSUPP = WSAEOPNOTSUPP,
183     EPFNOSUPPORT = WSAEPFNOSUPPORT,
184     EAFNOSUPPORT = WSAEAFNOSUPPORT,
185     EADDRINUSE = WSAEADDRINUSE,
186     EADDRNOTAVAIL = WSAEADDRNOTAVAIL,
187     ENETDOWN = WSAENETDOWN,
188     ENETUNREACH = WSAENETUNREACH,
189     ENETRESET = WSAENETRESET,
190     ECONNABORTED = WSAECONNABORTED,
191     ECONNRESET = WSAECONNRESET,
192     ENOBUFS = WSAENOBUFS,
193     EISCONN = WSAEISCONN,
194     ENOTCONN = WSAENOTCONN,
195     ESHUTDOWN = WSAESHUTDOWN,
196     ETOOMANYREFS = WSAETOOMANYREFS,
197     ETIMEDOUT = WSAETIMEDOUT,
198     ECONNREFUSED = WSAECONNREFUSED,
199     ELOOP = WSAELOOP,
200     ENAMETOOLONG = WSAENAMETOOLONG,
201     EHOSTDOWN = WSAEHOSTDOWN,
202     EHOSTUNREACH = WSAEHOSTUNREACH,
203     ENOTEMPTY = WSAENOTEMPTY,
204     EPROCLIM = WSAEPROCLIM,
205     EUSERS = WSAEUSERS,
206     EDQUOT = WSAEDQUOT,
207     ESTALE = WSAESTALE,
208     EREMOTE = WSAEREMOTE
209 }
210 
211 enum : int {
212     EAI_NONAME = WSAHOST_NOT_FOUND,
213 }
214 
215 int WSAGetLastError() @trusted @nogc;
216 
217 enum : int {
218     AF_UNSPEC = 0,
219 
220     AF_UNIX = 1,
221     AF_INET = 2,
222     AF_IMPLINK = 3,
223     AF_PUP = 4,
224     AF_CHAOS = 5,
225     AF_NS = 6,
226     AF_IPX = AF_NS,
227     AF_ISO = 7,
228     AF_OSI = AF_ISO,
229     AF_ECMA = 8,
230     AF_DATAKIT = 9,
231     AF_CCITT = 10,
232     AF_SNA = 11,
233     AF_DECnet = 12,
234     AF_DLI = 13,
235     AF_LAT = 14,
236     AF_HYLINK = 15,
237     AF_APPLETALK = 16,
238     AF_NETBIOS = 17,
239     AF_VOICEVIEW = 18,
240     AF_FIREFOX = 19,
241     AF_UNKNOWN1 = 20,
242     AF_BAN = 21,
243     AF_ATM = 22,
244     AF_INET6 = 23,
245     AF_CLUSTER = 24,
246     AF_12844 = 25,
247     AF_IRDA = 26,
248     AF_NETDES = 28,
249 
250     AF_MAX = 29,
251 
252     PF_UNSPEC = AF_UNSPEC,
253 
254     PF_UNIX = AF_UNIX,
255     PF_INET = AF_INET,
256     PF_IMPLINK = AF_IMPLINK,
257     PF_PUP = AF_PUP,
258     PF_CHAOS = AF_CHAOS,
259     PF_NS = AF_NS,
260     PF_IPX = AF_IPX,
261     PF_ISO = AF_ISO,
262     PF_OSI = AF_OSI,
263     PF_ECMA = AF_ECMA,
264     PF_DATAKIT = AF_DATAKIT,
265     PF_CCITT = AF_CCITT,
266     PF_SNA = AF_SNA,
267     PF_DECnet = AF_DECnet,
268     PF_DLI = AF_DLI,
269     PF_LAT = AF_LAT,
270     PF_HYLINK = AF_HYLINK,
271     PF_APPLETALK = AF_APPLETALK,
272     PF_VOICEVIEW = AF_VOICEVIEW,
273     PF_FIREFOX = AF_FIREFOX,
274     PF_UNKNOWN1 = AF_UNKNOWN1,
275     PF_BAN = AF_BAN,
276     PF_INET6 = AF_INET6,
277 
278     PF_MAX = AF_MAX,
279 }
280 
281 enum : int {
282     SOL_SOCKET = 0xFFFF,
283 }
284 
285 enum : int {
286     SO_DEBUG = 0x0001,
287     SO_ACCEPTCONN = 0x0002,
288     SO_REUSEADDR = 0x0004,
289     SO_KEEPALIVE = 0x0008,
290     SO_DONTROUTE = 0x0010,
291     SO_BROADCAST = 0x0020,
292     SO_USELOOPBACK = 0x0040,
293     SO_LINGER = 0x0080,
294     SO_DONTLINGER = ~SO_LINGER,
295     SO_OOBINLINE = 0x0100,
296     SO_SNDBUF = 0x1001,
297     SO_RCVBUF = 0x1002,
298     SO_SNDLOWAT = 0x1003,
299     SO_RCVLOWAT = 0x1004,
300     SO_SNDTIMEO = 0x1005,
301     SO_RCVTIMEO = 0x1006,
302     SO_ERROR = 0x1007,
303     SO_TYPE = 0x1008,
304     SO_EXCLUSIVEADDRUSE = ~SO_REUSEADDR,
305 
306     TCP_NODELAY = 1,
307 
308     IP_OPTIONS = 1,
309 
310     IP_HDRINCL = 2,
311     IP_TOS = 3,
312     IP_TTL = 4,
313     IP_MULTICAST_IF = 9,
314     IP_MULTICAST_TTL = 10,
315     IP_MULTICAST_LOOP = 11,
316     IP_ADD_MEMBERSHIP = 12,
317     IP_DROP_MEMBERSHIP = 13,
318     IP_DONTFRAGMENT = 14,
319     IP_ADD_SOURCE_MEMBERSHIP = 15,
320     IP_DROP_SOURCE_MEMBERSHIP = 16,
321     IP_BLOCK_SOURCE = 17,
322     IP_UNBLOCK_SOURCE = 18,
323     IP_PKTINFO = 19,
324 
325     IPV6_UNICAST_HOPS = 4,
326     IPV6_MULTICAST_IF = 9,
327     IPV6_MULTICAST_HOPS = 10,
328     IPV6_MULTICAST_LOOP = 11,
329     IPV6_ADD_MEMBERSHIP = 12,
330     IPV6_DROP_MEMBERSHIP = 13,
331     IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP,
332     IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP,
333     IPV6_V6ONLY = 27,
334 }
335 
336 /// Default FD_SETSIZE value.
337 /// In C/C++, it is redefinable by #define-ing the macro before #include-ing
338 /// winsock.h. In D, use the $(D FD_CREATE) function to allocate a $(D fd_set)
339 /// of an arbitrary size.
340 enum int FD_SETSIZE = 64;
341 
342 struct fd_set_custom(uint SETSIZE) {
343     uint fd_count;
344     SOCKET[SETSIZE] fd_array;
345 }
346 
347 alias fd_set = fd_set_custom!FD_SETSIZE;
348 
349 // Removes.
350 void FD_CLR(SOCKET fd, fd_set* set) pure @nogc {
351     uint c = set.fd_count;
352     SOCKET* start = set.fd_array.ptr;
353     SOCKET* stop = start + c;
354 
355     for (; start != stop; start++) {
356         if (*start == fd)
357             goto found;
358     }
359     return; //not found
360 
361     found: for (++start; start != stop; start++) {
362         *(start - 1) = *start;
363     }
364 
365     set.fd_count = c - 1;
366 }
367 
368 // Tests.
369 int FD_ISSET(SOCKET fd, const(fd_set)* set) pure @nogc {
370     const(SOCKET)* start = set.fd_array.ptr;
371     const(SOCKET)* stop = start + set.fd_count;
372 
373     for (; start != stop; start++) {
374         if (*start == fd)
375             return true;
376     }
377     return false;
378 }
379 
380 // Adds.
381 void FD_SET(SOCKET fd, fd_set* set) pure @nogc {
382     uint c = set.fd_count;
383     set.fd_array.ptr[c] = fd;
384     set.fd_count = c + 1;
385 }
386 
387 // Resets to zero.
388 void FD_ZERO(fd_set* set) pure @nogc {
389     set.fd_count = 0;
390 }
391 
392 /// Creates a new $(D fd_set) with the specified capacity.
393 fd_set* FD_CREATE(uint capacity) pure {
394     // Take into account alignment (SOCKET may be 64-bit and require 64-bit alignment on 64-bit systems)
395     size_t size = (fd_set_custom!1).sizeof - SOCKET.sizeof + (SOCKET.sizeof * capacity);
396     auto data = new ubyte[size];
397     auto set = cast(fd_set*) data.ptr;
398     FD_ZERO(set);
399     return set;
400 }
401 
402 struct linger {
403     ushort l_onoff;
404     ushort l_linger;
405 }
406 
407 struct protoent {
408     char* p_name;
409     char** p_aliases;
410     short p_proto;
411 }
412 
413 struct servent {
414     char* s_name;
415     char** s_aliases;
416 
417     version (Win64) {
418         char* s_proto;
419         short s_port;
420     } else version (Win32) {
421         short s_port;
422         char* s_proto;
423     }
424 }
425 
426 /+
427 union in6_addr
428 {
429     private union _u_t
430     {
431         ubyte[16] Byte;
432         ushort[8] Word;
433     }
434     _u_t u;
435 }
436 
437 
438 struct in_addr6
439 {
440     ubyte[16] s6_addr;
441 }
442 +/
443 
444 @safe pure @nogc {
445     ushort htons(ushort x);
446     uint htonl(uint x);
447     ushort ntohs(ushort x);
448     uint ntohl(uint x);
449 }
450 
451 enum : int {
452     SOCK_STREAM = 1,
453     SOCK_DGRAM = 2,
454     SOCK_RAW = 3,
455     SOCK_RDM = 4,
456     SOCK_SEQPACKET = 5,
457 }
458 
459 enum : int {
460     IPPROTO_IP = 0,
461     IPPROTO_ICMP = 1,
462     IPPROTO_IGMP = 2,
463     IPPROTO_GGP = 3,
464     IPPROTO_TCP = 6,
465     IPPROTO_PUP = 12,
466     IPPROTO_UDP = 17,
467     IPPROTO_IDP = 22,
468     IPPROTO_IPV6 = 41,
469     IPPROTO_ND = 77,
470     IPPROTO_RAW = 255,
471 
472     IPPROTO_MAX = 256,
473 }
474 
475 enum : int {
476     MSG_OOB = 0x1,
477     MSG_PEEK = 0x2,
478     MSG_DONTROUTE = 0x4
479 }
480 
481 enum : int {
482     SD_RECEIVE = 0,
483     SD_SEND = 1,
484     SD_BOTH = 2,
485 }
486 
487 enum : uint {
488     INADDR_ANY = 0,
489     INADDR_LOOPBACK = 0x7F000001,
490     INADDR_BROADCAST = 0xFFFFFFFF,
491     INADDR_NONE = 0xFFFFFFFF,
492     ADDR_ANY = INADDR_ANY,
493 }
494 
495 enum : int {
496     AI_PASSIVE = 0x1, // Socket address will be used in bind() call
497     AI_CANONNAME = 0x2, // Return canonical name in first ai_canonname
498     AI_NUMERICHOST = 0x4, // Nodename must be a numeric address string
499     AI_NUMERICSERV = 0x8, // Servicename must be a numeric port number
500     AI_DNS_ONLY = 0x10, // Restrict queries to unicast DNS only (no LLMNR, netbios, etc.)
501     AI_FORCE_CLEAR_TEXT = 0x20, // Force clear text DNS query
502     AI_BYPASS_DNS_CACHE = 0x40, // Bypass DNS cache
503     AI_RETURN_TTL = 0x80, // Return record TTL
504     AI_ALL = 0x0100, // Query both IP6 and IP4 with AI_V4MAPPED
505     AI_ADDRCONFIG = 0x0400, // Resolution only if global address configured
506     AI_V4MAPPED = 0x0800, // On v6 failure, query v4 and convert to V4MAPPED format
507     AI_NON_AUTHORITATIVE = 0x04000, // LUP_NON_AUTHORITATIVE
508     AI_SECURE = 0x08000, // LUP_SECURE
509     AI_RETURN_PREFERRED_NAMES = 0x010000, // LUP_RETURN_PREFERRED_NAMES
510     AI_FQDN = 0x00020000, // Return the FQDN in ai_canonname
511     AI_FILESERVER = 0x00040000, // Resolving fileserver name resolution
512     AI_DISABLE_IDN_ENCODING = 0x00080000, // Disable Internationalized Domain Names handling
513     AI_SECURE_WITH_FALLBACK = 0x00100000, // Forces clear text fallback if the secure DNS query fails
514     AI_EXCLUSIVE_CUSTOM_SERVERS = 0x00200000, // Use exclusively the custom DNS servers
515     AI_RETURN_RESPONSE_FLAGS = 0x10000000, // Requests extra information about the DNS results
516     AI_REQUIRE_SECURE = 0x20000000, // Forces the DNS query to be done over seucre protocols
517     AI_RESOLUTION_HANDLE = 0x40000000, // Request resolution handle
518     AI_EXTENDED = 0x80000000, // Indicates this is extended ADDRINFOEX(2/..) struct
519 }
520 
521 struct timeval {
522     int tv_sec;
523     int tv_usec;
524 }
525 
526 union in_addr {
527     private union _S_un_t {
528         private struct _S_un_b_t {
529             ubyte s_b1, s_b2, s_b3, s_b4;
530         }
531 
532         _S_un_b_t S_un_b;
533 
534         private struct _S_un_w_t {
535             ushort s_w1, s_w2;
536         }
537 
538         _S_un_w_t S_un_w;
539 
540         uint S_addr;
541     }
542 
543     _S_un_t S_un;
544 
545     uint s_addr;
546 
547     struct {
548         ubyte s_net, s_host;
549 
550         union {
551             ushort s_imp;
552 
553             struct {
554                 ubyte s_lh, s_impno;
555             }
556         }
557     }
558 }
559 
560 union in6_addr {
561     private union _in6_u_t {
562         ubyte[16] u6_addr8;
563         ushort[8] u6_addr16;
564         uint[4] u6_addr32;
565     }
566 
567     _in6_u_t in6_u;
568 
569     ubyte[16] s6_addr8;
570     ushort[8] s6_addr16;
571     uint[4] s6_addr32;
572 
573     alias s6_addr = s6_addr8;
574 }
575 
576 // enum in6_addr IN6ADDR_ANY = in6_addr([0]);
577 // enum in6_addr IN6ADDR_LOOPBACK = in6_addr([
578 //         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
579 // ]);
580 //alias IN6ADDR_ANY_INIT = IN6ADDR_ANY;
581 //alias IN6ADDR_LOOPBACK_INIT = IN6ADDR_LOOPBACK;
582 
583 enum int INET_ADDRSTRLEN = 16;
584 enum int INET6_ADDRSTRLEN = 46;
585 
586 struct sockaddr {
587     short sa_family;
588     ubyte[14] sa_data;
589 }
590 
591 alias SOCKADDR = sockaddr;
592 alias PSOCKADDR = SOCKADDR*;
593 alias LPSOCKADDR = SOCKADDR*;
594 
595 struct sockaddr_storage {
596     short ss_family;
597     char[6] __ss_pad1 = void;
598     long __ss_align;
599     char[112] __ss_pad2 = void;
600 }
601 
602 alias SOCKADDR_STORAGE = sockaddr_storage;
603 alias PSOCKADDR_STORAGE = SOCKADDR_STORAGE*;
604 
605 struct sockaddr_in {
606     short sin_family = AF_INET;
607     ushort sin_port;
608     in_addr sin_addr;
609     ubyte[8] sin_zero;
610 }
611 
612 alias SOCKADDR_IN = sockaddr_in;
613 alias PSOCKADDR_IN = SOCKADDR_IN*;
614 alias LPSOCKADDR_IN = SOCKADDR_IN*;
615 
616 struct sockaddr_in6 {
617     short sin6_family = AF_INET6;
618     ushort sin6_port;
619     uint sin6_flowinfo;
620     in6_addr sin6_addr;
621     uint sin6_scope_id;
622 }
623 
624 struct addrinfo {
625     int ai_flags;
626     int ai_family;
627     int ai_socktype;
628     int ai_protocol;
629     size_t ai_addrlen;
630     char* ai_canonname;
631     sockaddr* ai_addr;
632     addrinfo* ai_next;
633 }
634 
635 struct hostent {
636     char* h_name;
637     char** h_aliases;
638     short h_addrtype;
639     short h_length;
640     char** h_addr_list;
641 
642     char* h_addr() @safe pure nothrow @nogc {
643         return h_addr_list[0];
644     }
645 }
646 
647 // Note: These are Winsock2!!
648 struct WSAOVERLAPPED;
649 alias LPWSAOVERLAPPED = WSAOVERLAPPED*;
650 alias LPWSAOVERLAPPED_COMPLETION_ROUTINE = void function(uint, uint, LPWSAOVERLAPPED, uint) nothrow @nogc;
651 int WSAIoctl(SOCKET s, uint dwIoControlCode,
652     void* lpvInBuffer, uint cbInBuffer,
653     void* lpvOutBuffer, uint cbOutBuffer,
654     uint* lpcbBytesReturned,
655     LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) @nogc;
656 
657 enum IOC_VENDOR = 0x18000000;
658 enum SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4;
659 
660 /* Argument structure for SIO_KEEPALIVE_VALS */
661 struct tcp_keepalive {
662     uint onoff;
663     uint keepalivetime;
664     uint keepaliveinterval;
665 }
666 
667 struct pollfd {
668     SOCKET fd; // Socket handle
669     short events; // Requested events to monitor
670     short revents; // Returned events indicating status
671 }
672 
673 alias WSAPOLLFD = pollfd;
674 alias PWSAPOLLFD = pollfd*;
675 alias LPWSAPOLLFD = pollfd*;
676 
677 enum : short {
678     POLLRDNORM = 0x0100,
679     POLLRDBAND = 0x0200,
680     POLLIN = (POLLRDNORM | POLLRDBAND),
681     POLLPRI = 0x0400,
682 
683     POLLWRNORM = 0x0010,
684     POLLOUT = (POLLWRNORM),
685     POLLWRBAND = 0x0020,
686 
687     POLLERR = 0x0001,
688     POLLHUP = 0x0002,
689     POLLNVAL = 0x0004
690 }
691 
692 int WSAPoll(LPWSAPOLLFD fdArray, uint fds, int timeout) @nogc;