1 /* Copyright (C) 2003 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
12 #ifdef HAVE_NETINET_IN_H
13 #include <netinet/in.h>
15 #ifdef HAVE_ARPA_INET_H
16 #include <arpa/inet.h>
22 // Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2
27 #include <gnu/java/net/PlainDatagramSocketImpl.h>
28 #include <java/io/IOException.h>
29 #include <java/io/InterruptedIOException.h>
30 #include <java/net/BindException.h>
31 #include <java/net/SocketException.h>
32 #include <java/net/SocketTimeoutException.h>
33 #include <java/net/InetAddress.h>
34 #include <java/net/NetworkInterface.h>
35 #include <java/net/DatagramPacket.h>
36 #include <java/net/PortUnreachableException.h>
37 #include <java/lang/InternalError.h>
38 #include <java/lang/Object.h>
39 #include <java/lang/Boolean.h>
40 #include <java/lang/Integer.h>
44 struct sockaddr_in address
;
46 struct sockaddr_in6 address6
;
52 #if HAVE_STRUCT_IP_MREQ
55 #if HAVE_STRUCT_IPV6_MREQ
56 struct ipv6_mreq mreq6
;
64 struct in6_addr addr6
;
69 // FIXME: routines here and/or in natPlainSocketImpl.cc could throw
70 // NoRouteToHostException; also consider UnknownHostException, ConnectException.
73 gnu::java::net::PlainDatagramSocketImpl::create ()
75 int sock
= _Jv_socket (AF_INET
, SOCK_DGRAM
, 0);
79 char* strerr
= strerror (errno
);
80 throw new ::java::net::SocketException (JvNewStringUTF (strerr
));
83 _Jv_platform_close_on_exec (sock
);
85 // We use native_fd in place of fd here. From leaving fd null we avoid
86 // the double close problem in FileDescriptor.finalize.
91 gnu::java::net::PlainDatagramSocketImpl::bind (jint lport
,
92 ::java::net::InetAddress
*host
)
95 struct sockaddr
*ptr
= (struct sockaddr
*) &u
.address
;
96 // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4.
97 jbyteArray haddress
= host
->addr
;
98 jbyte
*bytes
= elements (haddress
);
99 int len
= haddress
->length
;
103 u
.address
.sin_family
= AF_INET
;
106 memcpy (&u
.address
.sin_addr
, bytes
, len
);
108 u
.address
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
110 len
= sizeof (struct sockaddr_in
);
111 u
.address
.sin_port
= htons (lport
);
116 u
.address6
.sin6_family
= AF_INET6
;
117 memcpy (&u
.address6
.sin6_addr
, bytes
, len
);
118 len
= sizeof (struct sockaddr_in6
);
119 u
.address6
.sin6_port
= htons (lport
);
123 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
125 if (_Jv_bind (native_fd
, ptr
, len
) == 0)
127 socklen_t addrlen
= sizeof(u
);
131 else if (::getsockname (native_fd
, (sockaddr
*) &u
, &addrlen
) == 0)
132 localPort
= ntohs (u
.address
.sin_port
);
136 /* Allow broadcast by default. */
138 if (::setsockopt (native_fd
, SOL_SOCKET
, SO_BROADCAST
, (char *) &broadcast
,
139 sizeof (broadcast
)) != 0)
146 char* strerr
= strerror (errno
);
147 throw new ::java::net::BindException (JvNewStringUTF (strerr
));
151 gnu::java::net::PlainDatagramSocketImpl::connect (::java::net::InetAddress
*, jint
)
153 throw new ::java::lang::InternalError (JvNewStringLatin1 (
154 "PlainDatagramSocketImpl::connect: not implemented yet"));
158 gnu::java::net::PlainDatagramSocketImpl::disconnect ()
160 throw new ::java::lang::InternalError (JvNewStringLatin1 (
161 "PlainDatagramSocketImpl::disconnect: not implemented yet"));
165 gnu::java::net::PlainDatagramSocketImpl::peek (::java::net::InetAddress
*i
)
167 // FIXME: Deal with Multicast and if the socket is connected.
169 socklen_t addrlen
= sizeof(u
);
171 ::recvfrom (native_fd
, (char *) NULL
, 0, MSG_PEEK
, (sockaddr
*) &u
,
175 // FIXME: Deal with Multicast addressing and if the socket is connected.
178 if (u
.address
.sin_family
== AF_INET
)
180 raddr
= JvNewByteArray (4);
181 memcpy (elements (raddr
), &u
.address
.sin_addr
, 4);
182 rport
= ntohs (u
.address
.sin_port
);
185 else if (u
.address
.sin_family
== AF_INET6
)
187 raddr
= JvNewByteArray (16);
188 memcpy (elements (raddr
), &u
.address6
.sin6_addr
, 16);
189 rport
= ntohs (u
.address6
.sin6_port
);
193 throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
198 char* strerr
= strerror (errno
);
200 if (errno
== ECONNREFUSED
)
201 throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr
));
203 throw new ::java::io::IOException (JvNewStringUTF (strerr
));
207 gnu::java::net::PlainDatagramSocketImpl::peekData (::java::net::DatagramPacket
*p
)
209 // FIXME: Deal with Multicast and if the socket is connected.
211 socklen_t addrlen
= sizeof(u
);
212 jbyte
*dbytes
= elements (p
->getData()) + p
->getOffset();
213 jint maxlen
= p
->maxlen
- p
->getOffset();
216 // Do timeouts via select since SO_RCVTIMEO is not always available.
217 if (timeout
> 0 && native_fd
>= 0 && native_fd
< FD_SETSIZE
)
222 FD_SET(native_fd
, &rset
);
223 tv
.tv_sec
= timeout
/ 1000;
224 tv
.tv_usec
= (timeout
% 1000) * 1000;
226 if ((retval
= _Jv_select (native_fd
+ 1, &rset
, NULL
, NULL
, &tv
)) < 0)
228 else if (retval
== 0)
229 throw new ::java::net::SocketTimeoutException
230 (JvNewStringUTF ("PeekData timed out") );
234 ::recvfrom (native_fd
, (char *) dbytes
, maxlen
, MSG_PEEK
, (sockaddr
*) &u
,
238 // FIXME: Deal with Multicast addressing and if the socket is connected.
241 if (u
.address
.sin_family
== AF_INET
)
243 raddr
= JvNewByteArray (4);
244 memcpy (elements (raddr
), &u
.address
.sin_addr
, 4);
245 rport
= ntohs (u
.address
.sin_port
);
248 else if (u
.address
.sin_family
== AF_INET6
)
250 raddr
= JvNewByteArray (16);
251 memcpy (elements (raddr
), &u
.address6
.sin6_addr
, 16);
252 rport
= ntohs (u
.address6
.sin6_port
);
256 throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
258 p
->setAddress (new ::java::net::InetAddress (raddr
, NULL
));
260 p
->length
= (int) retlen
;
264 char* strerr
= strerror (errno
);
266 if (errno
== ECONNREFUSED
)
267 throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr
));
269 throw new ::java::io::IOException (JvNewStringUTF (strerr
));
272 // Close(shutdown) the socket.
274 gnu::java::net::PlainDatagramSocketImpl::close ()
276 // Avoid races from asynchronous finalization.
277 JvSynchronize
sync (this);
279 // The method isn't declared to throw anything, so we disregard
281 _Jv_close (native_fd
);
287 gnu::java::net::PlainDatagramSocketImpl::send (::java::net::DatagramPacket
*p
)
289 JvSynchronize
lock (SEND_LOCK
);
291 // FIXME: Deal with Multicast and if the socket is connected.
292 jint rport
= p
->getPort();
294 jbyteArray haddress
= p
->getAddress()->addr
;
295 jbyte
*bytes
= elements (haddress
);
296 int len
= haddress
->length
;
297 struct sockaddr
*ptr
= (struct sockaddr
*) &u
.address
;
298 jbyte
*dbytes
= elements (p
->getData()) + p
->getOffset();
301 u
.address
.sin_family
= AF_INET
;
302 memcpy (&u
.address
.sin_addr
, bytes
, len
);
303 len
= sizeof (struct sockaddr_in
);
304 u
.address
.sin_port
= htons (rport
);
309 u
.address6
.sin6_family
= AF_INET6
;
310 memcpy (&u
.address6
.sin6_addr
, bytes
, len
);
311 len
= sizeof (struct sockaddr_in6
);
312 u
.address6
.sin6_port
= htons (rport
);
316 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
318 if (::sendto (native_fd
, (char *) dbytes
, p
->getLength(), 0, ptr
, len
) >= 0)
321 char* strerr
= strerror (errno
);
323 if (errno
== ECONNREFUSED
)
324 throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr
));
326 throw new ::java::io::IOException (JvNewStringUTF (strerr
));
330 gnu::java::net::PlainDatagramSocketImpl::receive (::java::net::DatagramPacket
*p
)
332 JvSynchronize
lock (RECEIVE_LOCK
);
334 // FIXME: Deal with Multicast and if the socket is connected.
336 socklen_t addrlen
= sizeof(u
);
337 jbyte
*dbytes
= elements (p
->getData()) + p
->getOffset();
338 jint maxlen
= p
->maxlen
- p
->getOffset();
341 // Do timeouts via select since SO_RCVTIMEO is not always available.
342 if (timeout
> 0 && native_fd
>= 0 && native_fd
< FD_SETSIZE
)
347 FD_SET(native_fd
, &rset
);
348 tv
.tv_sec
= timeout
/ 1000;
349 tv
.tv_usec
= (timeout
% 1000) * 1000;
351 if ((retval
= _Jv_select (native_fd
+ 1, &rset
, NULL
, NULL
, &tv
)) < 0)
353 else if (retval
== 0)
354 throw new ::java::net::SocketTimeoutException
355 (JvNewStringUTF ("Receive timed out") );
359 ::recvfrom (native_fd
, (char *) dbytes
, maxlen
, 0, (sockaddr
*) &u
,
363 // FIXME: Deal with Multicast addressing and if the socket is connected.
366 if (u
.address
.sin_family
== AF_INET
)
368 raddr
= JvNewByteArray (4);
369 memcpy (elements (raddr
), &u
.address
.sin_addr
, 4);
370 rport
= ntohs (u
.address
.sin_port
);
373 else if (u
.address
.sin_family
== AF_INET6
)
375 raddr
= JvNewByteArray (16);
376 memcpy (elements (raddr
), &u
.address6
.sin6_addr
, 16);
377 rport
= ntohs (u
.address6
.sin6_port
);
381 throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
383 p
->setAddress (new ::java::net::InetAddress (raddr
, NULL
));
385 p
->length
= (jint
) retlen
;
389 char* strerr
= strerror (errno
);
391 if (errno
== ECONNREFUSED
)
392 throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr
));
394 throw new ::java::io::IOException (JvNewStringUTF (strerr
));
398 gnu::java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl
)
400 // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
401 char val
= (char) ttl
;
402 socklen_t val_len
= sizeof(val
);
404 if (::setsockopt (native_fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, &val
, val_len
) == 0)
407 char* strerr
= strerror (errno
);
408 throw new ::java::io::IOException (JvNewStringUTF (strerr
));
412 gnu::java::net::PlainDatagramSocketImpl::getTimeToLive ()
414 // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
416 socklen_t val_len
= sizeof(val
);
418 if (::getsockopt (native_fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, &val
, &val_len
) == 0)
419 return ((int) val
) & 0xFF;
421 char* strerr
= strerror (errno
);
422 throw new ::java::io::IOException (JvNewStringUTF (strerr
));
426 gnu::java::net::PlainDatagramSocketImpl::mcastGrp (::java::net::InetAddress
*inetaddr
,
427 ::java::net::NetworkInterface
*,
430 // FIXME: implement use of NetworkInterface
432 jbyteArray haddress
= inetaddr
->addr
;
433 #if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IPV6_MREQ
435 jbyte
*bytes
= elements (haddress
);
438 int len
= haddress
->length
;
443 #if HAVE_STRUCT_IP_MREQ
447 opname
= join
? IP_ADD_MEMBERSHIP
: IP_DROP_MEMBERSHIP
;
448 memcpy (&u
.mreq
.imr_multiaddr
, bytes
, len
);
449 // FIXME: If a non-default interface is set, use it; see Stevens p. 501.
450 // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
451 u
.mreq
.imr_interface
.s_addr
= htonl (INADDR_ANY
);
452 len
= sizeof (struct ip_mreq
);
453 ptr
= (const char *) &u
.mreq
;
456 #if HAVE_STRUCT_IPV6_MREQ
459 level
= IPPROTO_IPV6
;
461 /* Prefer new RFC 2553 names. */
462 #ifndef IPV6_JOIN_GROUP
463 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
465 #ifndef IPV6_LEAVE_GROUP
466 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
469 opname
= join
? IPV6_JOIN_GROUP
: IPV6_LEAVE_GROUP
;
470 memcpy (&u
.mreq6
.ipv6mr_multiaddr
, bytes
, len
);
471 // FIXME: If a non-default interface is set, use it; see Stevens p. 501.
472 // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
473 u
.mreq6
.ipv6mr_interface
= 0;
474 len
= sizeof (struct ipv6_mreq
);
475 ptr
= (const char *) &u
.mreq6
;
479 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
481 if (::setsockopt (native_fd
, level
, opname
, ptr
, len
) == 0)
484 char* strerr
= strerror (errno
);
485 throw new ::java::io::IOException (JvNewStringUTF (strerr
));
489 gnu::java::net::PlainDatagramSocketImpl::setOption (jint optID
,
490 ::java::lang::Object
*value
)
493 socklen_t val_len
= sizeof (val
);
496 throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed"));
498 if (_Jv_IsInstanceOf (value
, &::java::lang::Boolean::class$
))
500 ::java::lang::Boolean
*boolobj
=
501 static_cast< ::java::lang::Boolean
*> (value
);
502 val
= boolobj
->booleanValue() ? 1 : 0;
504 else if (_Jv_IsInstanceOf (value
, &::java::lang::Integer::class$
))
506 ::java::lang::Integer
*intobj
=
507 static_cast< ::java::lang::Integer
*> (value
);
508 val
= (int) intobj
->intValue();
510 // Else assume value to be an InetAddress for use with IP_MULTICAST_IF.
514 case _Jv_TCP_NODELAY_
:
515 throw new ::java::net::SocketException (
516 JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
518 case _Jv_SO_LINGER_
:
519 throw new ::java::net::SocketException (
520 JvNewStringUTF ("SO_LINGER not valid for UDP"));
522 case _Jv_SO_KEEPALIVE_
:
523 throw new ::java::net::SocketException (
524 JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
527 case _Jv_SO_BROADCAST_
:
528 if (::setsockopt (native_fd
, SOL_SOCKET
, SO_BROADCAST
, (char *) &val
,
533 case _Jv_SO_OOBINLINE_
:
534 throw new ::java::net::SocketException (
535 JvNewStringUTF ("SO_OOBINLINE: not valid for UDP"));
538 case _Jv_SO_SNDBUF_
:
539 case _Jv_SO_RCVBUF_
:
540 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
542 optID
== _Jv_SO_SNDBUF_
? opt
= SO_SNDBUF
: opt
= SO_RCVBUF
;
543 if (::setsockopt (native_fd
, SOL_SOCKET
, opt
, (char *) &val
, val_len
) != 0)
546 throw new ::java::lang::InternalError (
547 JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
550 case _Jv_SO_REUSEADDR_
:
551 #if defined(SO_REUSEADDR)
552 if (::setsockopt (native_fd
, SOL_SOCKET
, SO_REUSEADDR
, (char *) &val
,
556 throw new ::java::lang::InternalError (
557 JvNewStringUTF ("SO_REUSEADDR not supported"));
560 case _Jv_SO_BINDADDR_
:
561 throw new ::java::net::SocketException (
562 JvNewStringUTF ("SO_BINDADDR: read only option"));
564 case _Jv_IP_MULTICAST_IF_
:
572 haddress
= ((::java::net::InetAddress
*) value
)->addr
;
573 bytes
= elements (haddress
);
574 len
= haddress
->length
;
578 opname
= IP_MULTICAST_IF
;
579 memcpy (&u
.addr
, bytes
, len
);
580 len
= sizeof (struct in_addr
);
581 ptr
= (const char *) &u
.addr
;
583 // Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF
584 #if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF)
587 level
= IPPROTO_IPV6
;
588 opname
= IPV6_MULTICAST_IF
;
589 memcpy (&u
.addr6
, bytes
, len
);
590 len
= sizeof (struct in6_addr
);
591 ptr
= (const char *) &u
.addr6
;
596 new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
598 if (::setsockopt (native_fd
, level
, opname
, ptr
, len
) != 0)
602 case _Jv_IP_MULTICAST_IF2_
:
603 throw new ::java::net::SocketException (
604 JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
607 case _Jv_IP_MULTICAST_LOOP_
:
608 haddress
= ((::java::net::InetAddress
*) value
)->addr
;
609 len
= haddress
->length
;
613 opname
= IP_MULTICAST_LOOP
;
615 #if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP)
618 level
= IPPROTO_IPV6
;
619 opname
= IPV6_MULTICAST_LOOP
;
624 new ::java::net::SocketException (JvNewStringUTF ("invalid address length"));
625 if (::setsockopt (native_fd
, level
, opname
, (char *) &val
,
631 if (::setsockopt (native_fd
, SOL_SOCKET
, IP_TOS
, (char *) &val
,
636 case _Jv_SO_TIMEOUT_
:
644 char* strerr
= strerror (errno
);
645 throw new ::java::net::SocketException (JvNewStringUTF (strerr
));
648 ::java::lang::Object
*
649 gnu::java::net::PlainDatagramSocketImpl::getOption (jint optID
)
652 socklen_t val_len
= sizeof(val
);
654 socklen_t addrlen
= sizeof(u
);
659 case _Jv_TCP_NODELAY_
:
660 throw new ::java::net::SocketException (
661 JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
663 case _Jv_SO_LINGER_
:
664 throw new ::java::net::SocketException (
665 JvNewStringUTF ("SO_LINGER not valid for UDP"));
667 case _Jv_SO_KEEPALIVE_
:
668 throw new ::java::net::SocketException (
669 JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
672 case _Jv_SO_BROADCAST_
:
673 if (::getsockopt (native_fd
, SOL_SOCKET
, SO_BROADCAST
, (char *) &val
,
676 return new ::java::lang::Boolean (val
!= 0);
678 case _Jv_SO_OOBINLINE_
:
679 throw new ::java::net::SocketException (
680 JvNewStringUTF ("SO_OOBINLINE not valid for UDP"));
683 case _Jv_SO_RCVBUF_
:
684 case _Jv_SO_SNDBUF_
:
685 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
687 optID
== _Jv_SO_SNDBUF_
? opt
= SO_SNDBUF
: opt
= SO_RCVBUF
;
688 if (::getsockopt (native_fd
, SOL_SOCKET
, opt
, (char *) &val
, &val_len
) != 0)
691 return new ::java::lang::Integer (val
);
693 throw new ::java::lang::InternalError (
694 JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
697 case _Jv_SO_BINDADDR_
:
698 // cache the local address
699 if (localAddress
== NULL
)
702 if (::getsockname (native_fd
, (sockaddr
*) &u
, &addrlen
) != 0)
704 if (u
.address
.sin_family
== AF_INET
)
706 laddr
= JvNewByteArray (4);
707 memcpy (elements (laddr
), &u
.address
.sin_addr
, 4);
710 else if (u
.address
.sin_family
== AF_INET6
)
712 laddr
= JvNewByteArray (16);
713 memcpy (elements (laddr
), &u
.address6
.sin6_addr
, 16);
717 throw new ::java::net::SocketException (
718 JvNewStringUTF ("invalid family"));
719 localAddress
= new ::java::net::InetAddress (laddr
, NULL
);
723 case _Jv_SO_REUSEADDR_
:
724 #if defined(SO_REUSEADDR)
725 if (::getsockopt (native_fd
, SOL_SOCKET
, SO_REUSEADDR
, (char *) &val
,
728 return new ::java::lang::Boolean (val
!= 0);
730 throw new ::java::lang::InternalError (
731 JvNewStringUTF ("SO_REUSEADDR not supported"));
734 case _Jv_IP_MULTICAST_IF_
:
735 #ifdef HAVE_INET_NTOA
736 struct in_addr inaddr
;
737 socklen_t inaddr_len
;
740 inaddr_len
= sizeof(inaddr
);
741 if (::getsockopt (native_fd
, IPPROTO_IP
, IP_MULTICAST_IF
, (char *) &inaddr
,
745 bytes
= inet_ntoa (inaddr
);
747 return ::java::net::InetAddress::getByName (JvNewStringLatin1 (bytes
));
749 throw new ::java::net::SocketException (
750 JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()"));
753 case _Jv_SO_TIMEOUT_
:
754 return new ::java::lang::Integer (timeout
);
757 case _Jv_IP_MULTICAST_IF2_
:
758 throw new ::java::net::SocketException (
759 JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
762 case _Jv_IP_MULTICAST_LOOP_
:
763 // cache the local address
764 if (localAddress
== NULL
)
767 if (::getsockname (native_fd
, (sockaddr
*) &u
, &addrlen
) != 0)
769 if (u
.address
.sin_family
== AF_INET
)
771 laddr
= JvNewByteArray (4);
772 memcpy (elements (laddr
), &u
.address
.sin_addr
, 4);
775 else if (u
.address
.sin_family
== AF_INET6
)
777 laddr
= JvNewByteArray (16);
778 memcpy (elements (laddr
), &u
.address6
.sin6_addr
, 16);
782 throw new ::java::net::SocketException (
783 JvNewStringUTF ("invalid family"));
784 localAddress
= new ::java::net::InetAddress (laddr
, NULL
);
787 if (localAddress
->addr
->length
== 4)
790 opname
= IP_MULTICAST_LOOP
;
792 #if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP)
793 else if (localAddress
->addr
->length
== 16)
795 level
= IPPROTO_IPV6
;
796 opname
= IPV6_MULTICAST_LOOP
;
801 new ::java::net::SocketException (JvNewStringUTF ("invalid address length"));
802 if (::getsockopt (native_fd
, level
, opname
, (char *) &val
,
805 return new ::java::lang::Boolean (val
!= 0);
808 if (::getsockopt (native_fd
, SOL_SOCKET
, IP_TOS
, (char *) &val
,
811 return new ::java::lang::Integer (val
);
818 char* strerr
= strerror (errno
);
819 throw new ::java::net::SocketException (JvNewStringUTF (strerr
));