Coverage Report

Created: 2023-09-25 06:56

/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 <unistd.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
#include <winpr/assert.h>
299
300
#ifndef MSG_NOSIGNAL
301
#define MSG_NOSIGNAL 0
302
#endif
303
304
int WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
305
0
{
306
0
  WINPR_ASSERT(lpWSAData);
307
308
0
  ZeroMemory(lpWSAData, sizeof(WSADATA));
309
0
  lpWSAData->wVersion = wVersionRequired;
310
0
  lpWSAData->wHighVersion = MAKEWORD(2, 2);
311
0
  return 0; /* success */
312
0
}
313
314
int WSACleanup(void)
315
0
{
316
0
  return 0; /* success */
317
0
}
318
319
void WSASetLastError(int iError)
320
0
{
321
0
  switch (iError)
322
0
  {
323
    /* Base error codes */
324
0
    case WSAEINTR:
325
0
      errno = EINTR;
326
0
      break;
327
328
0
    case WSAEBADF:
329
0
      errno = EBADF;
330
0
      break;
331
332
0
    case WSAEACCES:
333
0
      errno = EACCES;
334
0
      break;
335
336
0
    case WSAEFAULT:
337
0
      errno = EFAULT;
338
0
      break;
339
340
0
    case WSAEINVAL:
341
0
      errno = EINVAL;
342
0
      break;
343
344
0
    case WSAEMFILE:
345
0
      errno = EMFILE;
346
0
      break;
347
348
      /* BSD sockets error codes */
349
350
0
    case WSAEWOULDBLOCK:
351
0
      errno = EWOULDBLOCK;
352
0
      break;
353
354
0
    case WSAEINPROGRESS:
355
0
      errno = EINPROGRESS;
356
0
      break;
357
358
0
    case WSAEALREADY:
359
0
      errno = EALREADY;
360
0
      break;
361
362
0
    case WSAENOTSOCK:
363
0
      errno = ENOTSOCK;
364
0
      break;
365
366
0
    case WSAEDESTADDRREQ:
367
0
      errno = EDESTADDRREQ;
368
0
      break;
369
370
0
    case WSAEMSGSIZE:
371
0
      errno = EMSGSIZE;
372
0
      break;
373
374
0
    case WSAEPROTOTYPE:
375
0
      errno = EPROTOTYPE;
376
0
      break;
377
378
0
    case WSAENOPROTOOPT:
379
0
      errno = ENOPROTOOPT;
380
0
      break;
381
382
0
    case WSAEPROTONOSUPPORT:
383
0
      errno = EPROTONOSUPPORT;
384
0
      break;
385
386
0
    case WSAESOCKTNOSUPPORT:
387
0
      errno = ESOCKTNOSUPPORT;
388
0
      break;
389
390
0
    case WSAEOPNOTSUPP:
391
0
      errno = EOPNOTSUPP;
392
0
      break;
393
394
0
    case WSAEPFNOSUPPORT:
395
0
      errno = EPFNOSUPPORT;
396
0
      break;
397
398
0
    case WSAEAFNOSUPPORT:
399
0
      errno = EAFNOSUPPORT;
400
0
      break;
401
402
0
    case WSAEADDRINUSE:
403
0
      errno = EADDRINUSE;
404
0
      break;
405
406
0
    case WSAEADDRNOTAVAIL:
407
0
      errno = EADDRNOTAVAIL;
408
0
      break;
409
410
0
    case WSAENETDOWN:
411
0
      errno = ENETDOWN;
412
0
      break;
413
414
0
    case WSAENETUNREACH:
415
0
      errno = ENETUNREACH;
416
0
      break;
417
418
0
    case WSAENETRESET:
419
0
      errno = ENETRESET;
420
0
      break;
421
422
0
    case WSAECONNABORTED:
423
0
      errno = ECONNABORTED;
424
0
      break;
425
426
0
    case WSAECONNRESET:
427
0
      errno = ECONNRESET;
428
0
      break;
429
430
0
    case WSAENOBUFS:
431
0
      errno = ENOBUFS;
432
0
      break;
433
434
0
    case WSAEISCONN:
435
0
      errno = EISCONN;
436
0
      break;
437
438
0
    case WSAENOTCONN:
439
0
      errno = ENOTCONN;
440
0
      break;
441
442
0
    case WSAESHUTDOWN:
443
0
      errno = ESHUTDOWN;
444
0
      break;
445
446
0
    case WSAETOOMANYREFS:
447
0
      errno = ETOOMANYREFS;
448
0
      break;
449
450
0
    case WSAETIMEDOUT:
451
0
      errno = ETIMEDOUT;
452
0
      break;
453
454
0
    case WSAECONNREFUSED:
455
0
      errno = ECONNREFUSED;
456
0
      break;
457
458
0
    case WSAELOOP:
459
0
      errno = ELOOP;
460
0
      break;
461
462
0
    case WSAENAMETOOLONG:
463
0
      errno = ENAMETOOLONG;
464
0
      break;
465
466
0
    case WSAEHOSTDOWN:
467
0
      errno = EHOSTDOWN;
468
0
      break;
469
470
0
    case WSAEHOSTUNREACH:
471
0
      errno = EHOSTUNREACH;
472
0
      break;
473
474
0
    case WSAENOTEMPTY:
475
0
      errno = ENOTEMPTY;
476
0
      break;
477
#ifdef EPROCLIM
478
479
    case WSAEPROCLIM:
480
      errno = EPROCLIM;
481
      break;
482
#endif
483
484
0
    case WSAEUSERS:
485
0
      errno = EUSERS;
486
0
      break;
487
488
0
    case WSAEDQUOT:
489
0
      errno = EDQUOT;
490
0
      break;
491
492
0
    case WSAESTALE:
493
0
      errno = ESTALE;
494
0
      break;
495
496
0
    case WSAEREMOTE:
497
0
      errno = EREMOTE;
498
0
      break;
499
0
  }
500
0
}
501
502
int WSAGetLastError(void)
503
0
{
504
0
  int iError = 0;
505
506
0
  switch (errno)
507
0
  {
508
    /* Base error codes */
509
0
    case EINTR:
510
0
      iError = WSAEINTR;
511
0
      break;
512
513
0
    case EBADF:
514
0
      iError = WSAEBADF;
515
0
      break;
516
517
0
    case EACCES:
518
0
      iError = WSAEACCES;
519
0
      break;
520
521
0
    case EFAULT:
522
0
      iError = WSAEFAULT;
523
0
      break;
524
525
0
    case EINVAL:
526
0
      iError = WSAEINVAL;
527
0
      break;
528
529
0
    case EMFILE:
530
0
      iError = WSAEMFILE;
531
0
      break;
532
533
      /* BSD sockets error codes */
534
535
0
    case EWOULDBLOCK:
536
0
      iError = WSAEWOULDBLOCK;
537
0
      break;
538
539
0
    case EINPROGRESS:
540
0
      iError = WSAEINPROGRESS;
541
0
      break;
542
543
0
    case EALREADY:
544
0
      iError = WSAEALREADY;
545
0
      break;
546
547
0
    case ENOTSOCK:
548
0
      iError = WSAENOTSOCK;
549
0
      break;
550
551
0
    case EDESTADDRREQ:
552
0
      iError = WSAEDESTADDRREQ;
553
0
      break;
554
555
0
    case EMSGSIZE:
556
0
      iError = WSAEMSGSIZE;
557
0
      break;
558
559
0
    case EPROTOTYPE:
560
0
      iError = WSAEPROTOTYPE;
561
0
      break;
562
563
0
    case ENOPROTOOPT:
564
0
      iError = WSAENOPROTOOPT;
565
0
      break;
566
567
0
    case EPROTONOSUPPORT:
568
0
      iError = WSAEPROTONOSUPPORT;
569
0
      break;
570
571
0
    case ESOCKTNOSUPPORT:
572
0
      iError = WSAESOCKTNOSUPPORT;
573
0
      break;
574
575
0
    case EOPNOTSUPP:
576
0
      iError = WSAEOPNOTSUPP;
577
0
      break;
578
579
0
    case EPFNOSUPPORT:
580
0
      iError = WSAEPFNOSUPPORT;
581
0
      break;
582
583
0
    case EAFNOSUPPORT:
584
0
      iError = WSAEAFNOSUPPORT;
585
0
      break;
586
587
0
    case EADDRINUSE:
588
0
      iError = WSAEADDRINUSE;
589
0
      break;
590
591
0
    case EADDRNOTAVAIL:
592
0
      iError = WSAEADDRNOTAVAIL;
593
0
      break;
594
595
0
    case ENETDOWN:
596
0
      iError = WSAENETDOWN;
597
0
      break;
598
599
0
    case ENETUNREACH:
600
0
      iError = WSAENETUNREACH;
601
0
      break;
602
603
0
    case ENETRESET:
604
0
      iError = WSAENETRESET;
605
0
      break;
606
607
0
    case ECONNABORTED:
608
0
      iError = WSAECONNABORTED;
609
0
      break;
610
611
0
    case ECONNRESET:
612
0
      iError = WSAECONNRESET;
613
0
      break;
614
615
0
    case ENOBUFS:
616
0
      iError = WSAENOBUFS;
617
0
      break;
618
619
0
    case EISCONN:
620
0
      iError = WSAEISCONN;
621
0
      break;
622
623
0
    case ENOTCONN:
624
0
      iError = WSAENOTCONN;
625
0
      break;
626
627
0
    case ESHUTDOWN:
628
0
      iError = WSAESHUTDOWN;
629
0
      break;
630
631
0
    case ETOOMANYREFS:
632
0
      iError = WSAETOOMANYREFS;
633
0
      break;
634
635
0
    case ETIMEDOUT:
636
0
      iError = WSAETIMEDOUT;
637
0
      break;
638
639
0
    case ECONNREFUSED:
640
0
      iError = WSAECONNREFUSED;
641
0
      break;
642
643
0
    case ELOOP:
644
0
      iError = WSAELOOP;
645
0
      break;
646
647
0
    case ENAMETOOLONG:
648
0
      iError = WSAENAMETOOLONG;
649
0
      break;
650
651
0
    case EHOSTDOWN:
652
0
      iError = WSAEHOSTDOWN;
653
0
      break;
654
655
0
    case EHOSTUNREACH:
656
0
      iError = WSAEHOSTUNREACH;
657
0
      break;
658
659
0
    case ENOTEMPTY:
660
0
      iError = WSAENOTEMPTY;
661
0
      break;
662
#ifdef EPROCLIM
663
664
    case EPROCLIM:
665
      iError = WSAEPROCLIM;
666
      break;
667
#endif
668
669
0
    case EUSERS:
670
0
      iError = WSAEUSERS;
671
0
      break;
672
673
0
    case EDQUOT:
674
0
      iError = WSAEDQUOT;
675
0
      break;
676
677
0
    case ESTALE:
678
0
      iError = WSAESTALE;
679
0
      break;
680
681
0
    case EREMOTE:
682
0
      iError = WSAEREMOTE;
683
0
      break;
684
      /* Special cases */
685
#if (EAGAIN != EWOULDBLOCK)
686
687
    case EAGAIN:
688
      iError = WSAEWOULDBLOCK;
689
      break;
690
#endif
691
0
#if defined(EPROTO)
692
693
0
    case EPROTO:
694
0
      iError = WSAECONNRESET;
695
0
      break;
696
0
#endif
697
0
  }
698
699
  /**
700
   * Windows Sockets Extended Error Codes:
701
   *
702
   * WSASYSNOTREADY
703
   * WSAVERNOTSUPPORTED
704
   * WSANOTINITIALISED
705
   * WSAEDISCON
706
   * WSAENOMORE
707
   * WSAECANCELLED
708
   * WSAEINVALIDPROCTABLE
709
   * WSAEINVALIDPROVIDER
710
   * WSAEPROVIDERFAILEDINIT
711
   * WSASYSCALLFAILURE
712
   * WSASERVICE_NOT_FOUND
713
   * WSATYPE_NOT_FOUND
714
   * WSA_E_NO_MORE
715
   * WSA_E_CANCELLED
716
   * WSAEREFUSED
717
   */
718
0
  return iError;
719
0
}
720
721
HANDLE WSACreateEvent(void)
722
0
{
723
0
  return CreateEvent(NULL, TRUE, FALSE, NULL);
724
0
}
725
726
BOOL WSASetEvent(HANDLE hEvent)
727
0
{
728
0
  return SetEvent(hEvent);
729
0
}
730
731
BOOL WSAResetEvent(HANDLE hEvent)
732
0
{
733
  /* POSIX systems auto reset the socket,
734
   * if no more data is available. */
735
0
  return TRUE;
736
0
}
737
738
BOOL WSACloseEvent(HANDLE hEvent)
739
0
{
740
0
  BOOL status;
741
0
  status = CloseHandle(hEvent);
742
743
0
  if (!status)
744
0
    SetLastError(6);
745
746
0
  return status;
747
0
}
748
749
int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, LONG lNetworkEvents)
750
0
{
751
0
  u_long arg = 1;
752
0
  ULONG mode = 0;
753
754
0
  if (_ioctlsocket(s, FIONBIO, &arg) != 0)
755
0
    return SOCKET_ERROR;
756
757
0
  if (arg == 0)
758
0
    return 0;
759
760
0
  if (lNetworkEvents & FD_READ)
761
0
    mode |= WINPR_FD_READ;
762
763
0
  if (lNetworkEvents & FD_WRITE)
764
0
    mode |= WINPR_FD_WRITE;
765
766
0
  if (SetEventFileDescriptor(hEventObject, s, mode) < 0)
767
0
    return SOCKET_ERROR;
768
769
0
  return 0;
770
0
}
771
772
DWORD WSAWaitForMultipleEvents(DWORD cEvents, const HANDLE* lphEvents, BOOL fWaitAll,
773
                               DWORD dwTimeout, BOOL fAlertable)
