/* Copyright (C) 2003, 2005, 2006  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#include <config.h>
#include <platform.h>

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <errno.h>
#include <string.h>

#if HAVE_BSTRING_H
// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 
#include <bstring.h>
#endif

#include <gcj/cni.h>
#include <gnu/java/net/PlainDatagramSocketImpl.h>
#include <java/io/IOException.h>
#include <java/io/InterruptedIOException.h>
#include <java/net/BindException.h>
#include <java/net/SocketException.h>
#include <java/net/SocketTimeoutException.h>
#include <java/net/InetAddress.h>
#include <java/net/NetworkInterface.h>
#include <java/net/DatagramPacket.h>
#include <java/net/PortUnreachableException.h>
#include <java/lang/InternalError.h>
#include <java/lang/Object.h>
#include <java/lang/Boolean.h>
#include <java/lang/Integer.h>
#include <java/net/UnknownHostException.h>
#include <java/net/ConnectException.h>
#include <java/lang/NullPointerException.h>

union SockAddr
{
  struct sockaddr_in address;
#ifdef HAVE_INET6
  struct sockaddr_in6 address6;
#endif
};

union McastReq
{
#if HAVE_STRUCT_IP_MREQ
  struct ip_mreq mreq;
#endif
#if HAVE_STRUCT_IPV6_MREQ
  struct ipv6_mreq mreq6;
#endif
};

union InAddr
{
  struct in_addr addr;
#ifdef HAVE_INET6
  struct in6_addr addr6;
#endif
};


// FIXME: routines here and/or in natPlainSocketImpl.cc could throw
// NoRouteToHostException; also consider UnknownHostException, ConnectException.

void
gnu::java::net::PlainDatagramSocketImpl::create ()
{
  int sock = _Jv_socket (AF_INET, SOCK_DGRAM, 0);

  if (sock < 0)
    {
      char* strerr = strerror (errno);
      throw new ::java::net::SocketException (JvNewStringUTF (strerr));
    }

  // We use native_fd in place of fd here.  From leaving fd null we avoid
  // the double close problem in FileDescriptor.finalize.
  native_fd = sock;
}

void
gnu::java::net::PlainDatagramSocketImpl::bind (jint lport,
                                               ::java::net::InetAddress *host)
{
  union SockAddr u;
  struct sockaddr *ptr = (struct sockaddr *) &u.address;
  // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4.
  jbyteArray haddress = host->addr;
  jbyte *bytes = elements (haddress);
  int len = haddress->length;

  if (len == 4)
    {
      u.address.sin_family = AF_INET;

      if (host != NULL)
        memcpy (&u.address.sin_addr, bytes, len);
      else
        u.address.sin_addr.s_addr = htonl (INADDR_ANY);

      len = sizeof (struct sockaddr_in);
      u.address.sin_port = htons (lport);
    }
#ifdef HAVE_INET6
  else if (len == 16)
    {
      u.address6.sin6_family = AF_INET6;
      memcpy (&u.address6.sin6_addr, bytes, len);
      len = sizeof (struct sockaddr_in6);
      u.address6.sin6_port = htons (lport);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));

  if (_Jv_bind (native_fd, ptr, len) == 0)
    {
      socklen_t addrlen = sizeof(u);

      if (lport != 0)
        localPort = lport;
      else if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) == 0)
        localPort = ntohs (u.address.sin_port);
      else
        goto error;

      /* Allow broadcast by default. */
      int broadcast = 1;
      if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast, 
                        sizeof (broadcast)) != 0)
        goto error;

      return;
    }

 error:
  char* strerr = strerror (errno);
  throw new ::java::net::BindException (JvNewStringUTF (strerr));
}

