FreeRDP
winsock.c
1 
20 #include <winpr/config.h>
21 
22 #include <winpr/assert.h>
23 #include <winpr/crt.h>
24 #include <winpr/synch.h>
25 
26 #include <winpr/winsock.h>
27 
28 #ifdef WINPR_HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #ifdef WINPR_HAVE_SYS_FILIO_H
32 #include <sys/filio.h>
33 #endif
34 #ifdef WINPR_HAVE_SYS_SOCKIO_H
35 #include <sys/sockio.h>
36 #endif
37 
38 #ifndef _WIN32
39 #include <fcntl.h>
40 #endif
41 
42 #ifdef __APPLE__
43 #define WSAIOCTL_IFADDRS
44 #include <ifaddrs.h>
45 #endif
46 
232 #ifdef _WIN32
233 
234 #if (_WIN32_WINNT < 0x0600)
235 
236 PCSTR winpr_inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize)
237 {
238  if (Family == AF_INET)
239  {
240  struct sockaddr_in in = { 0 };
241 
242  in.sin_family = AF_INET;
243  memcpy(&in.sin_addr, pAddr, sizeof(struct in_addr));
244  getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), pStringBuf, StringBufSize,
245  NULL, 0, NI_NUMERICHOST);
246  return pStringBuf;
247  }
248  else if (Family == AF_INET6)
249  {
250  struct sockaddr_in6 in = { 0 };
251 
252  in.sin6_family = AF_INET6;
253  memcpy(&in.sin6_addr, pAddr, sizeof(struct in_addr6));
254  getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6), pStringBuf, StringBufSize,
255  NULL, 0, NI_NUMERICHOST);
256  return pStringBuf;
257  }
258 
259  return NULL;
260 }
261 
262 INT winpr_inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf)
263 {
264  SOCKADDR_STORAGE addr;
265  int addr_len = sizeof(addr);
266 
267  if ((Family != AF_INET) && (Family != AF_INET6))
268  return -1;
269 
270  if (WSAStringToAddressA((char*)pszAddrString, Family, NULL, (struct sockaddr*)&addr,
271  &addr_len) != 0)
272  return 0;
273 
274  if (Family == AF_INET)
275  {
276  memcpy(pAddrBuf, &((struct sockaddr_in*)&addr)->sin_addr, sizeof(struct in_addr));
277  }
278  else if (Family == AF_INET6)
279  {
280  memcpy(pAddrBuf, &((struct sockaddr_in6*)&addr)->sin6_addr, sizeof(struct in6_addr));
281  }
282 
283  return 1;
284 }
285 
286 #endif /* (_WIN32_WINNT < 0x0600) */
287 
288 #else /* _WIN32 */
289 
290 #include <netdb.h>
291 #include <errno.h>
292 #include <sys/ioctl.h>
293 #include <sys/socket.h>
294 #include <netinet/in.h>
295 #include <netinet/tcp.h>
296 #include <net/if.h>
297 
298 #ifndef MSG_NOSIGNAL
299 #define MSG_NOSIGNAL 0
300 #endif
301 
302 int WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
303 {
304  WINPR_ASSERT(lpWSAData);
305 
306  ZeroMemory(lpWSAData, sizeof(WSADATA));
307  lpWSAData->wVersion = wVersionRequired;
308  lpWSAData->wHighVersion = MAKEWORD(2, 2);
309  return 0; /* success */
310 }
311 
312 int WSACleanup(void)
313 {
314  return 0; /* success */
315 }
316 
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  default:
498  break;
499  }
500 }
501 
502 int WSAGetLastError(void)
503 {
504  int iError = 0;
505 
506  switch (errno)
507  {
508  /* Base error codes */
509  case EINTR:
510  iError = WSAEINTR;
511  break;
512 
513  case EBADF:
514  iError = WSAEBADF;
515  break;
516 
517  case EACCES:
518  iError = WSAEACCES;
519  break;
520 
521  case EFAULT:
522  iError = WSAEFAULT;
523  break;
524 
525  case EINVAL:
526  iError = WSAEINVAL;
527  break;
528 
529  case EMFILE:
530  iError = WSAEMFILE;
531  break;
532 
533  /* BSD sockets error codes */
534 
535  case EWOULDBLOCK:
536  iError = WSAEWOULDBLOCK;
537  break;
538 
539  case EINPROGRESS:
540  iError = WSAEINPROGRESS;
541  break;
542 
543  case EALREADY:
544  iError = WSAEALREADY;
545  break;
546 
547  case ENOTSOCK:
548  iError = WSAENOTSOCK;
549  break;
550 
551  case EDESTADDRREQ:
552  iError = WSAEDESTADDRREQ;
553  break;
554 
555  case EMSGSIZE:
556  iError = WSAEMSGSIZE;
557  break;
558 
559  case EPROTOTYPE:
560  iError = WSAEPROTOTYPE;
561  break;
562 
563  case ENOPROTOOPT:
564  iError = WSAENOPROTOOPT;
565  break;
566 
567  case EPROTONOSUPPORT:
568  iError = WSAEPROTONOSUPPORT;
569  break;
570 
571  case ESOCKTNOSUPPORT:
572  iError = WSAESOCKTNOSUPPORT;
573  break;
574 
575  case EOPNOTSUPP:
576  iError = WSAEOPNOTSUPP;
577  break;
578 
579  case EPFNOSUPPORT:
580  iError = WSAEPFNOSUPPORT;
581  break;
582 
583  case EAFNOSUPPORT:
584  iError = WSAEAFNOSUPPORT;
585  break;
586 
587  case EADDRINUSE:
588  iError = WSAEADDRINUSE;
589  break;
590 
591  case EADDRNOTAVAIL:
592  iError = WSAEADDRNOTAVAIL;
593  break;
594 
595  case ENETDOWN:
596  iError = WSAENETDOWN;
597  break;
598 
599  case ENETUNREACH:
600  iError = WSAENETUNREACH;
601  break;
602 
603  case ENETRESET:
604  iError = WSAENETRESET;
605  break;
606 
607  case ECONNABORTED:
608  iError = WSAECONNABORTED;
609  break;
610 
611  case ECONNRESET:
612  iError = WSAECONNRESET;
613  break;
614 
615  case ENOBUFS:
616  iError = WSAENOBUFS;
617  break;
618 
619  case EISCONN:
620  iError = WSAEISCONN;
621  break;
622 
623  case ENOTCONN:
624  iError = WSAENOTCONN;
625  break;
626 
627  case ESHUTDOWN:
628  iError = WSAESHUTDOWN;
629  break;
630 
631  case ETOOMANYREFS:
632  iError = WSAETOOMANYREFS;
633  break;
634 
635  case ETIMEDOUT:
636  iError = WSAETIMEDOUT;
637  break;
638 
639  case ECONNREFUSED:
640  iError = WSAECONNREFUSED;
641  break;
642 
643  case ELOOP:
644  iError = WSAELOOP;
645  break;
646 
647  case ENAMETOOLONG:
648  iError = WSAENAMETOOLONG;
649  break;
650 
651  case EHOSTDOWN:
652  iError = WSAEHOSTDOWN;
653  break;
654 
655  case EHOSTUNREACH:
656  iError = WSAEHOSTUNREACH;
657  break;
658 
659  case ENOTEMPTY:
660  iError = WSAENOTEMPTY;
661  break;
662 #ifdef EPROCLIM
663 
664  case EPROCLIM:
665  iError = WSAEPROCLIM;
666  break;
667 #endif
668 
669  case EUSERS:
670  iError = WSAEUSERS;
671  break;
672 
673  case EDQUOT:
674  iError = WSAEDQUOT;
675  break;
676 
677  case ESTALE:
678  iError = WSAESTALE;
679  break;
680 
681  case EREMOTE:
682  iError = WSAEREMOTE;
683  break;
684  /* Special cases */
685 #if (EAGAIN != EWOULDBLOCK)
686 
687  case EAGAIN:
688  iError = WSAEWOULDBLOCK;
689  break;
690 #endif
691 #if defined(EPROTO)
692 
693  case EPROTO:
694  iError = WSAECONNRESET;
695  break;
696 #endif
697  default:
698  break;
699  }
700 
720  return iError;
721 }
722 
723 HANDLE WSACreateEvent(void)
724 {
725  return CreateEvent(NULL, TRUE, FALSE, NULL);
726 }
727 
728 BOOL WSASetEvent(HANDLE hEvent)
729 {
730  return SetEvent(hEvent);
731 }
732 
733 BOOL WSAResetEvent(HANDLE hEvent)
734 {
735  /* POSIX systems auto reset the socket,
736  * if no more data is available. */
737  return TRUE;
738 }
739 
740 BOOL WSACloseEvent(HANDLE hEvent)
741 {
742  BOOL status = CloseHandle(hEvent);
743 
744  if (!status)
745  SetLastError(6);
746 
747  return status;
748 }
749 
750 int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, LONG lNetworkEvents)
751 {
752  u_long arg = 1;
753  ULONG mode = 0;
754 
755  if (_ioctlsocket(s, FIONBIO, &arg) != 0)
756  return SOCKET_ERROR;
757 
758  if (arg == 0)
759  return 0;
760 
761  if (lNetworkEvents & FD_READ)
762  mode |= WINPR_FD_READ;
763 
764  if (lNetworkEvents & FD_WRITE)
765  mode |= WINPR_FD_WRITE;
766 
767  if (SetEventFileDescriptor(hEventObject, (int)s, mode) < 0)
768  return SOCKET_ERROR;
769 
770  return 0;
771 }
772 
773 DWORD WSAWaitForMultipleEvents(DWORD cEvents, const HANDLE* lphEvents, BOOL fWaitAll,
774  DWORD dwTimeout, BOOL fAlertable)
775 {
776  return WaitForMultipleObjectsEx(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable);
777 }
778 
779 SOCKET WSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g,
780  DWORD dwFlags)
781 {
782  SOCKET s = 0;
783  s = _socket(af, type, protocol);
784  return s;
785 }
786 
787 SOCKET WSASocketW(int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g,
788  DWORD dwFlags)
789 {
790  return WSASocketA(af, type, protocol, (LPWSAPROTOCOL_INFOA)lpProtocolInfo, g, dwFlags);
791 }
792 
793 int WSAIoctl(SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
794  LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
795  LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
796 {
797  int fd = 0;
798  int index = 0;
799  ULONG nFlags = 0;
800  size_t offset = 0;
801  size_t ifreq_len = 0;
802  struct ifreq* ifreq = NULL;
803  struct ifconf ifconf = { 0 };
804  char address[128] = { 0 };
805  char broadcast[128] = { 0 };
806  char netmask[128] = { 0 };
807  char buffer[4096] = { 0 };
808  size_t numInterfaces = 0;
809  size_t maxNumInterfaces = 0;
810  INTERFACE_INFO* pInterface = NULL;
811  INTERFACE_INFO* pInterfaces = NULL;
812  struct sockaddr_in* pAddress = NULL;
813  struct sockaddr_in* pBroadcast = NULL;
814  struct sockaddr_in* pNetmask = NULL;
815 
816  if ((dwIoControlCode != SIO_GET_INTERFACE_LIST) ||
817  (!lpvOutBuffer || !cbOutBuffer || !lpcbBytesReturned))
818  {
819  WSASetLastError(WSAEINVAL);
820  return SOCKET_ERROR;
821  }
822 
823  fd = (int)s;
824  pInterfaces = (INTERFACE_INFO*)lpvOutBuffer;
825  maxNumInterfaces = cbOutBuffer / sizeof(INTERFACE_INFO);
826 #ifdef WSAIOCTL_IFADDRS
827  {
828  struct ifaddrs* ifap = NULL;
829 
830  if (getifaddrs(&ifap) != 0)
831  {
832  WSASetLastError(WSAENETDOWN);
833  return SOCKET_ERROR;
834  }
835 
836  index = 0;
837  numInterfaces = 0;
838 
839  for (struct ifaddrs* ifa = ifap; ifa; ifa = ifa->ifa_next)
840  {
841  pInterface = &pInterfaces[index];
842  pAddress = (struct sockaddr_in*)&pInterface->iiAddress;
843  pBroadcast = (struct sockaddr_in*)&pInterface->iiBroadcastAddress;
844  pNetmask = (struct sockaddr_in*)&pInterface->iiNetmask;
845  nFlags = 0;
846 
847  if (ifa->ifa_flags & IFF_UP)
848  nFlags |= _IFF_UP;
849 
850  if (ifa->ifa_flags & IFF_BROADCAST)
851  nFlags |= _IFF_BROADCAST;
852 
853  if (ifa->ifa_flags & IFF_LOOPBACK)
854  nFlags |= _IFF_LOOPBACK;
855 
856  if (ifa->ifa_flags & IFF_POINTOPOINT)
857  nFlags |= _IFF_POINTTOPOINT;
858 
859  if (ifa->ifa_flags & IFF_MULTICAST)
860  nFlags |= _IFF_MULTICAST;
861 
862  pInterface->iiFlags = nFlags;
863 
864  if (ifa->ifa_addr)
865  {
866  if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6))
867  continue;
868 
869  getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr), address, sizeof(address), 0, 0,
870  NI_NUMERICHOST);
871  inet_pton(ifa->ifa_addr->sa_family, address, (void*)&pAddress->sin_addr);
872  }
873  else
874  {
875  ZeroMemory(pAddress, sizeof(struct sockaddr_in));
876  }
877 
878  if (ifa->ifa_dstaddr)
879  {
880  if ((ifa->ifa_dstaddr->sa_family != AF_INET) &&
881  (ifa->ifa_dstaddr->sa_family != AF_INET6))
882  continue;
883 
884  getnameinfo(ifa->ifa_dstaddr, sizeof(struct sockaddr), broadcast, sizeof(broadcast),
885  0, 0, NI_NUMERICHOST);
886  inet_pton(ifa->ifa_dstaddr->sa_family, broadcast, (void*)&pBroadcast->sin_addr);
887  }
888  else
889  {
890  ZeroMemory(pBroadcast, sizeof(struct sockaddr_in));
891  }
892 
893  if (ifa->ifa_netmask)
894  {
895  if ((ifa->ifa_netmask->sa_family != AF_INET) &&
896  (ifa->ifa_netmask->sa_family != AF_INET6))
897  continue;
898 
899  getnameinfo(ifa->ifa_netmask, sizeof(struct sockaddr), netmask, sizeof(netmask), 0,
900  0, NI_NUMERICHOST);
901  inet_pton(ifa->ifa_netmask->sa_family, netmask, (void*)&pNetmask->sin_addr);
902  }
903  else
904  {
905  ZeroMemory(pNetmask, sizeof(struct sockaddr_in));
906  }
907 
908  numInterfaces++;
909  index++;
910  }
911 
912  *lpcbBytesReturned = (DWORD)(numInterfaces * sizeof(INTERFACE_INFO));
913  freeifaddrs(ifap);
914  return 0;
915  }
916 #endif
917  ifconf.ifc_len = sizeof(buffer);
918  ifconf.ifc_buf = buffer;
919 
920  if (ioctl(fd, SIOCGIFCONF, &ifconf) != 0)
921  {
922  WSASetLastError(WSAENETDOWN);
923  return SOCKET_ERROR;
924  }
925 
926  index = 0;
927  offset = 0;
928  numInterfaces = 0;
929  ifreq = ifconf.ifc_req;
930 
931  while ((ifconf.ifc_len >= 0) && (offset < (size_t)ifconf.ifc_len) &&
932  (numInterfaces < maxNumInterfaces))
933  {
934  pInterface = &pInterfaces[index];
935  pAddress = (struct sockaddr_in*)&pInterface->iiAddress;
936  pBroadcast = (struct sockaddr_in*)&pInterface->iiBroadcastAddress;
937  pNetmask = (struct sockaddr_in*)&pInterface->iiNetmask;
938 
939  if (ioctl(fd, SIOCGIFFLAGS, ifreq) != 0)
940  goto next_ifreq;
941 
942  nFlags = 0;
943 
944  if (ifreq->ifr_flags & IFF_UP)
945  nFlags |= _IFF_UP;
946 
947  if (ifreq->ifr_flags & IFF_BROADCAST)
948  nFlags |= _IFF_BROADCAST;
949 
950  if (ifreq->ifr_flags & IFF_LOOPBACK)
951  nFlags |= _IFF_LOOPBACK;
952 
953  if (ifreq->ifr_flags & IFF_POINTOPOINT)
954  nFlags |= _IFF_POINTTOPOINT;
955 
956  if (ifreq->ifr_flags & IFF_MULTICAST)
957  nFlags |= _IFF_MULTICAST;
958 
959  pInterface->iiFlags = nFlags;
960 
961  if (ioctl(fd, SIOCGIFADDR, ifreq) != 0)
962  goto next_ifreq;
963 
964  if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
965  goto next_ifreq;
966 
967  getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), address, sizeof(address), 0, 0,
968  NI_NUMERICHOST);
969  inet_pton(ifreq->ifr_addr.sa_family, address, (void*)&pAddress->sin_addr);
970 
971  if (ioctl(fd, SIOCGIFBRDADDR, ifreq) != 0)
972  goto next_ifreq;
973 
974  if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
975  goto next_ifreq;
976 
977  getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), broadcast, sizeof(broadcast), 0, 0,
978  NI_NUMERICHOST);
979  inet_pton(ifreq->ifr_addr.sa_family, broadcast, (void*)&pBroadcast->sin_addr);
980 
981  if (ioctl(fd, SIOCGIFNETMASK, ifreq) != 0)
982  goto next_ifreq;
983 
984  if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
985  goto next_ifreq;
986 
987  getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), netmask, sizeof(netmask), 0, 0,
988  NI_NUMERICHOST);
989  inet_pton(ifreq->ifr_addr.sa_family, netmask, (void*)&pNetmask->sin_addr);
990  numInterfaces++;
991  next_ifreq:
992 #if !defined(__linux__) && !defined(__sun__) && !defined(__CYGWIN__) && !defined(EMSCRIPTEN)
993  ifreq_len = IFNAMSIZ + ifreq->ifr_addr.sa_len;
994 #else
995  ifreq_len = sizeof(*ifreq);
996 #endif
997  ifreq = (struct ifreq*)&((BYTE*)ifreq)[ifreq_len];
998  offset += ifreq_len;
999  index++;
1000  }
1001 
1002  *lpcbBytesReturned = (DWORD)(numInterfaces * sizeof(INTERFACE_INFO));
1003  return 0;
1004 }
1005 
1006 SOCKET _accept(SOCKET s, struct sockaddr* addr, int* addrlen)
1007 {
1008  int fd = WINPR_ASSERTING_INT_CAST(int, s);
1009  socklen_t s_addrlen = (socklen_t)*addrlen;
1010  const int status = accept(fd, addr, &s_addrlen);
1011  *addrlen = (int)s_addrlen;
1012  return (SOCKET)status;
1013 }
1014 
1015 int _bind(SOCKET s, const struct sockaddr* addr, int namelen)
1016 {
1017  int status = 0;
1018  int fd = (int)s;
1019  status = bind(fd, addr, (socklen_t)namelen);
1020 
1021  if (status < 0)
1022  return SOCKET_ERROR;
1023 
1024  return status;
1025 }
1026 
1027 int closesocket(SOCKET s)
1028 {
1029  int status = 0;
1030  int fd = (int)s;
1031  status = close(fd);
1032  return status;
1033 }
1034 
1035 int _connect(SOCKET s, const struct sockaddr* name, int namelen)
1036 {
1037  int status = 0;
1038  int fd = (int)s;
1039  status = connect(fd, name, (socklen_t)namelen);
1040 
1041  if (status < 0)
1042  return SOCKET_ERROR;
1043 
1044  return status;
1045 }
1046 
1047 // NOLINTNEXTLINE(readability-non-const-parameter)
1048 int _ioctlsocket(SOCKET s, long cmd, u_long* argp)
1049 {
1050  int fd = (int)s;
1051 
1052  if (cmd == FIONBIO)
1053  {
1054  int flags = 0;
1055 
1056  if (!argp)
1057  return SOCKET_ERROR;
1058 
1059  flags = fcntl(fd, F_GETFL);
1060 
1061  if (flags == -1)
1062  return SOCKET_ERROR;
1063 
1064  if (*argp)
1065  (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK);
1066  else
1067  (void)fcntl(fd, F_SETFL, flags & ~(O_NONBLOCK));
1068  }
1069 
1070  return 0;
1071 }
1072 
1073 int _getpeername(SOCKET s, struct sockaddr* name, int* namelen)
1074 {
1075  int status = 0;
1076  int fd = (int)s;
1077  socklen_t s_namelen = (socklen_t)*namelen;
1078  status = getpeername(fd, name, &s_namelen);
1079  *namelen = (int)s_namelen;
1080  return status;
1081 }
1082 
1083 int _getsockname(SOCKET s, struct sockaddr* name, int* namelen)
1084 {
1085  int status = 0;
1086  int fd = (int)s;
1087  socklen_t s_namelen = (socklen_t)*namelen;
1088  status = getsockname(fd, name, &s_namelen);
1089  *namelen = (int)s_namelen;
1090  return status;
1091 }
1092 
1093 int _getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen)
1094 {
1095  int status = 0;
1096  int fd = (int)s;
1097  socklen_t s_optlen = (socklen_t)*optlen;
1098  status = getsockopt(fd, level, optname, (void*)optval, &s_optlen);
1099  *optlen = (int)s_optlen;
1100  return status;
1101 }
1102 
1103 u_long _htonl(u_long hostlong)
1104 {
1105  WINPR_ASSERT(hostlong <= UINT32_MAX);
1106  return htonl((UINT32)hostlong);
1107 }
1108 
1109 u_short _htons(u_short hostshort)
1110 {
1111  return htons(hostshort);
1112 }
1113 
1114 unsigned long _inet_addr(const char* cp)
1115 {
1116  return WINPR_ASSERTING_INT_CAST(unsigned long, inet_addr(cp));
1117 }
1118 
1119 char* _inet_ntoa(struct in_addr in)
1120 {
1121  return inet_ntoa(in);
1122 }
1123 
1124 int _listen(SOCKET s, int backlog)
1125 {
1126  int status = 0;
1127  int fd = (int)s;
1128  status = listen(fd, backlog);
1129  return status;
1130 }
1131 
1132 u_long _ntohl(u_long netlong)
1133 {
1134  WINPR_ASSERT((netlong & 0xFFFFFFFF00000000ULL) == 0);
1135  return ntohl((UINT32)netlong);
1136 }
1137 
1138 u_short _ntohs(u_short netshort)
1139 {
1140  return ntohs(netshort);
1141 }
1142 
1143 int _recv(SOCKET s, char* buf, int len, int flags)
1144 {
1145  int status = 0;
1146  int fd = (int)s;
1147  status = (int)recv(fd, (void*)buf, (size_t)len, flags);
1148  return status;
1149 }
1150 
1151 int _recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen)
1152 {
1153  int status = 0;
1154  int fd = (int)s;
1155  socklen_t s_fromlen = (socklen_t)*fromlen;
1156  status = (int)recvfrom(fd, (void*)buf, (size_t)len, flags, from, &s_fromlen);
1157  *fromlen = (int)s_fromlen;
1158  return status;
1159 }
1160 
1161 int _select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
1162  const struct timeval* timeout)
1163 {
1164  int status = 0;
1165  union
1166  {
1167  const struct timeval* cpv;
1168  struct timeval* pv;
1169  } cnv;
1170  cnv.cpv = timeout;
1171  do
1172  {
1173  status = select(nfds, readfds, writefds, exceptfds, cnv.pv);
1174  } while ((status < 0) && (errno == EINTR));
1175 
1176  return status;
1177 }
1178 
1179 int _send(SOCKET s, const char* buf, int len, int flags)
1180 {
1181  int status = 0;
1182  int fd = (int)s;
1183  flags |= MSG_NOSIGNAL;
1184  status = (int)send(fd, (const void*)buf, (size_t)len, flags);
1185  return status;
1186 }
1187 
1188 int _sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen)
1189 {
1190  int status = 0;
1191  int fd = (int)s;
1192  status = (int)sendto(fd, (const void*)buf, (size_t)len, flags, to, (socklen_t)tolen);
1193  return status;
1194 }
1195 
1196 int _setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen)
1197 {
1198  int status = 0;
1199  int fd = (int)s;
1200  status = setsockopt(fd, level, optname, (const void*)optval, (socklen_t)optlen);
1201  return status;
1202 }
1203 
1204 int _shutdown(SOCKET s, int how)
1205 {
1206  int status = 0;
1207  int fd = (int)s;
1208  int s_how = -1;
1209 
1210  switch (how)
1211  {
1212  case SD_RECEIVE:
1213  s_how = SHUT_RD;
1214  break;
1215 
1216  case SD_SEND:
1217  s_how = SHUT_WR;
1218  break;
1219 
1220  case SD_BOTH:
1221  s_how = SHUT_RDWR;
1222  break;
1223  default:
1224  break;
1225  }
1226 
1227  if (s_how < 0)
1228  return SOCKET_ERROR;
1229 
1230  status = shutdown(fd, s_how);
1231  return status;
1232 }
1233 
1234 SOCKET _socket(int af, int type, int protocol)
1235 {
1236  int fd = 0;
1237  SOCKET s = 0;
1238  fd = socket(af, type, protocol);
1239 
1240  if (fd < 0)
1241  return INVALID_SOCKET;
1242 
1243  s = (SOCKET)fd;
1244  return s;
1245 }
1246 
1247 struct hostent* _gethostbyaddr(const char* addr, int len, int type)
1248 {
1249  struct hostent* host = NULL;
1250  host = gethostbyaddr((const void*)addr, (socklen_t)len, type);
1251  return host;
1252 }
1253 
1254 struct hostent* _gethostbyname(const char* name)
1255 {
1256  struct hostent* host = NULL;
1257  host = gethostbyname(name);
1258  return host;
1259 }
1260 
1261 int _gethostname(char* name, int namelen)
1262 {
1263  int status = 0;
1264  status = gethostname(name, (size_t)namelen);
1265  return status;
1266 }
1267 
1268 struct servent* /* codespell:ignore servent */ _getservbyport(int port, const char* proto)
1269 {
1270  struct servent* serv = NULL; // codespell:ignore servent
1271 
1272  serv = getservbyport(port, proto);
1273  return serv;
1274 }
1275 
1276 struct servent* /* codespell:ignore servent */
1277 _getservbyname(const char* name, const char* proto) // codespell:ignore servent
1278 
1279 {
1280  struct servent* serv = NULL; // codespell:ignore servent
1281 
1282  serv = getservbyname(name, proto);
1283  return serv;
1284 }
1285 
1286 struct protoent* _getprotobynumber(int number)
1287 {
1288  struct protoent* proto = NULL;
1289  proto = getprotobynumber(number);
1290  return proto;
1291 }
1292 
1293 struct protoent* _getprotobyname(const char* name)
1294 {
1295  struct protoent* proto = NULL;
1296  proto = getprotobyname(name);
1297  return proto;
1298 }
1299 
1300 #endif /* _WIN32 */