1 /**
2 * WinPR: Windows Portable Runtime
3 * Windows Sockets (Winsock)
4 *
5 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <winpr/crt.h>
25 #include <winpr/synch.h>
26
27 #include <winpr/winsock.h>
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #ifdef HAVE_SYS_FILIO_H
33 #include <sys/filio.h>
34 #endif
35 #ifdef HAVE_SYS_SOCKIO_H
36 #include <sys/sockio.h>
37 #endif
38
39 #ifndef _WIN32
40 #include <fcntl.h>
41 #endif
42
43 #ifdef __APPLE__
44 #define WSAIOCTL_IFADDRS
45 #include <ifaddrs.h>
46 #endif
47
48 /**
49 * ws2_32.dll:
50 *
51 * __WSAFDIsSet
52 * accept
53 * bind
54 * closesocket
55 * connect
56 * freeaddrinfo
57 * FreeAddrInfoEx
58 * FreeAddrInfoExW
59 * FreeAddrInfoW
60 * getaddrinfo
61 * GetAddrInfoExA
62 * GetAddrInfoExCancel
63 * GetAddrInfoExOverlappedResult
64 * GetAddrInfoExW
65 * GetAddrInfoW
66 * gethostbyaddr
67 * gethostbyname
68 * gethostname
69 * GetHostNameW
70 * getnameinfo
71 * GetNameInfoW
72 * getpeername
73 * getprotobyname
74 * getprotobynumber
75 * getservbyname
76 * getservbyport
77 * getsockname
78 * getsockopt
79 * htonl
80 * htons
81 * inet_addr
82 * inet_ntoa
83 * inet_ntop
84 * inet_pton
85 * InetNtopW
86 * InetPtonW
87 * ioctlsocket
88 * listen
89 * ntohl
90 * ntohs
91 * recv
92 * recvfrom
93 * select
94 * send
95 * sendto
96 * SetAddrInfoExA
97 * SetAddrInfoExW
98 * setsockopt
99 * shutdown
100 * socket
101 * WahCloseApcHelper
102 * WahCloseHandleHelper
103 * WahCloseNotificationHandleHelper
104 * WahCloseSocketHandle
105 * WahCloseThread
106 * WahCompleteRequest
107 * WahCreateHandleContextTable
108 * WahCreateNotificationHandle
109 * WahCreateSocketHandle
110 * WahDestroyHandleContextTable
111 * WahDisableNonIFSHandleSupport
112 * WahEnableNonIFSHandleSupport
113 * WahEnumerateHandleContexts
114 * WahInsertHandleContext
115 * WahNotifyAllProcesses
116 * WahOpenApcHelper
117 * WahOpenCurrentThread
118 * WahOpenHandleHelper
119 * WahOpenNotificationHandleHelper
120 * WahQueueUserApc
121 * WahReferenceContextByHandle
122 * WahRemoveHandleContext
123 * WahWaitForNotification
124 * WahWriteLSPEvent
125 * WEP
126 * WPUCompleteOverlappedRequest
127 * WPUGetProviderPathEx
128 * WSAAccept
129 * WSAAddressToStringA
130 * WSAAddressToStringW
131 * WSAAdvertiseProvider
132 * WSAAsyncGetHostByAddr
133 * WSAAsyncGetHostByName
134 * WSAAsyncGetProtoByName
135 * WSAAsyncGetProtoByNumber
136 * WSAAsyncGetServByName
137 * WSAAsyncGetServByPort
138 * WSAAsyncSelect
139 * WSACancelAsyncRequest
140 * WSACancelBlockingCall
141 * WSACleanup
142 * WSACloseEvent
143 * WSAConnect
144 * WSAConnectByList
145 * WSAConnectByNameA
146 * WSAConnectByNameW
147 * WSACreateEvent
148 * WSADuplicateSocketA
149 * WSADuplicateSocketW
150 * WSAEnumNameSpaceProvidersA
151 * WSAEnumNameSpaceProvidersExA
152 * WSAEnumNameSpaceProvidersExW
153 * WSAEnumNameSpaceProvidersW
154 * WSAEnumNetworkEvents
155 * WSAEnumProtocolsA
156 * WSAEnumProtocolsW
157 * WSAEventSelect
158 * WSAGetLastError
159 * WSAGetOverlappedResult
160 * WSAGetQOSByName
161 * WSAGetServiceClassInfoA
162 * WSAGetServiceClassInfoW
163 * WSAGetServiceClassNameByClassIdA
164 * WSAGetServiceClassNameByClassIdW
165 * WSAHtonl
166 * WSAHtons
167 * WSAInstallServiceClassA
168 * WSAInstallServiceClassW
169 * WSAIoctl
170 * WSAIsBlocking
171 * WSAJoinLeaf
172 * WSALookupServiceBeginA
173 * WSALookupServiceBeginW
174 * WSALookupServiceEnd
175 * WSALookupServiceNextA
176 * WSALookupServiceNextW
177 * WSANSPIoctl
178 * WSANtohl
179 * WSANtohs
180 * WSAPoll
181 * WSAProviderCompleteAsyncCall
182 * WSAProviderConfigChange
183 * WSApSetPostRoutine
184 * WSARecv
185 * WSARecvDisconnect
186 * WSARecvFrom
187 * WSARemoveServiceClass
188 * WSAResetEvent
189 * WSASend
190 * WSASendDisconnect
191 * WSASendMsg
192 * WSASendTo
193 * WSASetBlockingHook
194 * WSASetEvent
195 * WSASetLastError
196 * WSASetServiceA
197 * WSASetServiceW
198 * WSASocketA
199 * WSASocketW
200 * WSAStartup
201 * WSAStringToAddressA
202 * WSAStringToAddressW
203 * WSAUnadvertiseProvider
204 * WSAUnhookBlockingHook
205 * WSAWaitForMultipleEvents
206 * WSCDeinstallProvider
207 * WSCDeinstallProviderEx
208 * WSCEnableNSProvider
209 * WSCEnumProtocols
210 * WSCEnumProtocolsEx
211 * WSCGetApplicationCategory
212 * WSCGetApplicationCategoryEx
213 * WSCGetProviderInfo
214 * WSCGetProviderPath
215 * WSCInstallNameSpace
216 * WSCInstallNameSpaceEx
217 * WSCInstallNameSpaceEx2
218 * WSCInstallProvider
219 * WSCInstallProviderAndChains
220 * WSCInstallProviderEx
221 * WSCSetApplicationCategory
222 * WSCSetApplicationCategoryEx
223 * WSCSetProviderInfo
224 * WSCUnInstallNameSpace
225 * WSCUnInstallNameSpaceEx2
226 * WSCUpdateProvider
227 * WSCUpdateProviderEx
228 * WSCWriteNameSpaceOrder
229 * WSCWriteProviderOrder
230 * WSCWriteProviderOrderEx
231 */
232
233 #ifdef _WIN32
234
235 #if (_WIN32_WINNT < 0x0600)
236
winpr_inet_ntop(INT Family,PVOID pAddr,PSTR pStringBuf,size_t StringBufSize)237 PCSTR winpr_inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize)
238 {
239 if (Family == AF_INET)
240 {
241 struct sockaddr_in in;
242 memset(&in, 0, sizeof(in));
243 in.sin_family = AF_INET;
244 memcpy(&in.sin_addr, pAddr, sizeof(struct in_addr));
245 getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), pStringBuf, StringBufSize,
246 NULL, 0, NI_NUMERICHOST);
247 return pStringBuf;
248 }
249 else if (Family == AF_INET6)
250 {
251 struct sockaddr_in6 in;
252 memset(&in, 0, sizeof(in));
253 in.sin6_family = AF_INET6;
254 memcpy(&in.sin6_addr, pAddr, sizeof(struct in_addr6));
255 getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6), pStringBuf, StringBufSize,
256 NULL, 0, NI_NUMERICHOST);
257 return pStringBuf;
258 }
259
260 return NULL;
261 }
262
winpr_inet_pton(INT Family,PCSTR pszAddrString,PVOID pAddrBuf)263 INT winpr_inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf)
264 {
265 SOCKADDR_STORAGE addr;
266 int addr_len = sizeof(addr);
267
268 if ((Family != AF_INET) && (Family != AF_INET6))
269 return -1;
270
271 if (WSAStringToAddressA((char*)pszAddrString, Family, NULL, (struct sockaddr*)&addr,
272 &addr_len) != 0)
273 return 0;
274
275 if (Family == AF_INET)
276 {
277 memcpy(pAddrBuf, &((struct sockaddr_in*)&addr)->sin_addr, sizeof(struct in_addr));
278 }
279 else if (Family == AF_INET6)
280 {
281 memcpy(pAddrBuf, &((struct sockaddr_in6*)&addr)->sin6_addr, sizeof(struct in6_addr));
282 }
283
284 return 1;
285 }
286
287 #endif /* (_WIN32_WINNT < 0x0600) */
288
289 #else /* _WIN32 */
290
291 #include <netdb.h>
292 #include <errno.h>
293 #include <unistd.h>
294 #include <sys/ioctl.h>
295 #include <sys/socket.h>
296 #include <netinet/in.h>
297 #include <netinet/tcp.h>
298 #include <net/if.h>
299
300 #ifndef MSG_NOSIGNAL
301 #define MSG_NOSIGNAL 0
302 #endif
303
WSAStartup(WORD wVersionRequired,LPWSADATA lpWSAData)304 int WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
305 {
306 ZeroMemory(lpWSAData, sizeof(WSADATA));
307 lpWSAData->wVersion = wVersionRequired;
308 lpWSAData->wHighVersion = MAKEWORD(2, 2);
309 return 0; /* success */
310 }
311
WSACleanup(void)312 int WSACleanup(void)
313 {
314 return 0; /* success */
315 }
316
WSASetLastError(int iError)317 void WSASetLastError(int iError)
318 {
319 switch (iError)
320 {
321 /* Base error codes */
322 case WSAEINTR:
323 errno = EINTR;
324 break;
325
326 case WSAEBADF:
327 errno = EBADF;
328 break;
329
330 case WSAEACCES:
331 errno = EACCES;
332 break;
333
334 case WSAEFAULT:
335 errno = EFAULT;
336 break;
337
338 case WSAEINVAL:
339 errno = EINVAL;
340 break;
341
342 case WSAEMFILE:
343 errno = EMFILE;
344 break;
345
346 /* BSD sockets error codes */
347
348 case WSAEWOULDBLOCK:
349 errno = EWOULDBLOCK;
350 break;
351
352 case WSAEINPROGRESS:
353 errno = EINPROGRESS;
354 break;
355
356 case WSAEALREADY:
357 errno = EALREADY;
358 break;
359
360 case WSAENOTSOCK:
361 errno = ENOTSOCK;
362 break;
363
364 case WSAEDESTADDRREQ:
365 errno = EDESTADDRREQ;
366 break;
367
368 case WSAEMSGSIZE:
369 errno = EMSGSIZE;
370 break;
371
372 case WSAEPROTOTYPE:
373 errno = EPROTOTYPE;
374 break;
375
376 case WSAENOPROTOOPT:
377 errno = ENOPROTOOPT;
378 break;
379
380 case WSAEPROTONOSUPPORT:
381 errno = EPROTONOSUPPORT;
382 break;
383
384 case WSAESOCKTNOSUPPORT:
385 errno = ESOCKTNOSUPPORT;
386 break;
387
388 case WSAEOPNOTSUPP:
389 errno = EOPNOTSUPP;
390 break;
391
392 case WSAEPFNOSUPPORT:
393 errno = EPFNOSUPPORT;
394 break;
395
396 case WSAEAFNOSUPPORT:
397 errno = EAFNOSUPPORT;
398 break;
399
400 case WSAEADDRINUSE:
401 errno = EADDRINUSE;
402 break;
403
404 case WSAEADDRNOTAVAIL:
405 errno = EADDRNOTAVAIL;
406 break;
407
408 case WSAENETDOWN:
409 errno = ENETDOWN;
410 break;
411
412 case WSAENETUNREACH:
413 errno = ENETUNREACH;
414 break;
415
416 case WSAENETRESET:
417 errno = ENETRESET;
418 break;
419
420 case WSAECONNABORTED:
421 errno = ECONNABORTED;
422 break;
423
424 case WSAECONNRESET:
425 errno = ECONNRESET;
426 break;
427
428 case WSAENOBUFS:
429 errno = ENOBUFS;
430 break;
431
432 case WSAEISCONN:
433 errno = EISCONN;
434 break;
435
436 case WSAENOTCONN:
437 errno = ENOTCONN;
438 break;
439
440 case WSAESHUTDOWN:
441 errno = ESHUTDOWN;
442 break;
443
444 case WSAETOOMANYREFS:
445 errno = ETOOMANYREFS;
446 break;
447
448 case WSAETIMEDOUT:
449 errno = ETIMEDOUT;
450 break;
451
452 case WSAECONNREFUSED:
453 errno = ECONNREFUSED;
454 break;
455
456 case WSAELOOP:
457 errno = ELOOP;
458 break;
459
460 case WSAENAMETOOLONG:
461 errno = ENAMETOOLONG;
462 break;
463
464 case WSAEHOSTDOWN:
465 errno = EHOSTDOWN;
466 break;
467
468 case WSAEHOSTUNREACH:
469 errno = EHOSTUNREACH;
470 break;
471
472 case WSAENOTEMPTY:
473 errno = ENOTEMPTY;
474 break;
475 #ifdef EPROCLIM
476
477 case WSAEPROCLIM:
478 errno = EPROCLIM;
479 break;
480 #endif
481
482 case WSAEUSERS:
483 errno = EUSERS;
484 break;
485
486 case WSAEDQUOT:
487 errno = EDQUOT;
488 break;
489
490 case WSAESTALE:
491 errno = ESTALE;
492 break;
493
494 case WSAEREMOTE:
495 errno = EREMOTE;
496 break;
497 }
498 }
499
WSAGetLastError(void)500 int WSAGetLastError(void)
501 {
502 int iError = 0;
503
504 switch (errno)
505 {
506 /* Base error codes */
507 case EINTR:
508 iError = WSAEINTR;
509 break;
510
511 case EBADF:
512 iError = WSAEBADF;
513 break;
514
515 case EACCES:
516 iError = WSAEACCES;
517 break;
518
519 case EFAULT:
520 iError = WSAEFAULT;
521 break;
522
523 case EINVAL:
524 iError = WSAEINVAL;
525 break;
526
527 case EMFILE:
528 iError = WSAEMFILE;
529 break;
530
531 /* BSD sockets error codes */
532
533 case EWOULDBLOCK:
534 iError = WSAEWOULDBLOCK;
535 break;
536
537 case EINPROGRESS:
538 iError = WSAEINPROGRESS;
539 break;
540
541 case EALREADY:
542 iError = WSAEALREADY;
543 break;
544
545 case ENOTSOCK:
546 iError = WSAENOTSOCK;
547 break;
548
549 case EDESTADDRREQ:
550 iError = WSAEDESTADDRREQ;
551 break;
552
553 case EMSGSIZE:
554 iError = WSAEMSGSIZE;
555 break;
556
557 case EPROTOTYPE:
558 iError = WSAEPROTOTYPE;
559 break;
560
561 case ENOPROTOOPT:
562 iError = WSAENOPROTOOPT;
563 break;
564
565 case EPROTONOSUPPORT:
566 iError = WSAEPROTONOSUPPORT;
567 break;
568
569 case ESOCKTNOSUPPORT:
570 iError = WSAESOCKTNOSUPPORT;
571 break;
572
573 case EOPNOTSUPP:
574 iError = WSAEOPNOTSUPP;
575 break;
576
577 case EPFNOSUPPORT:
578 iError = WSAEPFNOSUPPORT;
579 break;
580
581 case EAFNOSUPPORT:
582 iError = WSAEAFNOSUPPORT;
583 break;
584
585 case EADDRINUSE:
586 iError = WSAEADDRINUSE;
587 break;
588
589 case EADDRNOTAVAIL:
590 iError = WSAEADDRNOTAVAIL;
591 break;
592
593 case ENETDOWN:
594 iError = WSAENETDOWN;
595 break;
596
597 case ENETUNREACH:
598 iError = WSAENETUNREACH;
599 break;
600
601 case ENETRESET:
602 iError = WSAENETRESET;
603 break;
604
605 case ECONNABORTED:
606 iError = WSAECONNABORTED;
607 break;
608
609 case ECONNRESET:
610 iError = WSAECONNRESET;
611 break;
612
613 case ENOBUFS:
614 iError = WSAENOBUFS;
615 break;
616
617 case EISCONN:
618 iError = WSAEISCONN;
619 break;
620
621 case ENOTCONN:
622 iError = WSAENOTCONN;
623 break;
624
625 case ESHUTDOWN:
626 iError = WSAESHUTDOWN;
627 break;
628
629 case ETOOMANYREFS:
630 iError = WSAETOOMANYREFS;
631 break;
632
633 case ETIMEDOUT:
634 iError = WSAETIMEDOUT;
635 break;
636
637 case ECONNREFUSED:
638 iError = WSAECONNREFUSED;
639 break;
640
641 case ELOOP:
642 iError = WSAELOOP;
643 break;
644
645 case ENAMETOOLONG:
646 iError = WSAENAMETOOLONG;
647 break;
648
649 case EHOSTDOWN:
650 iError = WSAEHOSTDOWN;
651 break;
652
653 case EHOSTUNREACH:
654 iError = WSAEHOSTUNREACH;
655 break;
656
657 case ENOTEMPTY:
658 iError = WSAENOTEMPTY;
659 break;
660 #ifdef EPROCLIM
661
662 case EPROCLIM:
663 iError = WSAEPROCLIM;
664 break;
665 #endif
666
667 case EUSERS:
668 iError = WSAEUSERS;
669 break;
670
671 case EDQUOT:
672 iError = WSAEDQUOT;
673 break;
674
675 case ESTALE:
676 iError = WSAESTALE;
677 break;
678
679 case EREMOTE:
680 iError = WSAEREMOTE;
681 break;
682 /* Special cases */
683 #if (EAGAIN != EWOULDBLOCK)
684
685 case EAGAIN:
686 iError = WSAEWOULDBLOCK;
687 break;
688 #endif
689 #if defined(EPROTO)
690
691 case EPROTO:
692 iError = WSAECONNRESET;
693 break;
694 #endif
695 }
696
697 /**
698 * Windows Sockets Extended Error Codes:
699 *
700 * WSASYSNOTREADY
701 * WSAVERNOTSUPPORTED
702 * WSANOTINITIALISED
703 * WSAEDISCON
704 * WSAENOMORE
705 * WSAECANCELLED
706 * WSAEINVALIDPROCTABLE
707 * WSAEINVALIDPROVIDER
708 * WSAEPROVIDERFAILEDINIT
709 * WSASYSCALLFAILURE
710 * WSASERVICE_NOT_FOUND
711 * WSATYPE_NOT_FOUND
712 * WSA_E_NO_MORE
713 * WSA_E_CANCELLED
714 * WSAEREFUSED
715 */
716 return iError;
717 }
718
WSACreateEvent(void)719 HANDLE WSACreateEvent(void)
720 {
721 return CreateEvent(NULL, TRUE, FALSE, NULL);
722 }
723
WSASetEvent(HANDLE hEvent)724 BOOL WSASetEvent(HANDLE hEvent)
725 {
726 return SetEvent(hEvent);
727 }
728
WSAResetEvent(HANDLE hEvent)729 BOOL WSAResetEvent(HANDLE hEvent)
730 {
731 /* POSIX systems auto reset the socket,
732 * if no more data is available. */
733 return TRUE;
734 }
735
WSACloseEvent(HANDLE hEvent)736 BOOL WSACloseEvent(HANDLE hEvent)
737 {
738 BOOL status;
739 status = CloseHandle(hEvent);
740
741 if (!status)
742 SetLastError(6);
743
744 return status;
745 }
746
WSAEventSelect(SOCKET s,WSAEVENT hEventObject,LONG lNetworkEvents)747 int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, LONG lNetworkEvents)
748 {
749 u_long arg = 1;
750 ULONG mode = 0;
751
752 if (_ioctlsocket(s, FIONBIO, &arg) != 0)
753 return SOCKET_ERROR;
754
755 if (arg == 0)
756 return 0;
757
758 if (lNetworkEvents & FD_READ)
759 mode |= WINPR_FD_READ;
760
761 if (lNetworkEvents & FD_WRITE)
762 mode |= WINPR_FD_WRITE;
763
764 if (SetEventFileDescriptor(hEventObject, s, mode) < 0)
765 return SOCKET_ERROR;
766
767 return 0;
768 }
769
WSAWaitForMultipleEvents(DWORD cEvents,const HANDLE * lphEvents,BOOL fWaitAll,DWORD dwTimeout,BOOL fAlertable)770 DWORD WSAWaitForMultipleEvents(DWORD cEvents, const HANDLE* lphEvents, BOOL fWaitAll,
771 DWORD dwTimeout, BOOL fAlertable)
772 {
773 return WaitForMultipleObjectsEx(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable);
774 }
775
WSASocketA(int af,int type,int protocol,LPWSAPROTOCOL_INFOA lpProtocolInfo,GROUP g,DWORD dwFlags)776 SOCKET WSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g,
777 DWORD dwFlags)
778 {
779 SOCKET s;
780 s = _socket(af, type, protocol);
781 return s;
782 }
783
WSASocketW(int af,int type,int protocol,LPWSAPROTOCOL_INFOW lpProtocolInfo,GROUP g,DWORD dwFlags)784 SOCKET WSASocketW(int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g,
785 DWORD dwFlags)
786 {
787 return WSASocketA(af, type, protocol, (LPWSAPROTOCOL_INFOA)lpProtocolInfo, g, dwFlags);
788 }
789
WSAIoctl(SOCKET s,DWORD dwIoControlCode,LPVOID lpvInBuffer,DWORD cbInBuffer,LPVOID lpvOutBuffer,DWORD cbOutBuffer,LPDWORD lpcbBytesReturned,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)790 int WSAIoctl(SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
791 LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
792 LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
793 {
794 int fd;
795 int index;
796 ULONG nFlags;
797 size_t offset;
798 size_t ifreq_len;
799 struct ifreq* ifreq;
800 struct ifconf ifconf;
801 char address[128];
802 char broadcast[128];
803 char netmask[128];
804 char buffer[4096];
805 int numInterfaces;
806 int maxNumInterfaces;
807 INTERFACE_INFO* pInterface;
808 INTERFACE_INFO* pInterfaces;
809 struct sockaddr_in* pAddress;
810 struct sockaddr_in* pBroadcast;
811 struct sockaddr_in* pNetmask;
812
813 if ((dwIoControlCode != SIO_GET_INTERFACE_LIST) ||
814 (!lpvOutBuffer || !cbOutBuffer || !lpcbBytesReturned))
815 {
816 WSASetLastError(WSAEINVAL);
817 return SOCKET_ERROR;
818 }
819
820 fd = (int)s;
821 pInterfaces = (INTERFACE_INFO*)lpvOutBuffer;
822 maxNumInterfaces = cbOutBuffer / sizeof(INTERFACE_INFO);
823 #ifdef WSAIOCTL_IFADDRS
824 {
825 struct ifaddrs* ifa = NULL;
826 struct ifaddrs* ifap = NULL;
827
828 if (getifaddrs(&ifap) != 0)
829 {
830 WSASetLastError(WSAENETDOWN);
831 return SOCKET_ERROR;
832 }
833
834 index = 0;
835 numInterfaces = 0;
836
837 for (ifa = ifap; ifa; ifa = ifa->ifa_next)
838 {
839 pInterface = &pInterfaces[index];
840 pAddress = (struct sockaddr_in*)&pInterface->iiAddress;
841 pBroadcast = (struct sockaddr_in*)&pInterface->iiBroadcastAddress;
842 pNetmask = (struct sockaddr_in*)&pInterface->iiNetmask;
843 nFlags = 0;
844
845 if (ifa->ifa_flags & IFF_UP)
846 nFlags |= _IFF_UP;
847
848 if (ifa->ifa_flags & IFF_BROADCAST)
849 nFlags |= _IFF_BROADCAST;
850
851 if (ifa->ifa_flags & IFF_LOOPBACK)
852 nFlags |= _IFF_LOOPBACK;
853
854 if (ifa->ifa_flags & IFF_POINTOPOINT)
855 nFlags |= _IFF_POINTTOPOINT;
856
857 if (ifa->ifa_flags & IFF_MULTICAST)
858 nFlags |= _IFF_MULTICAST;
859
860 pInterface->iiFlags = nFlags;
861
862 if (ifa->ifa_addr)
863 {
864 if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6))
865 continue;
866
867 getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr), address, sizeof(address), 0, 0,
868 NI_NUMERICHOST);
869 inet_pton(ifa->ifa_addr->sa_family, address, (void*)&pAddress->sin_addr);
870 }
871 else
872 {
873 ZeroMemory(pAddress, sizeof(struct sockaddr_in));
874 }
875
876 if (ifa->ifa_dstaddr)
877 {
878 if ((ifa->ifa_dstaddr->sa_family != AF_INET) &&
879 (ifa->ifa_dstaddr->sa_family != AF_INET6))
880 continue;
881
882 getnameinfo(ifa->ifa_dstaddr, sizeof(struct sockaddr), broadcast, sizeof(broadcast),
883 0, 0, NI_NUMERICHOST);
884 inet_pton(ifa->ifa_dstaddr->sa_family, broadcast, (void*)&pBroadcast->sin_addr);
885 }
886 else
887 {
888 ZeroMemory(pBroadcast, sizeof(struct sockaddr_in));
889 }
890
891 if (ifa->ifa_netmask)
892 {
893 if ((ifa->ifa_netmask->sa_family != AF_INET) &&
894 (ifa->ifa_netmask->sa_family != AF_INET6))
895 continue;
896
897 getnameinfo(ifa->ifa_netmask, sizeof(struct sockaddr), netmask, sizeof(netmask), 0,
898 0, NI_NUMERICHOST);
899 inet_pton(ifa->ifa_netmask->sa_family, netmask, (void*)&pNetmask->sin_addr);
900 }
901 else
902 {
903 ZeroMemory(pNetmask, sizeof(struct sockaddr_in));
904 }
905
906 numInterfaces++;
907 index++;
908 }
909
910 *lpcbBytesReturned = (DWORD)(numInterfaces * sizeof(INTERFACE_INFO));
911 freeifaddrs(ifap);
912 return 0;
913 }
914 #endif
915 ifconf.ifc_len = sizeof(buffer);
916 ifconf.ifc_buf = buffer;
917
918 if (ioctl(fd, SIOCGIFCONF, &ifconf) != 0)
919 {
920 WSASetLastError(WSAENETDOWN);
921 return SOCKET_ERROR;
922 }
923
924 index = 0;
925 offset = 0;
926 numInterfaces = 0;
927 ifreq = ifconf.ifc_req;
928
929 while ((ifconf.ifc_len >= 0) && (offset < (size_t)ifconf.ifc_len) &&
930 (numInterfaces < maxNumInterfaces))
931 {
932 pInterface = &pInterfaces[index];
933 pAddress = (struct sockaddr_in*)&pInterface->iiAddress;
934 pBroadcast = (struct sockaddr_in*)&pInterface->iiBroadcastAddress;
935 pNetmask = (struct sockaddr_in*)&pInterface->iiNetmask;
936
937 if (ioctl(fd, SIOCGIFFLAGS, ifreq) != 0)
938 goto next_ifreq;
939
940 nFlags = 0;
941
942 if (ifreq->ifr_flags & IFF_UP)
943 nFlags |= _IFF_UP;
944
945 if (ifreq->ifr_flags & IFF_BROADCAST)
946 nFlags |= _IFF_BROADCAST;
947
948 if (ifreq->ifr_flags & IFF_LOOPBACK)
949 nFlags |= _IFF_LOOPBACK;
950
951 if (ifreq->ifr_flags & IFF_POINTOPOINT)
952 nFlags |= _IFF_POINTTOPOINT;
953
954 if (ifreq->ifr_flags & IFF_MULTICAST)
955 nFlags |= _IFF_MULTICAST;
956
957 pInterface->iiFlags = nFlags;
958
959 if (ioctl(fd, SIOCGIFADDR, ifreq) != 0)
960 goto next_ifreq;
961
962 if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
963 goto next_ifreq;
964
965 getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), address, sizeof(address), 0, 0,
966 NI_NUMERICHOST);
967 inet_pton(ifreq->ifr_addr.sa_family, address, (void*)&pAddress->sin_addr);
968
969 if (ioctl(fd, SIOCGIFBRDADDR, ifreq) != 0)
970 goto next_ifreq;
971
972 if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
973 goto next_ifreq;
974
975 getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), broadcast, sizeof(broadcast), 0, 0,
976 NI_NUMERICHOST);
977 inet_pton(ifreq->ifr_addr.sa_family, broadcast, (void*)&pBroadcast->sin_addr);
978
979 if (ioctl(fd, SIOCGIFNETMASK, ifreq) != 0)
980 goto next_ifreq;
981
982 if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
983 goto next_ifreq;
984
985 getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), netmask, sizeof(netmask), 0, 0,
986 NI_NUMERICHOST);
987 inet_pton(ifreq->ifr_addr.sa_family, netmask, (void*)&pNetmask->sin_addr);
988 numInterfaces++;
989 next_ifreq:
990 #if !defined(__linux__) && !defined(__sun__) && !defined(__CYGWIN__)
991 ifreq_len = IFNAMSIZ + ifreq->ifr_addr.sa_len;
992 #else
993 ifreq_len = sizeof(*ifreq);
994 #endif
995 ifreq = (struct ifreq*)&((BYTE*)ifreq)[ifreq_len];
996 offset += ifreq_len;
997 index++;
998 }
999
1000 *lpcbBytesReturned = (DWORD)(numInterfaces * sizeof(INTERFACE_INFO));
1001 return 0;
1002 }
1003
_accept(SOCKET s,struct sockaddr * addr,int * addrlen)1004 SOCKET _accept(SOCKET s, struct sockaddr* addr, int* addrlen)
1005 {
1006 int status;
1007 int fd = (int)s;
1008 socklen_t s_addrlen = (socklen_t)*addrlen;
1009 status = accept(fd, addr, &s_addrlen);
1010 *addrlen = (socklen_t)s_addrlen;
1011 return status;
1012 }
1013
_bind(SOCKET s,const struct sockaddr * addr,int namelen)1014 int _bind(SOCKET s, const struct sockaddr* addr, int namelen)
1015 {
1016 int status;
1017 int fd = (int)s;
1018 status = bind(fd, addr, (socklen_t)namelen);
1019
1020 if (status < 0)
1021 return SOCKET_ERROR;
1022
1023 return status;
1024 }
1025
closesocket(SOCKET s)1026 int closesocket(SOCKET s)
1027 {
1028 int status;
1029 int fd = (int)s;
1030 status = close(fd);
1031 return status;
1032 }
1033
_connect(SOCKET s,const struct sockaddr * name,int namelen)1034 int _connect(SOCKET s, const struct sockaddr* name, int namelen)
1035 {
1036 int status;
1037 int fd = (int)s;
1038 status = connect(fd, name, (socklen_t)namelen);
1039
1040 if (status < 0)
1041 return SOCKET_ERROR;
1042
1043 return status;
1044 }
1045
_ioctlsocket(SOCKET s,long cmd,u_long * argp)1046 int _ioctlsocket(SOCKET s, long cmd, u_long* argp)
1047 {
1048 int fd = (int)s;
1049
1050 if (cmd == FIONBIO)
1051 {
1052 int flags;
1053
1054 if (!argp)
1055 return SOCKET_ERROR;
1056
1057 flags = fcntl(fd, F_GETFL);
1058
1059 if (flags == -1)
1060 return SOCKET_ERROR;
1061
1062 if (*argp)
1063 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
1064 else
1065 fcntl(fd, F_SETFL, flags & ~(O_NONBLOCK));
1066 }
1067
1068 return 0;
1069 }
1070
_getpeername(SOCKET s,struct sockaddr * name,int * namelen)1071 int _getpeername(SOCKET s, struct sockaddr* name, int* namelen)
1072 {
1073 int status;
1074 int fd = (int)s;
1075 socklen_t s_namelen = (socklen_t)*namelen;
1076 status = getpeername(fd, name, &s_namelen);
1077 *namelen = (int)s_namelen;
1078 return status;
1079 }
1080
_getsockname(SOCKET s,struct sockaddr * name,int * namelen)1081 int _getsockname(SOCKET s, struct sockaddr* name, int* namelen)
1082 {
1083 int status;
1084 int fd = (int)s;
1085 socklen_t s_namelen = (socklen_t)*namelen;
1086 status = getsockname(fd, name, &s_namelen);
1087 *namelen = (int)s_namelen;
1088 return status;
1089 }
1090
_getsockopt(SOCKET s,int level,int optname,char * optval,int * optlen)1091 int _getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen)
1092 {
1093 int status;
1094 int fd = (int)s;
1095 socklen_t s_optlen = (socklen_t)*optlen;
1096 status = getsockopt(fd, level, optname, (void*)optval, &s_optlen);
1097 *optlen = (socklen_t)s_optlen;
1098 return status;
1099 }
1100
_htonl(u_long hostlong)1101 u_long _htonl(u_long hostlong)
1102 {
1103 return htonl(hostlong);
1104 }
1105
_htons(u_short hostshort)1106 u_short _htons(u_short hostshort)
1107 {
1108 return htons(hostshort);
1109 }
1110
_inet_addr(const char * cp)1111 unsigned long _inet_addr(const char* cp)
1112 {
1113 return (long)inet_addr(cp);
1114 }
1115
_inet_ntoa(struct in_addr in)1116 char* _inet_ntoa(struct in_addr in)
1117 {
1118 return inet_ntoa(in);
1119 }
1120
_listen(SOCKET s,int backlog)1121 int _listen(SOCKET s, int backlog)
1122 {
1123 int status;
1124 int fd = (int)s;
1125 status = listen(fd, backlog);
1126 return status;
1127 }
1128
_ntohl(u_long netlong)1129 u_long _ntohl(u_long netlong)
1130 {
1131 return ntohl(netlong);
1132 }
1133
_ntohs(u_short netshort)1134 u_short _ntohs(u_short netshort)
1135 {
1136 return ntohs(netshort);
1137 }
1138
_recv(SOCKET s,char * buf,int len,int flags)1139 int _recv(SOCKET s, char* buf, int len, int flags)
1140 {
1141 int status;
1142 int fd = (int)s;
1143 status = (int)recv(fd, (void*)buf, (size_t)len, flags);
1144 return status;
1145 }
1146
_winsock_recvfrom(SOCKET s,char * buf,int len,int flags,struct sockaddr * from,int * fromlen)1147 int _winsock_recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen)
1148 {
1149 int status;
1150 int fd = (int)s;
1151 socklen_t s_fromlen = (socklen_t)*fromlen;
1152 status = (int)recvfrom(fd, (void*)buf, (size_t)len, flags, from, &s_fromlen);
1153 *fromlen = (int)s_fromlen;
1154 return status;
1155 }
1156
_select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,const struct timeval * timeout)1157 int _select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
1158 const struct timeval* timeout)
1159 {
1160 int status;
1161
1162 do
1163 {
1164 status = select(nfds, readfds, writefds, exceptfds, (struct timeval*)timeout);
1165 } while ((status < 0) && (errno == EINTR));
1166
1167 return status;
1168 }
1169
_send(SOCKET s,const char * buf,int len,int flags)1170 int _send(SOCKET s, const char* buf, int len, int flags)
1171 {
1172 int status;
1173 int fd = (int)s;
1174 flags |= MSG_NOSIGNAL;
1175 status = (int)send(fd, (void*)buf, (size_t)len, flags);
1176 return status;
1177 }
1178
_sendto(SOCKET s,const char * buf,int len,int flags,const struct sockaddr * to,int tolen)1179 int _sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen)
1180 {
1181 int status;
1182 int fd = (int)s;
1183 status = (int)sendto(fd, (void*)buf, (size_t)len, flags, to, (socklen_t)tolen);
1184 return status;
1185 }
1186
_setsockopt(SOCKET s,int level,int optname,const char * optval,int optlen)1187 int _setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen)
1188 {
1189 int status;
1190 int fd = (int)s;
1191 status = setsockopt(fd, level, optname, (void*)optval, (socklen_t)optlen);
1192 return status;
1193 }
1194
_shutdown(SOCKET s,int how)1195 int _shutdown(SOCKET s, int how)
1196 {
1197 int status;
1198 int fd = (int)s;
1199 int s_how = -1;
1200
1201 switch (how)
1202 {
1203 case SD_RECEIVE:
1204 s_how = SHUT_RD;
1205 break;
1206
1207 case SD_SEND:
1208 s_how = SHUT_WR;
1209 break;
1210
1211 case SD_BOTH:
1212 s_how = SHUT_RDWR;
1213 break;
1214 }
1215
1216 if (s_how < 0)
1217 return SOCKET_ERROR;
1218
1219 status = shutdown(fd, s_how);
1220 return status;
1221 }
1222
_socket(int af,int type,int protocol)1223 SOCKET _socket(int af, int type, int protocol)
1224 {
1225 int fd;
1226 SOCKET s;
1227 fd = socket(af, type, protocol);
1228
1229 if (fd < 0)
1230 return INVALID_SOCKET;
1231
1232 s = (SOCKET)fd;
1233 return s;
1234 }
1235
_gethostbyaddr(const char * addr,int len,int type)1236 struct hostent* _gethostbyaddr(const char* addr, int len, int type)
1237 {
1238 struct hostent* host;
1239 host = gethostbyaddr((void*)addr, (socklen_t)len, type);
1240 return host;
1241 }
1242
_gethostbyname(const char * name)1243 struct hostent* _gethostbyname(const char* name)
1244 {
1245 struct hostent* host;
1246 host = gethostbyname(name);
1247 return host;
1248 }
1249
_gethostname(char * name,int namelen)1250 int _gethostname(char* name, int namelen)
1251 {
1252 int status;
1253 status = gethostname(name, (size_t)namelen);
1254 return status;
1255 }
1256
_getservbyport(int port,const char * proto)1257 struct servent* _getservbyport(int port, const char* proto)
1258 {
1259 struct servent* serv;
1260 serv = getservbyport(port, proto);
1261 return serv;
1262 }
1263
_getservbyname(const char * name,const char * proto)1264 struct servent* _getservbyname(const char* name, const char* proto)
1265 {
1266 struct servent* serv;
1267 serv = getservbyname(name, proto);
1268 return serv;
1269 }
1270
_getprotobynumber(int number)1271 struct protoent* _getprotobynumber(int number)
1272 {
1273 struct protoent* proto;
1274 proto = getprotobynumber(number);
1275 return proto;
1276 }
1277
_getprotobyname(const char * name)1278 struct protoent* _getprotobyname(const char* name)
1279 {
1280 struct protoent* proto;
1281 proto = getprotobyname(name);
1282 return proto;
1283 }
1284
1285 #endif /* _WIN32 */
1286