774
0
{
775
0
  return WaitForMultipleObjectsEx(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable);
776
0
}
777
778
SOCKET WSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g,
779
                  DWORD dwFlags)
780
0
{
781
0
  SOCKET s;
782
0
  s = _socket(af, type, protocol);
783
0
  return s;
784
0
}
785
786
SOCKET WSASocketW(int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g,
787
                  DWORD dwFlags)
788
0
{
789
0
  return WSASocketA(af, type, protocol, (LPWSAPROTOCOL_INFOA)lpProtocolInfo, g, dwFlags);
790
0
}
791
792
int WSAIoctl(SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
793
             LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
794
             LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
795
0
{
796
0
  int fd;
797
0
  int index;
798
0
  ULONG nFlags;
799
0
  size_t offset;
800
0
  size_t ifreq_len;
801
0
  struct ifreq* ifreq;
802
0
  struct ifconf ifconf;
803
0
  char address[128];
804
0
  char broadcast[128];
805
0
  char netmask[128];
806
0
  char buffer[4096];
807
0
  int numInterfaces;
808
0
  int maxNumInterfaces;
809
0
  INTERFACE_INFO* pInterface;
810
0
  INTERFACE_INFO* pInterfaces;
811
0
  struct sockaddr_in* pAddress;
812
0
  struct sockaddr_in* pBroadcast;
813
0
  struct sockaddr_in* pNetmask;
814
815
0
  if ((dwIoControlCode != SIO_GET_INTERFACE_LIST) ||
816
0
      (!lpvOutBuffer || !cbOutBuffer || !lpcbBytesReturned))
817
0
  {
818
0
    WSASetLastError(WSAEINVAL);
819
0
    return SOCKET_ERROR;
820
0
  }
821
822
0
  fd = (int)s;
823
0
  pInterfaces = (INTERFACE_INFO*)lpvOutBuffer;
824
0
  maxNumInterfaces = cbOutBuffer / sizeof(INTERFACE_INFO);
825
#ifdef WSAIOCTL_IFADDRS
826
  {
827
    struct ifaddrs* ifa = NULL;
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 (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
0
  ifconf.ifc_len = sizeof(buffer);
918
0
  ifconf.ifc_buf = buffer;
919
920
0
  if (ioctl(fd, SIOCGIFCONF, &ifconf) != 0)
921
0
  {
922
0
    WSASetLastError(WSAENETDOWN);
923
0
    return SOCKET_ERROR;
924
0
  }
925
926
0
  index = 0;
927
0
  offset = 0;
928
0
  numInterfaces = 0;
929
0
  ifreq = ifconf.ifc_req;
930
931
0
  while ((ifconf.ifc_len >= 0) && (offset < (size_t)ifconf.ifc_len) &&
932
0
         (numInterfaces < maxNumInterfaces))
933
0
  {
934
0
    pInterface = &pInterfaces[index];
935
0
    pAddress = (struct sockaddr_in*)&pInterface->iiAddress;
936
0
    pBroadcast = (struct sockaddr_in*)&pInterface->iiBroadcastAddress;
937
0
    pNetmask = (struct sockaddr_in*)&pInterface->iiNetmask;
938
939
0
    if (ioctl(fd, SIOCGIFFLAGS, ifreq) != 0)
940
0
      goto next_ifreq;
941
942
0
    nFlags = 0;
943
944
0
    if (ifreq->ifr_flags & IFF_UP)
945
0
      nFlags |= _IFF_UP;
946
947
0
    if (ifreq->ifr_flags & IFF_BROADCAST)
948
0
      nFlags |= _IFF_BROADCAST;
949
950
0
    if (ifreq->ifr_flags & IFF_LOOPBACK)
951
0
      nFlags |= _IFF_LOOPBACK;
952
953
0
    if (ifreq->ifr_flags & IFF_POINTOPOINT)
954
0
      nFlags |= _IFF_POINTTOPOINT;
955
956
0
    if (ifreq->ifr_flags & IFF_MULTICAST)
957
0
      nFlags |= _IFF_MULTICAST;
958
959
0
    pInterface->iiFlags = nFlags;
960
961
0
    if (ioctl(fd, SIOCGIFADDR, ifreq) != 0)
962
0
      goto next_ifreq;
963
964
0
    if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
965
0
      goto next_ifreq;
966
967
0
    getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), address, sizeof(address), 0, 0,
968
0
                NI_NUMERICHOST);
969
0
    inet_pton(ifreq->ifr_addr.sa_family, address, (void*)&pAddress->sin_addr);
970
971
0
    if (ioctl(fd, SIOCGIFBRDADDR, ifreq) != 0)
972
0
      goto next_ifreq;
973
974
0
    if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
975
0
      goto next_ifreq;
976
977
0
    getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), broadcast, sizeof(broadcast), 0, 0,
978
0
                NI_NUMERICHOST);
979
0
    inet_pton(ifreq->ifr_addr.sa_family, broadcast, (void*)&pBroadcast->sin_addr);
980
981
0
    if (ioctl(fd, SIOCGIFNETMASK, ifreq) != 0)
982
0
      goto next_ifreq;
983
984
0
    if ((ifreq->ifr_addr.sa_family != AF_INET) && (ifreq->ifr_addr.sa_family != AF_INET6))
985
0
      goto next_ifreq;
986
987
0
    getnameinfo(&ifreq->ifr_addr, sizeof(ifreq->ifr_addr), netmask, sizeof(netmask), 0, 0,
988
0
                NI_NUMERICHOST);
989
0
    inet_pton(ifreq->ifr_addr.sa_family, netmask, (void*)&pNetmask->sin_addr);
990
0
    numInterfaces++;
991
0
  next_ifreq:
992
#if !defined(__linux__) && !defined(__sun__) && !defined(__CYGWIN__) && !defined(EMSCRIPTEN)
993
    ifreq_len = IFNAMSIZ + ifreq->ifr_addr.sa_len;
994
#else
995
0
    ifreq_len = sizeof(*ifreq);
996
0
#endif
997
0
    ifreq = (struct ifreq*)&((BYTE*)ifreq)[ifreq_len];
998
0
    offset += ifreq_len;
999
0
    index++;
1000
0
  }
