Coverage Report

Created: 2024-05-20 06:11

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