This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: NetworkInterfaces implementation


Hello list,


I have writtenn a little rough implementation of the class 
java.net.NetworkInterfaces. Its not yet ready, nor fully implemented.
I just post here for comments.

It needs a native method to retrieve the needed informations of the local 
interfaces, which is currently Linux 2.4 centric and not really useable. But 
perhaps we can build up on this.

I welcome all good comments. ;-)


Greetings,
Michael
// natNetworkInterface.cc

/* Copyright (C) 2002  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>

#ifdef WIN32

#include <windows.h>
#include <winsock.h>
#undef STRICT

#else /* WIN32 */

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#define BSD_COMP /* Get FIONREAD on Solaris2. */
#include <sys/ioctl.h>
#endif

// TODO: add configure check for this
#include <net/if.h>

#endif /* WIN32 */

#include <gcj/cni.h>
#include <jvm.h>
#include <java/net/NetworkInterface.h>
#include <java/net/Inet4Address.h>
#include <java/net/Inet6Address.h>
#include <java/util/Vector.h>

#ifdef DISABLE_JAVA_NET

::java::util::Vector*
java::net::NetworkInterface::getRealNetworkInterfaces ()
{
  ::java::util::Vector* ht = new ::java::util::Vector();
  return ht;
}

#else /* DISABLE_JAVA_NET */

::java::util::Vector*
java::net::NetworkInterface::getRealNetworkInterfaces ()
{
  int fd;
  int num_interfaces = 0;
  struct ifconf if_data;
  struct ifreq* if_record; 
  ::java::util::Vector* ht = new ::java::util::Vector();

  // open socket
  fd = ::socket(PF_INET, SOCK_DGRAM, htons(IPPROTO_IP));
  if (fd >= 0)
  {
    if_data.ifc_len = 0;
    if_data.ifc_buf = NULL;

    // get all interfaces
    // if not enough buffers are available try it with a bigger buffer size
    do
    {
      num_interfaces += 16;

      if_data.ifc_len = sizeof(struct ifreq) * num_interfaces;
      if_data.ifc_buf = (char*) realloc(if_data.ifc_buf, if_data.ifc_len);

      if (::ioctl(fd, SIOCGIFCONF, &if_data) < 0)
        goto out;
    }
    while (if_data.ifc_len >= (sizeof(struct ifreq) * num_interfaces));

    // get addresses of all interfaces
    if_record = if_data.ifc_req;
    for( int n = 0; n < if_data.ifc_len; n += sizeof(struct ifreq) )
    {
      struct ifreq ifr;

      memset(&ifr, 0, sizeof(ifr));
      strcpy(ifr.ifr_name, if_record->ifr_name);

      if (::ioctl(fd, SIOCGIFADDR, &ifr) >= 0)
      {
	int len = 4;
        struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
	
        jbyteArray baddr = JvNewByteArray (len);
	memcpy (elements (baddr), &(sa.sin_addr), len);
	jstring if_name = JvNewStringLatin1(if_record->ifr_name);
        InetAddress* address = new java::net::InetAddress(
                                            baddr, JvNewStringLatin1(""));
        ht->add (new NetworkInterface(if_name, address));
      }

      if_record++;
    }

    ::close (fd);
  }

out:
  return ht;
}

#endif // DISABLE_JAVA_NET //
// NetworkInterface.java -- An Internet Protocol (IP) address.

/* Copyright (C) 2002  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.  */

package java.net;

import java.util.Enumeration;
import java.util.Vector;
//import gnu.java.util.EmptyEnumeration;

/**
 * @author Michael Koch <konqueror@gmx.de>
 * @since 1.4
 */
public final class NetworkInterface extends Object
{
  private static Vector networkInterfaces;
	
  private String name;
  private Vector inetAddresses;

  private NetworkInterface(String name, InetAddress address)
  {
    this.name = name;
    this.inetAddresses = new Vector(1, 1);
    this.inetAddresses.add (address);
  }

  private native static Vector getRealNetworkInterfaces();

  public String getName()
  {
    return name;
  }

  public Enumeration getInetAddresses()
  {
    SecurityManager s = System.getSecurityManager();
    if (s != null)
    {
      // TODO: implement the usage of security manager
    }

    return inetAddresses.elements();
  }

  public String getDisplayName()
  {
    return name;
  }

  public static NetworkInterface getByName(String name) throws SocketException
  {
    if (networkInterfaces == null)
      networkInterfaces = getRealNetworkInterfaces();

    for (Enumeration e = networkInterfaces.elements(); e.hasMoreElements(); )
    {
      NetworkInterface tmp = (NetworkInterface) e.nextElement();
      
      if (tmp.getName() == name)
        return tmp;
    }

    throw new SocketException("no network interface with this name exists");
  }

  public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException
  {
    if (networkInterfaces == null)
      networkInterfaces = getRealNetworkInterfaces();
    
    for (Enumeration interfaces = networkInterfaces.elements(); interfaces.hasMoreElements();)
    {
      NetworkInterface tmp = (NetworkInterface) interfaces.nextElement();
      
      for (Enumeration addresses = tmp.inetAddresses.elements(); addresses.hasMoreElements();)
      {
        if (addr.equals((InetAddress) addresses.nextElement()))
          return tmp;
      }
    }

    throw new SocketException("no network intefaces is bound to such an IP address");
  }

  public static Enumeration getNetworkInterfaces() throws SocketException
  {
    if (networkInterfaces == null)
      networkInterfaces = getRealNetworkInterfaces();
    
    return networkInterfaces.elements();
  }

  public boolean equals(Object obj)
  {
    if (!(obj instanceof NetworkInterface))
      return false;
   
    NetworkInterface tmp = (NetworkInterface) obj;
    return name.equals(tmp.name) && inetAddresses.equals(tmp.inetAddresses);
  }

  public int hashCode()
  {
    // TODO: hash correctly
    return name.hashCode() + inetAddresses.hashCode();
  }

  public String toString()
  {
    // TODO: check if this is correct
    String result;

    result = "name: " + getDisplayName() + " (" + getName() + ") addresses:\n";
    for (Enumeration e = inetAddresses.elements(); e.hasMoreElements(); )
    {
      InetAddress address = (InetAddress) e.nextElement();
      result += "/" + address.toString() + "\n";
    }
    return result;
  }
} // class NetworkInterface

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]