1001
1002
0
  *lpcbBytesReturned = (DWORD)(numInterfaces * sizeof(INTERFACE_INFO));
1003
0
  return 0;
1004
0
}
1005
1006
SOCKET _accept(SOCKET s, struct sockaddr* addr, int* addrlen)
1007
0
{
1008
0
  int status;
1009
0
  int fd = (int)s;
1010
0
  socklen_t s_addrlen = (socklen_t)*addrlen;
1011
0
  status = accept(fd, addr, &s_addrlen);
1012
0
  *addrlen = (socklen_t)s_addrlen;
1013
0
  return status;
1014
0
}
1015
1016
int _bind(SOCKET s, const struct sockaddr* addr, int namelen)
1017
0
{
1018
0
  int status;
1019
0
  int fd = (int)s;
1020
0
  status = bind(fd, addr, (socklen_t)namelen);
1021
1022
0
  if (status < 0)
1023
0
    return SOCKET_ERROR;
1024
1025
0
  return status;
1026
0
}
1027
1028
int closesocket(SOCKET s)
1029
0
{
1030
0
  int status;
1031
0
  int fd = (int)s;
1032
0
  status = close(fd);
1033
0
  return status;
1034
0
}
1035
1036
int _connect(SOCKET s, const struct sockaddr* name, int namelen)
1037
0
{
1038
0
  int status;
1039
0
  int fd = (int)s;
1040
0
  status = connect(fd, name, (socklen_t)namelen);
1041
1042
0
  if (status < 0)
1043
0
    return SOCKET_ERROR;
1044
1045
0
  return status;
1046
0
}
1047
1048
int _ioctlsocket(SOCKET s, long cmd, u_long* argp)
1049
0
{
1050
0
  int fd = (int)s;
1051
1052
0
  if (cmd == FIONBIO)
1053
0
  {
1054
0
    int flags;
1055
1056
0
    if (!argp)
1057
0
      return SOCKET_ERROR;
1058
1059
0
    flags = fcntl(fd, F_GETFL);
1060
1061
0
    if (flags == -1)
1062
0
      return SOCKET_ERROR;
1063
1064
0
    if (*argp)
1065
0
      fcntl(fd, F_SETFL, flags | O_NONBLOCK);
1066
0
    else
1067
0
      fcntl(fd, F_SETFL, flags & ~(O_NONBLOCK));
1068
0
  }
1069
1070
0
  return 0;
1071
0
}
1072
1073
int _getpeername(SOCKET s, struct sockaddr* name, int* namelen)
1074
0
{
1075
0
  int status;
1076
0
  int fd = (int)s;
1077
0
  socklen_t s_namelen = (socklen_t)*namelen;
1078
0
  status = getpeername(fd, name, &s_namelen);
1079
0
  *namelen = (int)s_namelen;
1080
0
  return status;
1081
0
}
1082
1083
int _getsockname(SOCKET s, struct sockaddr* name, int* namelen)
1084
0
{
1085
0
  int status;
1086
0
  int fd = (int)s;
1087
0
  socklen_t s_namelen = (socklen_t)*namelen;
1088
0
  status = getsockname(fd, name, &s_namelen);
1089
0
  *namelen = (int)s_namelen;
1090
0
  return status;
1091
0
}
1092
1093
int _getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen)
1094
0
{
1095
0
  int status;
1096
0
  int fd = (int)s;
1097
0
  socklen_t s_optlen = (socklen_t)*optlen;
1098
0
  status = getsockopt(fd, level, optname, (void*)optval, &s_optlen);
1099
0
  *optlen = (socklen_t)s_optlen;
1100
0
  return status;
1101
0
}
1102
1103
u_long _htonl(u_long hostlong)
1104
0
{
1105
0
  return htonl(hostlong);
1106
0
}
1107
1108
u_short _htons(u_short hostshort)
1109
0
{
1110
0
  return htons(hostshort);
1111
0
}
1112
1113
unsigned long _inet_addr(const char* cp)
1114
0
{
1115
0
  return (long)inet_addr(cp);
1116
0
}
1117
1118
char* _inet_ntoa(struct in_addr in)
1119
0
{
1120
0
  return inet_ntoa(in);
1121
0
}
1122
1123
int _listen(SOCKET s, int backlog)
1124
0
{
1125
0
  int status;
1126
0
  int fd = (int)s;
1127
0
  status = listen(fd, backlog);
1128
0
  return status;
1129
0
}
1130
1131
u_long _ntohl(u_long netlong)
1132
0
{
1133
0
  return ntohl(netlong);
1134
0
}
1135
1136
u_short _ntohs(u_short netshort)
1137
0
{
1138
0
  return ntohs(netshort);
1139
0
}
1140
1141
int _recv(SOCKET s, char* buf, int len, int flags)
1142
0
{
1143
0
  int status;
1144
0
  int fd = (int)s;
1145
0
  status = (int)recv(fd, (void*)buf, (size_t)len, flags);
1146
0
  return status;
1147
0
}
1148
1149
int _recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen)
1150
0
{
1151
0
  int status;
1152
0
  int fd = (int)s;
1153
0
  socklen_t s_fromlen = (socklen_t)*fromlen;
1154
0
  status = (int)recvfrom(fd, (void*)buf, (size_t)len, flags, from, &s_fromlen);
1155
0
  *fromlen = (int)s_fromlen;
1156
0
  return status;
1157
0
}
1158
1159
int _select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
1160
            const struct timeval* timeout)