void
gnu::java::net::PlainDatagramSocketImpl::connect (::java::net::InetAddress *host,
						  jint rport)
{ 
  if (! host)
    throw new ::java::lang::NullPointerException;

  union SockAddr u;
  jbyteArray haddress = host->addr;
  jbyte *bytes = elements (haddress);
  int len = haddress->length;
  struct sockaddr *ptr = (struct sockaddr *) &u.address;
  if (len == 4)
    {
      u.address.sin_family = AF_INET;
      memcpy (&u.address.sin_addr, bytes, len);
      len = sizeof (struct sockaddr_in);
      u.address.sin_port = htons (rport);
    }
#ifdef HAVE_INET6
  else if (len == 16)
    {
      u.address6.sin6_family = AF_INET6;
      memcpy (&u.address6.sin6_addr, bytes, len);
      len = sizeof (struct sockaddr_in6);
      u.address6.sin6_port = htons (rport);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
  
  if (_Jv_connect (native_fd, ptr, len) == 0)
    return;
  char* strerr = strerror (errno);
  throw new ::java::net::ConnectException (JvNewStringUTF (strerr));
}

void
gnu::java::net::PlainDatagramSocketImpl::disconnect ()
{
  struct sockaddr addr;
  addr.sa_family = AF_UNSPEC;
  // Ignore errors.  This is lame but apparently required.
  _Jv_connect (native_fd, &addr, sizeof (addr));
}

jint
gnu::java::net::PlainDatagramSocketImpl::peek (::java::net::InetAddress *i)
{
  // FIXME: Deal with Multicast and if the socket is connected.
  union SockAddr u;
  socklen_t addrlen = sizeof(u);
  ssize_t retlen =
    ::recvfrom (native_fd, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u,
      &addrlen);
  if (retlen < 0)
    goto error;
  // FIXME: Deal with Multicast addressing and if the socket is connected.
  jbyteArray raddr;
  jint rport;
  if (u.address.sin_family == AF_INET)
    {
      raddr = JvNewByteArray (4);
      memcpy (elements (raddr), &u.address.sin_addr, 4);
      rport = ntohs (u.address.sin_port);
    }
#ifdef HAVE_INET6
  else if (u.address.sin_family == AF_INET6)
    {
      raddr = JvNewByteArray (16);
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
      rport = ntohs (u.address6.sin6_port);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));

  i->addr = raddr;
  return rport;
 error:
  char* strerr = strerror (errno);

  if (errno == ECONNREFUSED)
    throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr));

  throw new ::java::io::IOException (JvNewStringUTF (strerr));
}

jint
gnu::java::net::PlainDatagramSocketImpl::peekData (::java::net::DatagramPacket *p)
{
  // FIXME: Deal with Multicast and if the socket is connected.
  union SockAddr u;
  socklen_t addrlen = sizeof(u);
  jbyte *dbytes = elements (p->getData()) + p->getOffset();
  jint maxlen = p->maxlen - p->getOffset();
  ssize_t retlen = 0;

  // Do timeouts via select since SO_RCVTIMEO is not always available.
  if (timeout > 0 && native_fd >= 0 && native_fd < FD_SETSIZE)
    {
      fd_set rset;
      struct timeval tv;
      FD_ZERO(&rset);
      FD_SET(native_fd, &rset);
      tv.tv_sec = timeout / 1000;
      tv.tv_usec = (timeout % 1000) * 1000;
      int retval;
      if ((retval = _Jv_select (native_fd + 1, &rset, NULL, NULL, &tv)) < 0)
        goto error;
      else if (retval == 0)
        throw new ::java::net::SocketTimeoutException
          (JvNewStringUTF ("PeekData timed out") );
    }

  retlen =
    ::recvfrom (native_fd, (char *) dbytes, maxlen, MSG_PEEK, (sockaddr*) &u,
      &addrlen);
  if (retlen < 0)
    goto error;
  // FIXME: Deal with Multicast addressing and if the socket is connected.
  jbyteArray raddr;
  jint rport;
  if (u.address.sin_family == AF_INET)
    {
      raddr = JvNewByteArray (4);
      memcpy (elements (raddr), &u.address.sin_addr, 4);
      rport = ntohs (u.address.sin_port);
    }
#ifdef HAVE_INET6
  else if (u.address.sin_family == AF_INET6)
    {
      raddr = JvNewByteArray (16);
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
      rport = ntohs (u.address6.sin6_port);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));

  p->setAddress (::java::net::InetAddress::getByAddress (raddr));
  p->setPort (rport);
  p->length = (int) retlen;
  return rport;

 error:
  char* strerr = strerror (errno);

  if (errno == ECONNREFUSED)
    throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr));

  throw new ::java::io::IOException (JvNewStringUTF (strerr));
}

