1 /***********************************************************************\ 2 * winsock.d * 3 * * 4 * Windows API header module * 5 * * 6 * Translated from MinGW Windows headers * 7 * by Stewart Gordon * 8 \***********************************************************************/ 9 module win32.winsock; 10 version(Windows): 11 12 /* 13 Definitions for winsock 1.1 14 15 Portions Copyright (c) 1980, 1983, 1988, 1993 16 The Regents of the University of California. All rights reserved. 17 18 Portions Copyright (c) 1993 by Digital Equipment Corporation. 19 */ 20 21 /* DRK: This module should not be included if -version=Win32_Winsock2 has 22 * been set. If it has, assert. I think it's better that way than letting 23 * the user believe that it's worked. 24 * 25 * SG: It has now been changed so that winsock2 is the default, and 26 * -version=Win32_Winsock1 must be set to use winsock. 27 */ 28 version(Win32_Winsock1) {} 29 else { 30 pragma(msg, "Cannot use win32.winsock without " 31 ~ "Win32_Winsock1 defined."); 32 static assert(false); 33 } 34 35 import win32.windef; 36 37 alias char u_char; 38 alias ushort u_short; 39 alias uint u_int, u_long, SOCKET; 40 41 const size_t FD_SETSIZE = 64; 42 43 // shutdown() how types 44 enum : int { 45 SD_RECEIVE, 46 SD_SEND, 47 SD_BOTH 48 } 49 50 struct FD_SET { 51 u_int fd_count; 52 SOCKET[FD_SETSIZE] fd_array; 53 54 static void opCall(SOCKET fd, FD_SET* set) { 55 if (set.fd_count < FD_SETSIZE) set.fd_array[set.fd_count++] = fd; 56 } 57 } 58 alias FD_SET* PFD_SET, LPFD_SET; 59 60 extern(Pascal) int __WSAFDIsSet(SOCKET, FD_SET*); 61 alias __WSAFDIsSet FD_ISSET; 62 63 void FD_CLR(SOCKET fd, FD_SET* set) { 64 for (u_int i = 0; i < set.fd_count; i++) { 65 if (set.fd_array[i] == fd) { 66 while (i < set.fd_count - 1) { 67 set.fd_array[i] = set.fd_array[i+1]; 68 i++; 69 } 70 set.fd_count--; 71 break; 72 } 73 } 74 } 75 76 /+void FD_SET(SOCKET fd, FD_SET* set) { 77 if (set.fd_count < FD_SETSIZE) set.fd_array[set.fd_count++] = fd; 78 }+/ 79 80 void FD_ZERO(FD_SET* set) { 81 set.fd_count = 0; 82 } 83 84 85 struct TIMEVAL { 86 int tv_sec; 87 int tv_usec; 88 89 int opCmp(TIMEVAL tv) { 90 if (tv_sec < tv.tv_sec) return -1; 91 if (tv_sec > tv.tv_sec) return 1; 92 if (tv_usec < tv.tv_usec) return -1; 93 if (tv_usec > tv.tv_usec) return 1; 94 return 0; 95 } 96 } 97 alias TIMEVAL* PTIMEVAL, LPTIMEVAL; 98 99 bool timerisset(TIMEVAL tvp) { 100 return tvp.tv_sec || tvp.tv_usec; 101 } 102 103 void timerclear(ref TIMEVAL tvp) { 104 tvp.tv_sec = tvp.tv_usec = 0; 105 } 106 107 struct HOSTENT { 108 char* h_name; 109 char** h_aliases; 110 short h_addrtype; 111 short h_length; 112 char** h_addr_list; 113 114 char* h_addr() { return h_addr_list[0]; } 115 char* h_addr(char* h) { return h_addr_list[0] = h; } 116 } 117 alias HOSTENT* PHOSTENT, LPHOSTENT; 118 119 struct LINGER { 120 u_short l_onoff; 121 u_short l_linger; 122 } 123 alias LINGER* PLINGER, LPLINGER; 124 125 // TOTHINKABOUT: do we need these, or are they just for internal use? 126 /+ 127 #define IOCPARM_MASK 0x7f 128 #define IOC_VOID 0x20000000 129 #define IOC_OUT 0x40000000 130 #define IOC_IN 0x80000000 131 #define IOC_INOUT (IOC_IN|IOC_OUT) 132 133 #define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) 134 #define _IOR(x,y,t) (IOC_OUT|(((int)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) 135 #define _IOW(x,y,t) (IOC_IN|(((int)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) 136 137 #define FIONBIO _IOW('f', 126, u_long) 138 #define FIONREAD _IOR('f', 127, u_long) 139 #define FIOASYNC _IOW('f', 125, u_long) 140 #define SIOCSHIWAT _IOW('s', 0, u_long) 141 #define SIOCGHIWAT _IOR('s', 1, u_long) 142 #define SIOCSLOWAT _IOW('s', 2, u_long) 143 #define SIOCGLOWAT _IOR('s', 3, u_long) 144 #define SIOCATMARK _IOR('s', 7, u_long) 145 +/ 146 147 enum : DWORD { 148 FIONBIO = 0x8004667E, 149 FIONREAD = 0x4004667F, 150 FIOASYNC = 0x8004667D, 151 SIOCSHIWAT = 0x80047300, 152 SIOCGHIWAT = 0x40047301, 153 SIOCSLOWAT = 0x80047302, 154 SIOCGLOWAT = 0x40047303, 155 SIOCATMARK = 0x40047307 156 } 157 158 struct netent { 159 char* n_name; 160 char** n_aliases; 161 short n_addrtype; 162 u_long n_net; 163 } 164 165 struct SERVENT { 166 char* s_name; 167 char** s_aliases; 168 short s_port; 169 char* s_proto; 170 } 171 alias SERVENT* PSERVENT, LPSERVENT; 172 173 struct PROTOENT { 174 char* p_name; 175 char** p_aliases; 176 short p_proto; 177 } 178 alias PROTOENT* PPROTOENT, LPPROTOENT; 179 180 enum : int { 181 IPPROTO_IP = 0, 182 IPPROTO_ICMP = 1, 183 IPPROTO_IGMP = 2, 184 IPPROTO_GGP = 3, 185 IPPROTO_TCP = 6, 186 IPPROTO_PUP = 12, 187 IPPROTO_UDP = 17, 188 IPPROTO_IDP = 22, 189 IPPROTO_ND = 77, 190 IPPROTO_RAW = 255, 191 IPPROTO_MAX = 256 192 } 193 194 // These are not documented on the MSDN site 195 enum { 196 IPPORT_ECHO = 7, 197 IPPORT_DISCARD = 9, 198 IPPORT_SYSTAT = 11, 199 IPPORT_DAYTIME = 13, 200 IPPORT_NETSTAT = 15, 201 IPPORT_FTP = 21, 202 IPPORT_TELNET = 23, 203 IPPORT_SMTP = 25, 204 IPPORT_TIMESERVER = 37, 205 IPPORT_NAMESERVER = 42, 206 IPPORT_WHOIS = 43, 207 IPPORT_MTP = 57, 208 IPPORT_TFTP = 69, 209 IPPORT_RJE = 77, 210 IPPORT_FINGER = 79, 211 IPPORT_TTYLINK = 87, 212 IPPORT_SUPDUP = 95, 213 IPPORT_EXECSERVER = 512, 214 IPPORT_LOGINSERVER = 513, 215 IPPORT_CMDSERVER = 514, 216 IPPORT_EFSSERVER = 520, 217 IPPORT_BIFFUDP = 512, 218 IPPORT_WHOSERVER = 513, 219 IPPORT_ROUTESERVER = 520, 220 IPPORT_RESERVED = 1024 221 } 222 223 // These are not documented on the MSDN site 224 enum { 225 IMPLINK_IP = 155, 226 IMPLINK_LOWEXPER = 156, 227 IMPLINK_HIGHEXPER = 158 228 } 229 230 struct IN_ADDR { 231 union { 232 struct { u_char s_net, s_host, s_lh, s_impno; } 233 struct { u_short s_w1, s_imp; } 234 u_long s_addr; 235 } 236 } 237 alias IN_ADDR* PIN_ADDR, LPIN_ADDR; 238 239 // IN_CLASSx are not used anywhere or documented on MSDN. 240 bool IN_CLASSA(int i) { 241 return (i & 0x80000000) == 0; 242 } 243 244 const IN_CLASSA_NET = 0xff000000; 245 const IN_CLASSA_NSHIFT = 24; 246 const IN_CLASSA_HOST = 0x00ffffff; 247 const IN_CLASSA_MAX = 128; 248 249 bool IN_CLASSB(int i) { 250 return (i & 0xC0000000) == 0x80000000; 251 } 252 253 const IN_CLASSB_NET = 0xffff0000; 254 const IN_CLASSB_NSHIFT = 16; 255 const IN_CLASSB_HOST = 0x0000ffff; 256 const IN_CLASSB_MAX = 65536; 257 258 bool IN_CLASSC(int i) { 259 return (i & 0xE0000000) == 0xC0000000; 260 } 261 262 const IN_CLASSC_NET = 0xffffff00; 263 const IN_CLASSC_NSHIFT = 8; 264 const IN_CLASSC_HOST = 0x000000ff; 265 266 const u_long 267 INADDR_ANY = 0, 268 INADDR_LOOPBACK = 0x7F000001, 269 INADDR_BROADCAST = 0xFFFFFFFF, 270 INADDR_NONE = 0xFFFFFFFF; 271 272 struct SOCKADDR_IN { 273 short sin_family; 274 u_short sin_port; 275 IN_ADDR sin_addr; 276 char[8] sin_zero; 277 } 278 alias SOCKADDR_IN* PSOCKADDR_IN, LPSOCKADDR_IN; 279 280 const size_t 281 WSADESCRIPTION_LEN = 256, 282 WSASYS_STATUS_LEN = 128; 283 284 struct WSADATA { 285 WORD wVersion; 286 WORD wHighVersion; 287 char[WSADESCRIPTION_LEN+1] szDescription; 288 char[WSASYS_STATUS_LEN+1] szSystemStatus; 289 ushort iMaxSockets; 290 ushort iMaxUdpDg; 291 char* lpVendorInfo; 292 } 293 alias WSADATA* LPWSADATA; 294 295 // This is not documented on the MSDN site 296 const IP_OPTIONS = 1; 297 298 const int 299 SO_DEBUG = 1, 300 SO_ACCEPTCONN = 2, 301 SO_REUSEADDR = 4, 302 SO_KEEPALIVE = 8, 303 SO_DONTROUTE = 16, 304 SO_BROADCAST = 32, 305 SO_USELOOPBACK = 64, 306 SO_LINGER = 128, 307 SO_OOBINLINE = 256, 308 SO_DONTLINGER = ~SO_LINGER; 309 310 enum : int { 311 SO_SNDBUF = 0x1001, 312 SO_RCVBUF, 313 SO_SNDLOWAT, 314 SO_RCVLOWAT, 315 SO_SNDTIMEO, 316 SO_RCVTIMEO, 317 SO_ERROR, 318 SO_TYPE // = 0x1008 319 } 320 321 /* 322 * Note that the next 5 IP defines are specific to WinSock 1.1 (wsock32.dll). 323 * They will cause errors or unexpected results if used with the 324 * (gs)etsockopts exported from the WinSock 2 lib, ws2_32.dll. Refer ws2tcpip.h. 325 */ 326 enum : int { 327 IP_MULTICAST_IF = 2, 328 IP_MULTICAST_TTL, 329 IP_MULTICAST_LOOP, 330 IP_ADD_MEMBERSHIP, 331 IP_DROP_MEMBERSHIP 332 } 333 334 // These are not documented on the MSDN site 335 const IP_DEFAULT_MULTICAST_TTL = 1; 336 const IP_DEFAULT_MULTICAST_LOOP = 1; 337 const IP_MAX_MEMBERSHIPS = 20; 338 339 struct ip_mreq { 340 IN_ADDR imr_multiaddr; 341 IN_ADDR imr_interface; 342 } 343 344 const SOCKET INVALID_SOCKET = uint.max; 345 const int SOCKET_ERROR = -1; 346 347 enum : int { 348 SOCK_STREAM = 1, 349 SOCK_DGRAM, 350 SOCK_RAW, 351 SOCK_RDM, 352 SOCK_SEQPACKET 353 } 354 355 const int TCP_NODELAY = 1; 356 357 enum : int { 358 AF_UNSPEC, 359 AF_UNIX, 360 AF_INET, 361 AF_IMPLINK, 362 AF_PUP, 363 AF_CHAOS, 364 AF_IPX, // = 6 365 AF_NS = 6, 366 AF_ISO, 367 AF_OSI = AF_ISO, 368 AF_ECMA, 369 AF_DATAKIT, 370 AF_CCITT, 371 AF_SNA, 372 AF_DECnet, 373 AF_DLI, 374 AF_LAT, 375 AF_HYLINK, 376 AF_APPLETALK, 377 AF_NETBIOS, 378 AF_VOICEVIEW, 379 AF_FIREFOX, 380 AF_UNKNOWN1, 381 AF_BAN, 382 AF_ATM, 383 AF_INET6, 384 AF_MAX // = 24 385 } 386 387 struct SOCKADDR { 388 u_short sa_family; 389 char[14] sa_data; 390 } 391 alias SOCKADDR* PSOCKADDR, LPSOCKADDR; 392 393 struct sockproto { 394 u_short sp_family; 395 u_short sp_protocol; 396 } 397 398 enum : int { 399 PF_UNSPEC = AF_UNSPEC, 400 PF_UNIX = AF_UNIX, 401 PF_INET = AF_INET, 402 PF_IMPLINK = AF_IMPLINK, 403 PF_PUP = AF_PUP, 404 PF_CHAOS = AF_CHAOS, 405 PF_NS = AF_NS, 406 PF_IPX = AF_IPX, 407 PF_ISO = AF_ISO, 408 PF_OSI = AF_OSI, 409 PF_ECMA = AF_ECMA, 410 PF_DATAKIT = AF_DATAKIT, 411 PF_CCITT = AF_CCITT, 412 PF_SNA = AF_SNA, 413 PF_DECnet = AF_DECnet, 414 PF_DLI = AF_DLI, 415 PF_LAT = AF_LAT, 416 PF_HYLINK = AF_HYLINK, 417 PF_APPLETALK = AF_APPLETALK, 418 PF_VOICEVIEW = AF_VOICEVIEW, 419 PF_FIREFOX = AF_FIREFOX, 420 PF_UNKNOWN1 = AF_UNKNOWN1, 421 PF_BAN = AF_BAN, 422 PF_ATM = AF_ATM, 423 PF_INET6 = AF_INET6, 424 PF_MAX = AF_MAX 425 } 426 427 const int SOL_SOCKET = 0xFFFF; 428 429 const int SOMAXCONN = 5; 430 431 const int 432 MSG_OOB = 1, 433 MSG_PEEK = 2, 434 MSG_DONTROUTE = 4, 435 MSG_MAXIOVLEN = 16, 436 MSG_PARTIAL = 0x8000; 437 438 const size_t MAXGETHOSTSTRUCT = 1024; 439 440 const int 441 FD_READ = 1, 442 FD_WRITE = 2, 443 FD_OOB = 4, 444 FD_ACCEPT = 8, 445 FD_CONNECT = 16, 446 FD_CLOSE = 32; 447 448 enum : int { 449 WSABASEERR = 10000, 450 WSAEINTR = 10004, 451 WSAEBADF = 10009, 452 WSAEACCES = 10013, 453 WSAEFAULT = 10014, 454 WSAEINVAL = 10022, 455 WSAEMFILE = 10024, 456 WSAEWOULDBLOCK = 10035, 457 WSAEINPROGRESS = 10036, 458 WSAEALREADY = 10037, 459 WSAENOTSOCK = 10038, 460 WSAEDESTADDRREQ = 10039, 461 WSAEMSGSIZE = 10040, 462 WSAEPROTOTYPE = 10041, 463 WSAENOPROTOOPT = 10042, 464 WSAEPROTONOSUPPORT = 10043, 465 WSAESOCKTNOSUPPORT = 10044, 466 WSAEOPNOTSUPP = 10045, 467 WSAEPFNOSUPPORT = 10046, 468 WSAEAFNOSUPPORT = 10047, 469 WSAEADDRINUSE = 10048, 470 WSAEADDRNOTAVAIL = 10049, 471 WSAENETDOWN = 10050, 472 WSAENETUNREACH = 10051, 473 WSAENETRESET = 10052, 474 WSAECONNABORTED = 10053, 475 WSAECONNRESET = 10054, 476 WSAENOBUFS = 10055, 477 WSAEISCONN = 10056, 478 WSAENOTCONN = 10057, 479 WSAESHUTDOWN = 10058, 480 WSAETOOMANYREFS = 10059, 481 WSAETIMEDOUT = 10060, 482 WSAECONNREFUSED = 10061, 483 WSAELOOP = 10062, 484 WSAENAMETOOLONG = 10063, 485 WSAEHOSTDOWN = 10064, 486 WSAEHOSTUNREACH = 10065, 487 WSAENOTEMPTY = 10066, 488 WSAEPROCLIM = 10067, 489 WSAEUSERS = 10068, 490 WSAEDQUOT = 10069, 491 WSAESTALE = 10070, 492 WSAEREMOTE = 10071, 493 WSAEDISCON = 10101, 494 WSASYSNOTREADY = 10091, 495 WSAVERNOTSUPPORTED = 10092, 496 WSANOTINITIALISED = 10093, 497 WSAHOST_NOT_FOUND = 11001, 498 WSATRY_AGAIN = 11002, 499 WSANO_RECOVERY = 11003, 500 WSANO_DATA = 11004, 501 WSANO_ADDRESS = WSANO_DATA 502 } 503 504 alias WSAGetLastError h_errno; 505 506 enum : int { 507 HOST_NOT_FOUND = WSAHOST_NOT_FOUND, 508 TRY_AGAIN = WSATRY_AGAIN, 509 NO_RECOVERY = WSANO_RECOVERY, 510 NO_DATA = WSANO_DATA, 511 NO_ADDRESS = WSANO_ADDRESS 512 } 513 514 extern (Pascal) { 515 SOCKET accept(SOCKET, SOCKADDR*, int*); 516 int bind(SOCKET, const(SOCKADDR)*, int); 517 int closesocket(SOCKET); 518 int connect(SOCKET, const(SOCKADDR)*, int); 519 int ioctlsocket(SOCKET, int, u_long*); 520 int getpeername(SOCKET, SOCKADDR*, int*); 521 int getsockname(SOCKET, SOCKADDR*, int*); 522 int getsockopt(SOCKET, int, int, char*, int*); 523 uint inet_addr(const(char)*); 524 int listen(SOCKET, int); 525 int recv(SOCKET, char*, int, int); 526 int recvfrom(SOCKET, char*, int, int, SOCKADDR*, int*); 527 int send(SOCKET, const(char)*, int, int); 528 int sendto(SOCKET, const(char)*, int, int, const(SOCKADDR)*, int); 529 int setsockopt(SOCKET, int, int, const(char)*, int); 530 int shutdown(SOCKET, int); 531 SOCKET socket(int, int, int); 532 int WSAStartup(WORD, LPWSADATA); 533 int WSACleanup(); 534 void WSASetLastError(int); 535 int WSAGetLastError(); 536 BOOL WSAIsBlocking(); 537 int WSAUnhookBlockingHook(); 538 FARPROC WSASetBlockingHook(FARPROC); 539 int WSACancelBlockingCall(); 540 HANDLE WSAAsyncGetServByName(HWND, u_int, const(char)*, const(char)*, char*, int); 541 HANDLE WSAAsyncGetServByPort(HWND, u_int, int, const(char)*, char*, int); 542 HANDLE WSAAsyncGetProtoByName(HWND, u_int, const(char)*, char*, int); 543 HANDLE WSAAsyncGetProtoByNumber(HWND, u_int, int, char*, int); 544 HANDLE WSAAsyncGetHostByName(HWND, u_int, const(char)*, char*, int); 545 HANDLE WSAAsyncGetHostByAddr(HWND, u_int, const(char)*, int, int, char*, int); 546 int WSACancelAsyncRequest(HANDLE); 547 int WSAAsyncSelect(SOCKET, HWND, u_int, int); 548 u_long htonl(u_long); 549 u_long ntohl(u_long); 550 u_short htons(u_short); 551 u_short ntohs(u_short); 552 int select(int nfds, FD_SET*, FD_SET*, FD_SET*, const(TIMEVAL)*); 553 int gethostname(char*, int); 554 } 555 556 extern (Windows) { 557 char* inet_ntoa(IN_ADDR); 558 HOSTENT* gethostbyaddr(const(char)*, int, int); 559 HOSTENT* gethostbyname(const(char)*); 560 SERVENT* getservbyport(int, const(char)*); 561 SERVENT* getservbyname(const(char)*, const(char)*); 562 PROTOENT* getprotobynumber(int); 563 PROTOENT* getprotobyname(const(char)*); 564 } 565 566 alias MAKELONG WSAMAKEASYNCREPLY, WSAMAKESELECTREPLY; 567 alias LOWORD WSAGETASYNCBUFLEN, WSAGETSELECTEVENT; 568 alias HIWORD WSAGETASYNCERROR, WSAGETSELECTERROR; 569 570 571 /* 572 * Recent MSDN docs indicate that the MS-specific extensions exported from 573 * mswsock.dll (AcceptEx, TransmitFile. WSARecEx and GetAcceptExSockaddrs) are 574 * declared in mswsock.h. These extensions are not supported on W9x or WinCE. 575 * However, code using WinSock 1.1 API may expect the declarations and 576 * associated defines to be in this header. Thus we include mswsock.h here. 577 * 578 * When linking against the WinSock 1.1 lib, wsock32.dll, the mswsock functions 579 * are automatically routed to mswsock.dll (on platforms with support). 580 * The WinSock 2 lib, ws2_32.dll, does not contain any references to 581 * the mswsock extensions. 582 */ 583 584 import win32.mswsock;