1161
0
{
1162
0
  int status;
1163
0
  union
1164
0
  {
1165
0
    const struct timeval* cpv;
1166
0
    struct timeval* pv;
1167
0
  } cnv;
1168
0
  cnv.cpv = timeout;
1169
0
  do
1170
0
  {
1171
0
    status = select(nfds, readfds, writefds, exceptfds, cnv.pv);
1172
0
  } while ((status < 0) && (errno == EINTR));
1173
1174
0
  return status;
1175
0
}
1176
1177
int _send(SOCKET s, const char* buf, int len, int flags)
1178
0
{
1179
0
  int status;
1180
0
  int fd = (int)s;
1181
0
  flags |= MSG_NOSIGNAL;
1182
0
  status = (int)send(fd, (const void*)buf, (size_t)len, flags);
1183
0
  return status;
1184
0
}
1185
1186
int _sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen)
1187
0
{
1188
0
  int status;
1189
0
  int fd = (int)s;
1190
0
  status = (int)sendto(fd, (const void*)buf, (size_t)len, flags, to, (socklen_t)tolen);
1191
0
  return status;
1192
0
}
1193
1194
int _setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen)
1195
0
{
1196
0
  int status;
1197
0
  int fd = (int)s;
1198
0
  status = setsockopt(fd, level, optname, (const void*)optval, (socklen_t)optlen);
1199
0
  return status;
1200
0
}
1201
1202
int _shutdown(SOCKET s, int how)
1203
0
{
1204
0
  int status;
1205
0
  int fd = (int)s;
1206
0
  int s_how = -1;
1207
1208
0
  switch (how)
1209
0
  {
1210
0
    case SD_RECEIVE:
1211
0
      s_how = SHUT_RD;
1212
0
      break;
1213
1214
0
    case SD_SEND:
1215
0
      s_how = SHUT_WR;
1216
0
      break;
1217
1218
0
    case SD_BOTH:
1219
0
      s_how = SHUT_RDWR;
1220
0
      break;
1221
0
  }
1222
1223
0
  if (s_how < 0)
1224
0
    return SOCKET_ERROR;
1225
1226
0
  status = shutdown(fd, s_how);
1227
0
  return status;
1228
0
}
1229
1230
SOCKET _socket(int af, int type, int protocol)
1231
0
{
1232
0
  int fd;
1233
0
  SOCKET s;
1234
0
  fd = socket(af, type, protocol);
1235
1236
0
  if (fd < 0)
1237
0
    return INVALID_SOCKET;
1238
1239
0
  s = (SOCKET)fd;
1240
0
  return s;
1241
0
}
1242
1243
struct hostent* _gethostbyaddr(const char* addr, int len, int type)
1244
0
{
1245
0
  struct hostent* host;
1246
0
  host = gethostbyaddr((const void*)addr, (socklen_t)len, type);
1247
0
  return host;
1248
0
}
1249
1250
struct hostent* _gethostbyname(const char* name)
1251
0
{
1252
0
  struct hostent* host;
1253
0
  host = gethostbyname(name);
1254
0
  return host;
1255
0
}
1256
1257
int _gethostname(char* name, int namelen)
1258
0
{
1259
0
  int status;
1260
0
  status = gethostname(name, (size_t)namelen);
1261
0
  return status;
1262
0
}
1263
1264
struct servent* _getservbyport(int port, const char* proto)
1265
0
{
1266
0
  struct servent* serv;
1267
0
  serv = getservbyport(port, proto);
1268
0
  return serv;
1269
0
}
1270
1271
struct servent* _getservbyname(const char* name, const char* proto)
1272
0
{
1273
0
  struct servent* serv;
1274
0
  serv = getservbyname(name, proto);
1275
0
  return serv;
1276
0
}
1277
1278
struct protoent* _getprotobynumber(int number)
1279
0
{
1280
0
  struct protoent* proto;
1281
0
  proto = getprotobynumber(number);
1282
0
  return proto;
1283
0
}
1284
1285
struct protoent* _getprotobyname(const char* name)
1286
0
{
1287
0
  struct protoent* proto;
1288
0
  proto = getprotobyname(name);
1289
0
  return proto;
1290
0
}
1291
1292
#endif /* _WIN32 */