// Close(shutdown) the socket.
void
gnu::java::net::PlainDatagramSocketImpl::close ()
{
  // Avoid races from asynchronous finalization.
  JvSynchronize sync (this);

  // The method isn't declared to throw anything, so we disregard
  // the return value.
  _Jv_close (native_fd);
  native_fd = -1;
  timeout = 0;
}

void
gnu::java::net::PlainDatagramSocketImpl::send (::java::net::DatagramPacket *p)
{
  JvSynchronize lock (SEND_LOCK);
  
  // FIXME: Deal with Multicast.

  ::java::net::InetAddress *host = p->getAddress();
  if (host == NULL)
    {
      // If there is no host, maybe this socket was connected, in
      // which case we try a plain send().
      jbyte *dbytes = elements (p->getData()) + p->getOffset();
      if (::send (native_fd, (char *) dbytes, p->getLength(), 0) >= 0)
	return;
    }
  else
    {
      jint rport = p->getPort();
      union SockAddr u;

      jbyteArray haddress = host->addr;
      jbyte *bytes = elements (haddress);
      int len = haddress->length;
      struct sockaddr *ptr = (struct sockaddr *) &u.address;
      jbyte *dbytes = elements (p->getData()) + p->getOffset();
      if (len == 4)
	{
	  u.address.sin_family = AF_INET;
	  memcpy (&u.address.sin_addr, bytes, len);
	  len = sizeof (struct sockaddr_in);
	  u.address.sin_port = htons (rport);
	}
#ifdef HAVE_INET6
      else if (len == 16)
	{
	  u.address6.sin6_family = AF_INET6;
	  memcpy (&u.address6.sin6_addr, bytes, len);
	  len = sizeof (struct sockaddr_in6);
	  u.address6.sin6_port = htons (rport);
	}
#endif
      else
	throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));

      if (::sendto (native_fd, (char *) dbytes, p->getLength(), 0, ptr, len)
	  >= 0)
	return;
    }

  char* strerr = strerror (errno);

  if (errno == ECONNREFUSED)
    throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr));

  throw new ::java::io::IOException (JvNewStringUTF (strerr));
}

void
gnu::java::net::PlainDatagramSocketImpl::receive (::java::net::DatagramPacket *p)
{
  JvSynchronize lock (RECEIVE_LOCK);

  // FIXME: Deal with Multicast and if the socket is connected.
  union SockAddr u;
  socklen_t addrlen = sizeof(u);
  jbyte *dbytes = elements (p->getData()) + p->getOffset();
  jint maxlen = p->maxlen - p->getOffset();
  ssize_t retlen = 0;

  // Do timeouts via select since SO_RCVTIMEO is not always available.
  if (timeout > 0 && native_fd >= 0 && native_fd < FD_SETSIZE)
    {
      fd_set rset;
      struct timeval tv;
      FD_ZERO(&rset);
      FD_SET(native_fd, &rset);
      tv.tv_sec = timeout / 1000;
      tv.tv_usec = (timeout % 1000) * 1000;
      int retval;
      if ((retval = _Jv_select (native_fd + 1, &rset, NULL, NULL, &tv)) < 0)
        goto error;
      else if (retval == 0)
        throw new ::java::net::SocketTimeoutException
          (JvNewStringUTF ("Receive timed out") );
    }

  retlen =
    ::recvfrom (native_fd, (char *) dbytes, maxlen, 0, (sockaddr*) &u,
      &addrlen);
  if (retlen < 0)
    goto error;
  // FIXME: Deal with Multicast addressing and if the socket is connected.
  jbyteArray raddr;
  jint rport;
  if (u.address.sin_family == AF_INET)
    {
      raddr = JvNewByteArray (4);
      memcpy (elements (raddr), &u.address.sin_addr, 4);
      rport = ntohs (u.address.sin_port);
    }
#ifdef HAVE_INET6
  else if (u.address.sin_family == AF_INET6)
    {
      raddr = JvNewByteArray (16);
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
      rport = ntohs (u.address6.sin6_port);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));

  p->setAddress (::java::net::InetAddress::getByAddress (raddr));
  p->setPort (rport);
  p->length = (jint) retlen;
  return;

 error:
  char* strerr = strerror (errno);

  if (errno == ECONNREFUSED)
    throw new ::java::net::PortUnreachableException (JvNewStringUTF (strerr));

  throw new ::java::io::IOException (JvNewStringUTF (strerr));
}

