This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
RFC: NetworkInterfaces implementation
- From: Michael Koch <konqueror at gmx dot de>
- To: java at gcc dot gnu dot org
- Date: Thu, 15 Aug 2002 23:03:34 +0200
- Subject: 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