2
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
28
import java.io.FileDescriptor;
29
import cli.System.Net.IPAddress;
30
import cli.System.Net.IPEndPoint;
31
import static ikvm.internal.JNI.*;
32
import static ikvm.internal.Winsock.*;
34
final class net_util_md
36
private net_util_md() { }
38
static final int INADDR_ANY = 0;
40
static final int IPTOS_TOS_MASK = 0x1e;
41
static final int IPTOS_PREC_MASK = 0xe0;
43
static boolean isRcvTimeoutSupported = true;
46
* Table of Windows Sockets errors, the specific exception we
47
* throw for the error, and the error text.
49
* Note that this table excludes OS dependent errors.
51
* Latest list of Windows Sockets errors can be found at :-
52
* http://msdn.microsoft.com/library/psdk/winsock/errors_3wc2.htm
54
private static class WinsockError
58
final String errString;
60
WinsockError(int errCode, int exc, String errString)
62
this.errCode = errCode;
64
this.errString = errString;
68
private static final int Exception_BindException = 1;
69
private static final int Exception_ConnectException = 2;
70
private static final int Exception_NoRouteToHostException = 3;
72
private static final WinsockError[] winsock_errors = {
73
new WinsockError(WSAEACCES, 0, "Permission denied"),
74
new WinsockError(WSAEADDRINUSE, Exception_BindException, "Address already in use"),
75
new WinsockError(WSAEADDRNOTAVAIL, Exception_BindException, "Cannot assign requested address"),
76
new WinsockError(WSAEAFNOSUPPORT, 0, "Address family not supported by protocol family"),
77
new WinsockError(WSAEALREADY, 0, "Operation already in progress"),
78
new WinsockError(WSAECONNABORTED, 0, "Software caused connection abort"),
79
new WinsockError(WSAECONNREFUSED, Exception_ConnectException, "Connection refused"),
80
new WinsockError(WSAECONNRESET, 0, "Connection reset by peer"),
81
new WinsockError(WSAEDESTADDRREQ, 0, "Destination address required"),
82
new WinsockError(WSAEFAULT, 0, "Bad address"),
83
new WinsockError(WSAEHOSTDOWN, 0, "Host is down"),
84
new WinsockError(WSAEHOSTUNREACH, Exception_NoRouteToHostException, "No route to host"),
85
new WinsockError(WSAEINPROGRESS, 0, "Operation now in progress"),
86
new WinsockError(WSAEINTR, 0, "Interrupted function call"),
87
new WinsockError(WSAEINVAL, 0, "Invalid argument"),
88
new WinsockError(WSAEISCONN, 0, "Socket is already connected"),
89
new WinsockError(WSAEMFILE, 0, "Too many open files"),
90
new WinsockError(WSAEMSGSIZE, 0, "The message is larger than the maximum supported by the underlying transport"),
91
new WinsockError(WSAENETDOWN, 0, "Network is down"),
92
new WinsockError(WSAENETRESET, 0, "Network dropped connection on reset"),
93
new WinsockError(WSAENETUNREACH, 0, "Network is unreachable"),
94
new WinsockError(WSAENOBUFS, 0, "No buffer space available (maximum connections reached?)"),
95
new WinsockError(WSAENOPROTOOPT, 0, "Bad protocol option"),
96
new WinsockError(WSAENOTCONN, 0, "Socket is not connected"),
97
new WinsockError(WSAENOTSOCK, 0, "Socket operation on nonsocket"),
98
new WinsockError(WSAEOPNOTSUPP, 0, "Operation not supported"),
99
new WinsockError(WSAEPFNOSUPPORT, 0, "Protocol family not supported"),
100
new WinsockError(WSAEPROCLIM, 0, "Too many processes"),
101
new WinsockError(WSAEPROTONOSUPPORT, 0, "Protocol not supported"),
102
new WinsockError(WSAEPROTOTYPE, 0, "Protocol wrong type for socket"),
103
new WinsockError(WSAESHUTDOWN, 0, "Cannot send after socket shutdown"),
104
new WinsockError(WSAESOCKTNOSUPPORT, 0, "Socket type not supported"),
105
new WinsockError(WSAETIMEDOUT, Exception_ConnectException, "Connection timed out"),
106
new WinsockError(WSATYPE_NOT_FOUND, 0, "Class type not found"),
107
new WinsockError(WSAEWOULDBLOCK, 0, "Resource temporarily unavailable"),
108
new WinsockError(WSAHOST_NOT_FOUND, 0, "Host not found"),
109
new WinsockError(WSA_NOT_ENOUGH_MEMORY, 0, "Insufficient memory available"),
110
new WinsockError(WSANOTINITIALISED, 0, "Successful WSAStartup not yet performed"),
111
new WinsockError(WSANO_DATA, 0, "Valid name, no data record of requested type"),
112
new WinsockError(WSANO_RECOVERY, 0, "This is a nonrecoverable error"),
113
new WinsockError(WSASYSNOTREADY, 0, "Network subsystem is unavailable"),
114
new WinsockError(WSATRY_AGAIN, 0, "Nonauthoritative host not found"),
115
new WinsockError(WSAVERNOTSUPPORTED, 0, "Winsock.dll version out of range"),
116
new WinsockError(WSAEDISCON, 0, "Graceful shutdown in progress"),
117
new WinsockError(WSA_OPERATION_ABORTED, 0, "Overlapped operation aborted")
121
* Since winsock doesn't have the equivalent of strerror(errno)
122
* use table to lookup error text for the error.
124
static SocketException NET_ThrowNew(int errorNum, String msg)
127
int table_size = winsock_errors.length;
132
msg = "no further information";
136
* Check table for known winsock errors
139
while (i < table_size) {
140
if (errorNum == winsock_errors[i].errCode) {
147
* If found get pick the specific exception and error
148
* message corresponding to this error.
150
if (i < table_size) {
151
excP = winsock_errors[i].exc;
152
fullMsg = winsock_errors[i].errString + ": " + msg;
154
fullMsg = "Unrecognized Windows Sockets error: " + errorNum + ": " + msg;
158
* Throw SocketException if no specific exception for this
162
case Exception_BindException:
163
return new BindException(fullMsg);
164
case Exception_ConnectException:
165
return new ConnectException(fullMsg);
166
case Exception_NoRouteToHostException:
167
return new NoRouteToHostException(fullMsg);
169
return new SocketException(fullMsg);
173
static void NET_ThrowNew(JNIEnv env, int errorNum, String msg)
175
env.Throw(NET_ThrowNew(errorNum, msg));
178
static SocketException NET_ThrowCurrent(String msg)
180
return NET_ThrowNew(WSAGetLastError(), msg);
183
static void NET_ThrowCurrent(JNIEnv env, String msg)
185
env.Throw(NET_ThrowCurrent(msg));
189
* Return the default TOS value
191
static int NET_GetDefaultTOS() {
192
// we always use the "default" default...
197
* Map the Java level socket option to the platform specific
198
* level and option name.
201
private static final class sockopts {
206
sockopts(int cmd, int level, int optname) {
209
this.optname = optname;
213
private static final sockopts opts[] = {
214
new sockopts(SocketOptions.TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY ),
215
new sockopts(SocketOptions.SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE ),
216
new sockopts(SocketOptions.SO_LINGER, SOL_SOCKET, SO_LINGER ),
217
new sockopts(SocketOptions.SO_SNDBUF, SOL_SOCKET, SO_SNDBUF ),
218
new sockopts(SocketOptions.SO_RCVBUF, SOL_SOCKET, SO_RCVBUF ),
219
new sockopts(SocketOptions.SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE ),
220
new sockopts(SocketOptions.SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR ),
221
new sockopts(SocketOptions.SO_BROADCAST, SOL_SOCKET, SO_BROADCAST ),
222
new sockopts(SocketOptions.IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF ),
223
new sockopts(SocketOptions.IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP ),
224
new sockopts(SocketOptions.IP_TOS, IPPROTO_IP, IP_TOS ),
228
/* call NET_MapSocketOptionV6 for the IPv6 fd only
229
* and NET_MapSocketOption for the IPv4 fd
231
static int NET_MapSocketOptionV6(int cmd, int[] level, int[] optname) {
234
case SocketOptions.IP_MULTICAST_IF:
235
case SocketOptions.IP_MULTICAST_IF2:
236
level[0] = IPPROTO_IPV6;
237
optname[0] = IPV6_MULTICAST_IF;
240
case SocketOptions.IP_MULTICAST_LOOP:
241
level[0] = IPPROTO_IPV6;
242
optname[0] = IPV6_MULTICAST_LOOP;
245
return NET_MapSocketOption (cmd, level, optname);
248
static int NET_MapSocketOption(int cmd, int[] level, int[] optname) {
250
* Map the Java level option to the native level
252
for (int i=0; i<opts.length; i++) {
253
if (cmd == opts[i].cmd) {
254
level[0] = opts[i].level;
255
optname[0] = opts[i].optname;
264
static int NET_SetSockOpt(cli.System.Net.Sockets.Socket s, int level, int optname, Object optval)
268
if (level == IPPROTO_IP && optname == IP_TOS) {
269
int tos = (Integer)optval;
270
tos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK);
274
rv = setsockopt(s, level, optname, optval);
276
if (rv == SOCKET_ERROR) {
278
* IP_TOS & IP_MULTICAST_LOOP can't be set on some versions
281
if ((WSAGetLastError() == WSAENOPROTOOPT) &&
282
(level == IPPROTO_IP) &&
283
(optname == IP_TOS || optname == IP_MULTICAST_LOOP)) {
288
* IP_TOS can't be set on unbound UDP sockets.
290
if ((WSAGetLastError() == WSAEINVAL) &&
291
(level == IPPROTO_IP) &&
292
(optname == IP_TOS)) {
301
* Wrapper for setsockopt dealing with Windows specific issues :-
303
* IP_TOS is not supported on some versions of Windows so
304
* instead return the default value for the OS.
306
static int NET_GetSockOpt(cli.System.Net.Sockets.Socket s, int level, int optname, Object optval)
310
rv = getsockopt(s, level, optname, optval);
314
* IPPROTO_IP/IP_TOS is not supported on some Windows
315
* editions so return the default type-of-service
318
if (rv == SOCKET_ERROR) {
320
if (WSAGetLastError() == WSAENOPROTOOPT &&
321
level == IPPROTO_IP && optname == IP_TOS) {
323
((int[])optval)[0] = NET_GetDefaultTOS();
333
* Wrapper for bind winsock call - transparent converts an
334
* error related to binding to a port that has exclusive access
335
* into an error indicating the port is in use (facilitates
336
* better error reporting).
338
static int NET_Bind(cli.System.Net.Sockets.Socket s, SOCKETADDRESS him)
340
int rv = bind(s, him);
342
if (rv == SOCKET_ERROR) {
344
* If bind fails with WSAEACCES it means that a privileged
345
* process has done an exclusive bind (NT SP4/2000/XP only).
347
if (WSAGetLastError() == WSAEACCES) {
348
WSASetLastError(WSAEADDRINUSE);
355
static int NET_SocketClose(cli.System.Net.Sockets.Socket fd) {
356
linger l = new linger();
358
if (getsockopt(fd, SOL_SOCKET, SO_LINGER, l) == 0) {
359
if (l.l_onoff == 0) {
360
WSASendDisconnect(fd);
363
ret = closesocket (fd);
367
static int NET_Timeout(cli.System.Net.Sockets.Socket fd, long timeout) {
369
fd_set tbl = new fd_set();
370
timeval t = new timeval();
371
t.tv_sec = timeout / 1000;
372
t.tv_usec = (timeout % 1000) * 1000;
375
ret = select (tbl, null, null, t);
380
* differs from NET_Timeout() as follows:
382
* If timeout = -1, it blocks forever.
384
* returns 1 or 2 depending if only one or both sockets
387
* *fdret is (one of) the active fds. If both sockets
388
* fire at same time, *fdret = fd always.
390
static int NET_Timeout2(cli.System.Net.Sockets.Socket fd, cli.System.Net.Sockets.Socket fd1, long timeout, cli.System.Net.Sockets.Socket[] fdret) {
392
fd_set tbl = new fd_set();
393
timeval t = new timeval();
397
t.tv_sec = timeout / 1000;
398
t.tv_usec = (timeout % 1000) * 1000;
403
ret = select (tbl, null, null, t);
406
return 0; /* timeout */
408
if (FD_ISSET (fd, tbl)) {
422
* if ipv6 is available, call NET_BindV6 to bind to the required address/port.
423
* Because the same port number may need to be reserved in both v4 and v6 space,
424
* this may require socket(s) to be re-opened. Therefore, all of this information
425
* is passed in and returned through the ipv6bind structure.
427
* If the request is to bind to a specific address, then this (by definition) means
428
* only bind in either v4 or v6, and this is just the same as normal. ie. a single
429
* call to bind() will suffice. The other socket is closed in this case.
431
* The more complicated case is when the requested address is ::0 or 0.0.0.0.
434
* 2. If the reqeusted port is 0 (ie. any port) then we try to bind in v4 space
435
* first with a wild-card port argument. We then try to bind in v6 space
436
* using the returned port number. If this fails, we repeat the process
437
* until a free port common to both spaces becomes available.
439
* 3. If the requested port is a specific port, then we just try to get that
440
* port in both spaces, and if it is not free in both, then the bind fails.
442
* On failure, sockets are closed and an error returned with CLOSE_SOCKETS_AND_RETURN
445
static class ipv6bind {
447
cli.System.Net.Sockets.Socket ipv4_fd;
448
cli.System.Net.Sockets.Socket ipv6_fd;
451
private static int CLOSE_SOCKETS_AND_RETURN(
452
cli.System.Net.Sockets.Socket fd,
453
cli.System.Net.Sockets.Socket ofd,
454
cli.System.Net.Sockets.Socket close_fd,
455
cli.System.Net.Sockets.Socket close_ofd,
463
if (close_fd != null) {
464
closesocket (close_fd);
466
if (close_ofd != null) {
467
closesocket (close_ofd);
469
b.ipv4_fd = b.ipv6_fd = null;
473
static int NET_BindV6(ipv6bind b) {
474
cli.System.Net.Sockets.Socket fd = null;
475
cli.System.Net.Sockets.Socket ofd = null;
477
/* need to defer close until new sockets created */
478
cli.System.Net.Sockets.Socket close_fd = null;
479
cli.System.Net.Sockets.Socket close_ofd = null;
481
SOCKETADDRESS oaddr = new SOCKETADDRESS();
482
int family = b.addr.him.sa_family;
487
if (family == AF_INET && (b.addr.him4.sin_addr.s_addr != INADDR_ANY)) {
488
/* bind to v4 only */
490
ret = NET_Bind (b.ipv4_fd, b.addr);
491
if (ret == SOCKET_ERROR) {
492
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
494
closesocket (b.ipv6_fd);
498
if (family == AF_INET6 && (!IN6ADDR_ISANY(b.addr))) {
499
/* bind to v6 only */
501
ret = NET_Bind (b.ipv6_fd, b.addr);
502
if (ret == SOCKET_ERROR) {
503
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
505
closesocket (b.ipv4_fd);
510
/* We need to bind on both stacks, with the same port number */
512
if (family == AF_INET) {
516
port = GET_PORT (b.addr);
517
oaddr.set(new IPEndPoint(IPAddress.IPv6Any, htons(port)));
522
port = GET_PORT (b.addr);
523
oaddr.set(new IPEndPoint(IPAddress.Any, htons(port)));
526
rv = NET_Bind (fd, b.addr);
527
if (rv == SOCKET_ERROR) {
528
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
531
/* get the port and set it in the other address */
532
if (getsockname(fd, b.addr) == -1) {
533
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
535
bound_port = b.addr.sin_port;
536
oaddr.sin_port = bound_port;
537
if ((rv=NET_Bind (ofd, oaddr)) == SOCKET_ERROR) {
539
/* no retries unless, the request was for any free port */
542
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
545
int sotype = fd.get_SocketType().Value;
547
/* 50 is an arbitrary limit, just to ensure that this
548
* cannot be an endless loop. Would expect socket creation to
551
for (int retries = 0; retries < 50 /*SOCK_RETRIES*/; retries ++) {
559
/* create two new sockets */
560
fd = socket (family, sotype, 0);
561
if (fd == INVALID_SOCKET) {
562
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
564
ofd = socket (ofamily, sotype, 0);
565
if (ofd == INVALID_SOCKET) {
566
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
569
/* bind random port on first socket */
571
rv = NET_Bind (ofd, oaddr);
572
if (rv == SOCKET_ERROR) {
573
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
575
/* close the original pair of sockets before continuing */
576
closesocket (close_fd);
577
closesocket (close_ofd);
578
close_fd = close_ofd = null;
580
/* bind new port on second socket */
581
if (getsockname(ofd, oaddr) == -1) {
582
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
584
bound_port = oaddr.sin_port;
585
b.addr.sin_port = bound_port;
586
rv = NET_Bind (fd, b.addr);
588
if (rv != SOCKET_ERROR) {
589
if (family == AF_INET) {
599
return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
604
/* If address types is IPv6, then IPv6 must be available. Otherwise
605
* no address can be generated. In the case of an IPv4 Inetaddress this
606
* method will return an IPv4 mapped address where IPv6 is available and
607
* v4MappedAddress is TRUE. Otherwise it will return a sockaddr_in
608
* structure for an IPv4 InetAddress.
610
static int NET_InetAddressToSockaddr(JNIEnv env, InetAddress iaObj, int port, SOCKETADDRESS him, boolean v4MappedAddress) {
611
if (iaObj.family == InetAddress.IPv4) {
612
him.set(new IPEndPoint(new IPAddress(htonl(iaObj.address) & 0xFFFFFFFFL), port));
615
Inet6Address v6addr = (Inet6Address)iaObj;
616
int scope = v6addr.getScopeId();
618
him.set(new IPEndPoint(new IPAddress(v6addr.ipaddress), port));
621
him.set(new IPEndPoint(new IPAddress(v6addr.ipaddress, scope & 0xFFFFFFFFL), port));
627
static int NET_GetPortFromSockaddr(SOCKETADDRESS him) {
628
return ntohs(GET_PORT(him));
631
static boolean NET_IsIPv4Mapped(byte[] caddr) {
633
for (i = 0; i < 10; i++) {
634
if (caddr[i] != 0x00) {
639
if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) {
645
static int NET_IPv4MappedToIPv4(byte[] caddr) {
646
return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8)
647
| (caddr[15] & 0xff);
650
static boolean NET_IsEqual(byte[] caddr1, byte[] caddr2) {
652
for (i = 0; i < 16; i++) {
653
if (caddr1[i] != caddr2[i]) {
660
static int getScopeID (SOCKETADDRESS him) {
661
return him.him6.sin6_scope_id;
664
static boolean cmpScopeID (int scope, SOCKETADDRESS him) {
665
return him.him6.sin6_scope_id == scope;
668
/* these methods are not from net_util_md.c */
670
static boolean ipv6_available() {
671
return InetAddressImplFactory.isIPv6Supported();
674
static boolean IS_NULL(Object obj) {
678
static boolean IN6ADDR_ISANY(SOCKETADDRESS him) {
679
if (him.sa_family != AF_INET6) {
682
byte[] addr = him.him6.sin6_addr;
684
for (int i = 0; i < addr.length; i++) {
690
static boolean NET_SockaddrEqualsInetAddress(SOCKETADDRESS him, InetAddress iaObj) {
691
int family = iaObj.family == InetAddress.IPv4 ? AF_INET : AF_INET6;
693
if (him.sa_family == AF_INET6) {
694
byte[] caddrNew = him.him6.sin6_addr;
695
if (NET_IsIPv4Mapped(caddrNew)) {
698
if (family == AF_INET6) {
701
addrNew = NET_IPv4MappedToIPv4(caddrNew);
702
addrCur = iaObj.address;
703
if (addrNew == addrCur) {
712
if (family == AF_INET) {
715
scope = ((Inet6Address)iaObj).getScopeId();
716
caddrCur = ((Inet6Address)iaObj).ipaddress;
717
if (NET_IsEqual(caddrNew, caddrCur) && cmpScopeID(scope, him)) {
724
int addrNew, addrCur;
725
if (family != AF_INET) {
728
addrNew = ntohl(him.him4.sin_addr.s_addr);
729
addrCur = iaObj.address;
730
if (addrNew == addrCur) {
738
static InetAddress NET_SockaddrToInetAddress(JNIEnv env, SOCKETADDRESS him, int[] port) {
739
return NET_SockaddrToInetAddress(him, port);
742
static InetAddress NET_SockaddrToInetAddress(SOCKETADDRESS him, int[] port) {
744
if (him.sa_family == AF_INET6) {
745
byte[] caddr = him.him6.sin6_addr;
746
if (NET_IsIPv4Mapped(caddr)) {
747
iaObj = new Inet4Address(null, NET_IPv4MappedToIPv4(caddr));
749
int scope = getScopeID(him);
750
iaObj = new Inet6Address(null, caddr, scope > 0 ? scope : -1);
752
port[0] = ntohs(him.him6.sin_port);
754
iaObj = new Inet4Address(null, ntohl(him.him4.sin_addr.s_addr));
755
port[0] = ntohs(him.him4.sin_port);
760
static void NET_ThrowByNameWithLastError(JNIEnv env, String exceptionClass, String message) {
761
JNU_ThrowByName(env, exceptionClass, "errno: " + WSAGetLastError() + ", error: " + message + "\n");
764
static boolean IN_MULTICAST(int ipv4address) {
765
return ((ipv4address >> 24) & 0xf0) == 0xe0;
768
static boolean IN6_IS_ADDR_MULTICAST(in6_addr address) {
769
return (address.s6_bytes()[0] & 0xff) == 0xff;
772
static final class SOCKETADDRESS implements IIPEndPointWrapper {
773
final SOCKETADDRESS him = this;
774
final SOCKETADDRESS him4 = this;
775
final SOCKETADDRESS him6 = this;
776
final SOCKETADDRESS sin_addr = this;
783
public void set(IPEndPoint ep) {
791
sa_family = ep.get_AddressFamily().Value;
792
sin_port = htons(ep.get_Port());
793
if (sa_family == AF_INET) {
794
s_addr = (int)ep.get_Address().get_Address();
799
IPAddress addr = ep.get_Address();
800
sin6_addr = addr.GetAddressBytes();
801
sin6_scope_id = (int)addr.get_ScopeId();
806
public IPEndPoint get() {
807
if (sa_family == AF_INET) {
808
return new IPEndPoint(new IPAddress(s_addr & 0xFFFFFFFFL), ntohs(sin_port));
809
} else if (sa_family == AF_INET6) {
811
if (sin6_addr == null) {
812
addr = IPAddress.IPv6Any;
814
addr = new IPAddress(sin6_addr, sin6_scope_id & 0xFFFFFFFFL);
816
return new IPEndPoint(addr, ntohs(sin_port));
823
static int GET_PORT(SOCKETADDRESS sockaddr) {
824
return sockaddr.sin_port;
827
static void Sleep(int ms) {
828
cli.System.Threading.Thread.Sleep(ms);
831
static cli.System.Net.Sockets.Socket NET_Socket (int domain, int type, int protocol) {
832
cli.System.Net.Sockets.Socket sock;
833
sock = socket (domain, type, protocol);
834
if (sock != INVALID_SOCKET) {
835
//SetHandleInformation((HANDLE)(uintptr_t)sock, HANDLE_FLAG_INHERIT, FALSE);