void
gnu::java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl)
{
  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
  char val = (char) ttl;
  socklen_t val_len = sizeof(val);

  if (::setsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0)
    return;

  char* strerr = strerror (errno);
  throw new ::java::io::IOException (JvNewStringUTF (strerr));
}

jint
gnu::java::net::PlainDatagramSocketImpl::getTimeToLive ()
{
  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
  char val;
  socklen_t val_len = sizeof(val);

  if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0)
    return ((int) val) & 0xFF;

  char* strerr = strerror (errno);
  throw new ::java::io::IOException (JvNewStringUTF (strerr));
}

void
gnu::java::net::PlainDatagramSocketImpl::mcastGrp (::java::net::InetAddress *inetaddr,
                                                   ::java::net::NetworkInterface *,
                                                   jboolean join)
{
  // FIXME: implement use of NetworkInterface

  jbyteArray haddress = inetaddr->addr;
#if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IPV6_MREQ
  union McastReq u;
  jbyte *bytes = elements (haddress);
#endif

  int len = haddress->length;
  int level, opname;
  const char *ptr;
  if (0)
    ;
#if HAVE_STRUCT_IP_MREQ
  else if (len == 4)
    {
      level = IPPROTO_IP;
      opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
      memcpy (&u.mreq.imr_multiaddr, bytes, len);
      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
      u.mreq.imr_interface.s_addr = htonl (INADDR_ANY); 
      len = sizeof (struct ip_mreq);
      ptr = (const char *) &u.mreq;
    }
#endif
#if HAVE_STRUCT_IPV6_MREQ
  else if (len == 16)
    {
      level = IPPROTO_IPV6;

      /* Prefer new RFC 2553 names.  */
#ifndef IPV6_JOIN_GROUP
#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
#endif
#ifndef IPV6_LEAVE_GROUP
#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#endif

      opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP;
      memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len);
      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
      u.mreq6.ipv6mr_interface = 0;
      len = sizeof (struct ipv6_mreq);
      ptr = (const char *) &u.mreq6;
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));

  if (::setsockopt (native_fd, level, opname, ptr, len) == 0)
    return;

  char* strerr = strerror (errno);
  throw new ::java::io::IOException (JvNewStringUTF (strerr));
}

// Helper function to get the InetAddress for a given socket (file
// descriptor).
static ::java::net::InetAddress *
getLocalAddress (int native_fd)
{
  jbyteArray laddr;
  union SockAddr u;
  socklen_t addrlen = sizeof(u);

  if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != 0)
    {
      char* strerr = strerror (errno);
      throw new ::java::net::SocketException (JvNewStringUTF (strerr));
    }
  if (u.address.sin_family == AF_INET)
    {
      laddr = JvNewByteArray (4);
      memcpy (elements (laddr), &u.address.sin_addr, 4);
    }
#ifdef HAVE_INET6
  else if (u.address.sin_family == AF_INET6)
    {
      laddr = JvNewByteArray (16);
      memcpy (elements (laddr), &u.address6.sin6_addr, 16);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));

  return ::java::net::InetAddress::getByAddress (laddr);
}

void
gnu::java::net::PlainDatagramSocketImpl::setOption (jint optID,
                                                    ::java::lang::Object *value)
{
  int val;
  socklen_t val_len = sizeof (val);

  if (native_fd < 0)
    throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed"));

  if (_Jv_IsInstanceOf (value, &::java::lang::Boolean::class$))
    {
      ::java::lang::Boolean *boolobj = 
        static_cast< ::java::lang::Boolean *> (value);
      val = boolobj->booleanValue() ? 1 : 0;
    }
  else if (_Jv_IsInstanceOf (value, &::java::lang::Integer::class$))
    {
      ::java::lang::Integer *intobj = 
        static_cast< ::java::lang::Integer *> (value);          
      val = (int) intobj->intValue();
    }
  // Else assume value to be an InetAddress for use with IP_MULTICAST_IF.

  switch (optID) 
    {
      case _Jv_TCP_NODELAY_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
        return;
      case _Jv_SO_LINGER_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_LINGER not valid for UDP"));
        return;
      case _Jv_SO_KEEPALIVE_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
        return;

      case _Jv_SO_BROADCAST_ :
        if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
                          val_len) != 0)
          goto error;
	return;
	
      case _Jv_SO_OOBINLINE_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_OOBINLINE: not valid for UDP"));
        return;
	
      case _Jv_SO_SNDBUF_ :
      case _Jv_SO_RCVBUF_ :
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
        int opt;
        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
        if (::setsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, val_len) != 0)
	  goto error;    
#else
        throw new ::java::lang::InternalError (
          JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
#endif 
        return;
      case _Jv_SO_REUSEADDR_ :
#if defined(SO_REUSEADDR)
	if (::setsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
	    val_len) != 0)
	  goto error;
#else
        throw new ::java::lang::InternalError (
          JvNewStringUTF ("SO_REUSEADDR not supported"));
#endif 
	return;
      case _Jv_SO_BINDADDR_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_BINDADDR: read only option"));
        return;
      case _Jv_IP_MULTICAST_IF_ :
	union InAddr u;
        jbyteArray haddress;
	jbyte *bytes;
	int len;
	int level, opname;
	const char *ptr;

	haddress = ((::java::net::InetAddress *) value)->addr;
	bytes = elements (haddress);
	len = haddress->length;
	if (len == 4)
	  {
	    level = IPPROTO_IP;
	    opname = IP_MULTICAST_IF;
	    memcpy (&u.addr, bytes, len);
	    len = sizeof (struct in_addr);
	    ptr = (const char *) &u.addr;
	  }
// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF
#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF)
	else if (len == 16)
	  {
	    level = IPPROTO_IPV6;
	    opname = IPV6_MULTICAST_IF;
	    memcpy (&u.addr6, bytes, len);
	    len = sizeof (struct in6_addr);
	    ptr = (const char *) &u.addr6;
	  }
#endif
	else
	  throw
	    new ::java::net::SocketException (JvNewStringUTF ("invalid length"));

	if (::setsockopt (native_fd, level, opname, ptr, len) != 0)
	  goto error;
        return;
	
      case _Jv_IP_MULTICAST_IF2_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
        return;
	
      case _Jv_IP_MULTICAST_LOOP_ :
	// cache the local address
	if (localAddress == NULL)
	  localAddress = getLocalAddress (native_fd);
	len = localAddress->addr->length;
	if (len == 4)
	  {
	    level = IPPROTO_IP;
	    opname = IP_MULTICAST_LOOP;
	  }
#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP)
	else if (len == 16)
	  {
	    level = IPPROTO_IPV6;
	    opname = IPV6_MULTICAST_LOOP;
	  }
#endif
	else
	  throw
	    new ::java::net::SocketException (JvNewStringUTF ("invalid address length"));
	if (::setsockopt (native_fd, level, opname, (char *) &val,
			  val_len) != 0)
	  goto error;
	return;
	
      case _Jv_IP_TOS_ :
        if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
	   val_len) != 0)
	  goto error;    
	return;
	
      case _Jv_SO_TIMEOUT_ :
	timeout = val;
        return;
      default :
        errno = ENOPROTOOPT;
    }

 error:
  char* strerr = strerror (errno);
  throw new ::java::net::SocketException (JvNewStringUTF (strerr));
}

::java::lang::Object *
gnu::java::net::PlainDatagramSocketImpl::getOption (jint optID)
{
  int val;
  socklen_t val_len = sizeof(val);
  int level, opname;

  switch (optID)
    {
      case _Jv_TCP_NODELAY_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
        break;
      case _Jv_SO_LINGER_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_LINGER not valid for UDP"));
        break;    
      case _Jv_SO_KEEPALIVE_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
        break;
	
      case _Jv_SO_BROADCAST_ :
	if (::getsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
	    &val_len) != 0)
	  goto error;
	return new ::java::lang::Boolean (val != 0);
	
      case _Jv_SO_OOBINLINE_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_OOBINLINE not valid for UDP"));
        break;
      
      case _Jv_SO_RCVBUF_ :
      case _Jv_SO_SNDBUF_ :
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
        int opt;
        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
        if (::getsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, &val_len) != 0)
	  goto error;    
        else
	  return new ::java::lang::Integer (val);
#else
        throw new ::java::lang::InternalError (
          JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
#endif    
	break;
      case _Jv_SO_BINDADDR_:
	// cache the local address
	if (localAddress == NULL)
	  localAddress = getLocalAddress (native_fd);
	return localAddress;  
	break;
      case _Jv_SO_REUSEADDR_ :
#if defined(SO_REUSEADDR)
	if (::getsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
	    &val_len) != 0)
	  goto error;
	return new ::java::lang::Boolean (val != 0);
#else
        throw new ::java::lang::InternalError (
          JvNewStringUTF ("SO_REUSEADDR not supported"));
#endif 
	break;
      case _Jv_IP_MULTICAST_IF_ :
#ifdef HAVE_INET_NTOA
	struct in_addr inaddr;
  	socklen_t inaddr_len;
	char *bytes;

  	inaddr_len = sizeof(inaddr);
	if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr,
	    &inaddr_len) != 0)
	  goto error;

	bytes = inet_ntoa (inaddr);

	return ::java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));
#else
	throw new ::java::net::SocketException (
	  JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()"));
#endif
	break;
      case _Jv_SO_TIMEOUT_ :
	return new ::java::lang::Integer (timeout);
	break;
	
      case _Jv_IP_MULTICAST_IF2_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
        break;
	
      case _Jv_IP_MULTICAST_LOOP_ :
	// cache the local address
	localAddress = getLocalAddress (native_fd);
	if (localAddress->addr->length == 4) 
	  {
	    level = IPPROTO_IP;
	    opname = IP_MULTICAST_LOOP;
	  }
#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP)
	else if (localAddress->addr->length == 16)
	  {
	    level = IPPROTO_IPV6;
	    opname = IPV6_MULTICAST_LOOP;
	  }
#endif
	else
	  throw
	    new ::java::net::SocketException (JvNewStringUTF ("invalid address length"));
	if (::getsockopt (native_fd, level, opname, (char *) &val,
			  &val_len) != 0)
	  goto error;
	return new ::java::lang::Boolean (val != 0);
	
      case _Jv_IP_TOS_ :
        if (::getsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
           &val_len) != 0)
          goto error;
        return new ::java::lang::Integer (val);
	
      default :
	errno = ENOPROTOOPT;
    }

 error:
  char* strerr = strerror (errno);
  throw new ::java::net::SocketException (JvNewStringUTF (strerr));
}
