Here's a revised patch that uses getifaddrs. Works on Darwin with jamvm,
I have not yet tested Linux.

This still contains the same fix for jcl.c. I'll try to come up with a
better solution that fixes the issue, but for now, if you want to try it
on JamVM, you'll need this fix.


? native/jni/java-net/netif.c
? native/jni/java-net/netif.h
Index: configure.ac
===================================================================
RCS file: /cvsroot/classpath/classpath/configure.ac,v
retrieving revision 1.181
diff -u -r1.181 configure.ac
--- configure.ac        31 Aug 2006 19:56:03 -0000      1.181
+++ configure.ac        9 Sep 2006 19:01:13 -0000
@@ -373,12 +373,19 @@
                   fcntl \
                  mmap munmap mincore msync madvise getpagesize sysconf \
                  lstat readlink \
-                 ])
+                 getifaddrs])
 
   LIBMAGIC=
   AC_CHECK_LIB(magic, magic_open, LIBMAGIC=-lmagic)
   AC_SUBST(LIBMAGIC)
 
+  AC_MSG_CHECKING([whether struct sockaddr_in6 is in netinet/in.h])
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <netinet/in.h>]], [[struct 
sockaddr_in6 addr6;]])],
+                    [AC_DEFINE(HAVE_INET6, 1,
+                     [Define if inet6 structures are defined in netinet/in.h.])
+                     AC_MSG_RESULT(yes)],
+                    [AC_MSG_RESULT(no)])
+
   AC_HEADER_TIME
   AC_STRUCT_TM
   AC_STRUCT_TIMEZONE
Index: include/java_net_VMNetworkInterface.h
===================================================================
RCS file: /cvsroot/classpath/classpath/include/java_net_VMNetworkInterface.h,v
retrieving revision 1.1
diff -u -r1.1 java_net_VMNetworkInterface.h
--- include/java_net_VMNetworkInterface.h       11 Apr 2005 18:58:38 -0000      
1.1
+++ include/java_net_VMNetworkInterface.h       9 Sep 2006 19:01:13 -0000
@@ -1,19 +1,29 @@
 /* DO NOT EDIT THIS FILE - it is machine generated */
-
-#ifndef __java_net_VMNetworkInterface__
-#define __java_net_VMNetworkInterface__
-
 #include <jni.h>
+/* Header for class java_net_VMNetworkInterface */
 
+#ifndef _Included_java_net_VMNetworkInterface
+#define _Included_java_net_VMNetworkInterface
 #ifdef __cplusplus
-extern "C"
-{
+extern "C" {
 #endif
-
-JNIEXPORT jobject JNICALL Java_java_net_VMNetworkInterface_getInterfaces 
(JNIEnv *env, jclass);
+/*
+ * Class:     java_net_VMNetworkInterface
+ * Method:    initIds
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_VMNetworkInterface_initIds
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_net_VMNetworkInterface
+ * Method:    getVMInterfaces
+ * Signature: ()[Ljava/net/VMNetworkInterface;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_net_VMNetworkInterface_getVMInterfaces
+  (JNIEnv *, jclass);
 
 #ifdef __cplusplus
 }
 #endif
-
-#endif /* __java_net_VMNetworkInterface__ */
+#endif
Index: java/net/NetworkInterface.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/net/NetworkInterface.java,v
retrieving revision 1.18
diff -u -r1.18 NetworkInterface.java
--- java/net/NetworkInterface.java      29 Aug 2006 08:25:15 -0000      1.18
+++ java/net/NetworkInterface.java      9 Sep 2006 19:01:14 -0000
@@ -38,6 +38,8 @@
 
 package java.net;
 
+import gnu.classpath.SystemProperties;
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -58,25 +60,13 @@
  */
 public final class NetworkInterface
 {
-  private String name;
-  private Vector inetAddresses;
-
-  NetworkInterface(String name, InetAddress address)
-  {
-    this.name = name;
-    this.inetAddresses = new Vector(1, 1);
-    this.inetAddresses.add(address);
-  }
+  private final VMNetworkInterface netif;
 
-  NetworkInterface(String name, InetAddress[] addresses)
+  private NetworkInterface(VMNetworkInterface netif)
   {
-    this.name = name;
-    this.inetAddresses = new Vector(addresses.length, 1);
-
-    for (int i = 0; i < addresses.length; i++)
-      this.inetAddresses.add(addresses[i]);
+    this.netif = netif;
   }
-
+  
   /**
    * Returns the name of the network interface
    *
@@ -84,7 +74,7 @@
    */
   public String getName()
   {
-    return name;
+    return netif.name;
   }
 
   /**
@@ -100,6 +90,7 @@
   public Enumeration getInetAddresses()
   {
     SecurityManager s = System.getSecurityManager();
+    Vector inetAddresses = new Vector(netif.addresses);
 
     if (s == null)
       return inetAddresses.elements();
@@ -131,7 +122,7 @@
    */
   public String getDisplayName()
   {
-    return name;
+    return netif.name;
   }
 
   /**
@@ -148,15 +139,14 @@
   public static NetworkInterface getByName(String name)
     throws SocketException
   {
-    for (Enumeration e = getNetworkInterfaces(); e.hasMoreElements();)
+    if (name == null)
+      throw new NullPointerException();
+    VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces();
+    for (int i = 0; i < netifs.length; i++)
       {
-       NetworkInterface tmp = (NetworkInterface) e.nextElement();
-
-       if (name.equals(tmp.getName()))
-         return tmp;
+        if (netifs[i].name.equals(name))
+          return new NetworkInterface(netifs[i]);
       }
-
-    // No interface with the given name found.
     return null;
   }
 
@@ -173,55 +163,15 @@
   public static NetworkInterface getByInetAddress(InetAddress addr)
     throws SocketException
   {
-    for (Enumeration interfaces = getNetworkInterfaces();
-         interfaces.hasMoreElements();)
+    if (addr == null)
+      throw new NullPointerException();
+    VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces();
+    for (int i = 0; i < netifs.length; i++)
       {
-       NetworkInterface tmp = (NetworkInterface) interfaces.nextElement();
-
-       for (Enumeration addresses = tmp.inetAddresses.elements();
-            addresses.hasMoreElements();)
-         {
-           if (addr.equals((InetAddress) addresses.nextElement()))
-             return tmp;
-         }
+        if (netifs[i].addresses.contains(addr))
+          return new NetworkInterface(netifs[i]);
       }
-
-    throw new SocketException("no network interface is bound to such an IP 
address");
-  }
-
-  static private Collection condense(Collection interfaces) 
-  {
-    final Map condensed = new HashMap();
-
-    final Iterator interfs = interfaces.iterator();
-    while (interfs.hasNext()) {
-
-      final NetworkInterface face = (NetworkInterface) interfs.next();
-      final String name = face.getName();
-      
-      if (condensed.containsKey(name))
-       {
-         final NetworkInterface conface = (NetworkInterface) 
condensed.get(name);
-         if (!conface.inetAddresses.containsAll(face.inetAddresses))
-           {
-             final Iterator faceAddresses = face.inetAddresses.iterator();
-             while (faceAddresses.hasNext())
-               {
-                 final InetAddress faceAddress = (InetAddress) 
faceAddresses.next();
-                 if (!conface.inetAddresses.contains(faceAddress))
-                   {
-                     conface.inetAddresses.add(faceAddress);
-                   }
-               }
-           }
-       }
-      else
-       {
-         condensed.put(name, face);
-       }
-    }
-
-    return condensed.values();
+    return null;
   }
 
   /**
@@ -233,14 +183,14 @@
    */
   public static Enumeration getNetworkInterfaces() throws SocketException
   {
-    Vector networkInterfaces = VMNetworkInterface.getInterfaces();
-
-    if (networkInterfaces.isEmpty())
-      return null;
-
-    Collection condensed = condense(networkInterfaces);
-
-    return Collections.enumeration(condensed);
+    VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces();
+    Vector networkInterfaces = new Vector(netifs.length);
+    for (int i = 0; i < netifs.length; i++)
+      {
+        if (!netifs[i].addresses.isEmpty())
+          networkInterfaces.add(new NetworkInterface(netifs[i]));
+      }
+    return networkInterfaces.elements();
   }
 
   /**
@@ -257,7 +207,8 @@
 
     NetworkInterface tmp = (NetworkInterface) obj;
 
-    return (name.equals(tmp.name) && inetAddresses.equals(tmp.inetAddresses));
+    return (netif.name.equals(tmp.netif.name)
+            && (netif.addresses.equals(tmp.netif.addresses)));
   }
 
   /**
@@ -268,7 +219,7 @@
   public int hashCode()
   {
     // FIXME: hash correctly
-    return name.hashCode() + inetAddresses.hashCode();
+    return netif.name.hashCode() + netif.addresses.hashCode();
   }
 
   /**
@@ -279,19 +230,22 @@
   public String toString()
   {
     // FIXME: check if this is correct
-    String result;
-    String separator = System.getProperty("line.separator");
+    StringBuffer result;
+    String separator = SystemProperties.getProperty("line.separator");
 
-    result =
-      "name: " + getDisplayName() + " (" + getName() + ") addresses:"
-      + separator;
+    result = new StringBuffer();
+    
+    result.append("name: ");
+    result.append(getDisplayName());
+    result.append(" (").append(getName()).append(") addresses:");
+    result.append(separator);
 
-    for (Enumeration e = inetAddresses.elements(); e.hasMoreElements();)
+    for (Iterator it = netif.addresses.iterator(); it.hasNext(); )
       {
-       InetAddress address = (InetAddress) e.nextElement();
-       result += address.toString() + ";" + separator;
+       InetAddress address = (InetAddress) it.next();
+       result.append(address.toString()).append(";").append(separator);
       }
 
-    return result;
+    return result.toString();
   }
 }
Index: vm/reference/java/net/VMNetworkInterface.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/vm/reference/java/net/VMNetworkInterface.java,v
retrieving revision 1.4
diff -u -r1.4 VMNetworkInterface.java
--- vm/reference/java/net/VMNetworkInterface.java       2 Mar 2006 00:36:44 
-0000       1.4
+++ vm/reference/java/net/VMNetworkInterface.java       9 Sep 2006 19:01:14 
-0000
@@ -40,6 +40,9 @@
 
 import gnu.classpath.Configuration;
 
+import java.nio.ByteBuffer;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.Vector;
 
 /**
@@ -54,22 +57,50 @@
  */
 final class VMNetworkInterface
 {
+  String name;
+  Set addresses;
+
+  VMNetworkInterface(String name)
+  {
+    this.name = name;
+    addresses = new HashSet();
+  }
+  
   static
-    {
-      if (Configuration.INIT_LOAD_LIBRARY)
-       System.loadLibrary("javanet");
-    }
+  {
+    if (Configuration.INIT_LOAD_LIBRARY)
+      System.loadLibrary("javanet");
+    
+    initIds();
+  }
+  
+  private static native void initIds();
 
   /**
-   * Returns a Vector of InetAddresses. The returned value will be
-   * 'condensed', meaning that all elements with the same interface
-   * name will be collapesed into one InetAddress for that name
-   * containing all addresses before the returning the result to the
-   * user. This means the native method can be implemented in a naive
-   * way mapping each address/interface to a name even if that means
-   * that the Vector contains multiple InetAddresses with the same
-   * interface name.
+   * Return a list of VM network interface objects.
+   *
+   * @return The list of network interfaces.
+   * @throws SocketException
    */
-  public static native Vector getInterfaces()
+  public static native VMNetworkInterface[] getVMInterfaces()
     throws SocketException;
+  
+  private void addAddress(ByteBuffer addr)
+    throws SocketException, UnknownHostException
+  {
+    if (addr.remaining() == 4)
+      {
+        byte[] ipv4 = new byte[4];
+        addr.get(ipv4);
+        addresses.add(Inet4Address.getByAddress(ipv4));
+      }
+    else if (addr.remaining() == 16)
+      {
+        byte[] ipv6 = new byte[16];
+        addr.get(ipv6);
+        addresses.add(Inet6Address.getByAddress(ipv6));
+      }
+    else
+      throw new SocketException("invalid interface address");
+  }
 }
Index: native/jni/classpath/jcl.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/classpath/jcl.c,v
retrieving revision 1.23
diff -u -r1.23 jcl.c
--- native/jni/classpath/jcl.c  3 Apr 2006 14:03:12 -0000       1.23
+++ native/jni/classpath/jcl.c  9 Sep 2006 19:01:14 -0000
@@ -186,90 +186,113 @@
  * Build a Pointer object. The function caches the class type 
  */
 
-static jclass rawDataClass;
-static jfieldID rawData_fid;
-static jmethodID rawData_mid;
+/* Note, caching these values doesn't work. On jamvm, for example,
+   this fails if you use the JNI call NewDirectBuffer, because it
+   doesn't use JCL_NewRawDataObject, and thus these ID classes may not
+   have been filled in. This code is also not thread-safe. */
+
+/* static jclass rawDataClass; */
+/* static jfieldID rawData_fid; */
+/* static jmethodID rawData_mid; */
 
 JNIEXPORT jobject JNICALL
 JCL_NewRawDataObject (JNIEnv * env, void *data)
 {
+  jclass rawDataClass;
+  jmethodID rawData_mid;
+  jobject ret;
+
+#if SIZEOF_VOID_P == 8
+  rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer64");
   if (rawDataClass == NULL)
     {
-      jclass tmp;
-#if SIZEOF_VOID_P == 8
-      rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer64");
-      if (rawDataClass == NULL)
-       {
-         JCL_ThrowException (env, "java/lang/InternalError",
-                             "unable to find internal class");
-         return NULL;
-       }
-
-      rawData_mid = (*env)->GetMethodID (env, rawDataClass, "<init>", "(J)V");
-      if (rawData_mid == NULL)
-       {
-         JCL_ThrowException (env, "java/lang/InternalError",
-                             "unable to find internal constructor");
-         return NULL;
-       }
-
-      rawData_fid = (*env)->GetFieldID (env, rawDataClass, "data", "J");
-      if (rawData_fid == NULL)
-       {
-         JCL_ThrowException (env, "java/lang/InternalError",
-                             "unable to find internal field");
-         return NULL;
-       }
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal class");
+      return NULL;
+    }
+
+  rawData_mid = (*env)->GetMethodID (env, rawDataClass, "<init>", "(J)V");
+  if (rawData_mid == NULL)
+    {
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal constructor");
+      return NULL;
+    }
 #else
-      rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer32");
-      if (rawDataClass == NULL)
-       {
-         JCL_ThrowException (env, "java/lang/InternalError",
-                             "unable to find internal class");
-         return NULL;
-       }
-
-      rawData_mid = (*env)->GetMethodID (env, rawDataClass, "<init>", "(I)V");
-      if (rawData_mid == NULL)
-       {
-         JCL_ThrowException (env, "java/lang/InternalError",
-                             "unable to find internal constructor");
-         return NULL;
-       }
-
-      rawData_fid = (*env)->GetFieldID (env, rawDataClass, "data", "I");
-      if (rawData_fid == NULL)
-       {
-         JCL_ThrowException (env, "java/lang/InternalError",
-                             "unable to find internal field");
-         return NULL;
-       }
+  rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer32");
+  if (rawDataClass == NULL)
+    {
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal class");
+      return NULL;
+    }
 
-#endif
-      tmp = (*env)->NewGlobalRef (env, rawDataClass);
-      if (tmp == NULL)
-       {
-         JCL_ThrowException (env, "java/lang/InternalError",
-                             "unable to create an internal global ref");
-         return NULL;
-       }
-      (*env)->DeleteLocalRef(env, rawDataClass);
-      rawDataClass = tmp;
+  rawData_mid = (*env)->GetMethodID (env, rawDataClass, "<init>", "(I)V");
+  if (rawData_mid == NULL)
+    {
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal constructor");
+      return NULL;
     }
+#endif
 
 #if SIZEOF_VOID_P == 8
-  return (*env)->NewObject (env, rawDataClass, rawData_mid, (jlong) data);
+  ret = (*env)->NewObject (env, rawDataClass, rawData_mid, (jlong) data);
 #else
-  return (*env)->NewObject (env, rawDataClass, rawData_mid, (jint) data);
+  ret = (*env)->NewObject (env, rawDataClass, rawData_mid, (jint) data);
 #endif
+
+  (*env)->DeleteLocalRef (env, rawDataClass);
+  return ret;
 }
 
 JNIEXPORT void * JNICALL
 JCL_GetRawData (JNIEnv * env, jobject rawdata)
 {
+  jclass rawDataClass;
+  jfieldID rawData_fid;
+  jobject ret;
+
 #if SIZEOF_VOID_P == 8
-  return (void *) (*env)->GetLongField (env, rawdata, rawData_fid);
+  rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer64");
+  if (rawDataClass == NULL)
+    {
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal class");
+      return NULL;
+    }
+
+  rawData_fid = (*env)->GetFieldID (env, rawDataClass, "data", "J");
+  if (rawData_fid == NULL)
+    {
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal field");
+      return NULL;
+    }
+#else
+  rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer32");
+  if (rawDataClass == NULL)
+    {
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal class");
+      return NULL;
+    }
+
+  rawData_fid = (*env)->GetFieldID (env, rawDataClass, "data", "I");
+  if (rawData_fid == NULL)
+    {
+      JCL_ThrowException (env, "java/lang/InternalError",
+                          "unable to find internal field");
+      return NULL;
+    }
+#endif
+
+#if SIZEOF_VOID_P == 8
+  ret = (void *) (*env)->GetLongField (env, rawdata, rawData_fid);
 #else
-  return (void *) (*env)->GetIntField (env, rawdata, rawData_fid);
-#endif  
+  ret = (void *) (*env)->GetIntField (env, rawdata, rawData_fid);
+#endif
+
+  (*env)->DeleteLocalRef (env, rawDataClass);
+  return ret;
 }
Index: native/jni/java-net/java_net_VMNetworkInterface.c
===================================================================
RCS file: 
/cvsroot/classpath/classpath/native/jni/java-net/java_net_VMNetworkInterface.c,v
retrieving revision 1.3
diff -u -r1.3 java_net_VMNetworkInterface.c
--- native/jni/java-net/java_net_VMNetworkInterface.c   12 Jan 2006 09:37:31 
-0000      1.3
+++ native/jni/java-net/java_net_VMNetworkInterface.c   9 Sep 2006 19:01:14 
-0000
@@ -35,9 +35,15 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-/* do not move; needed here because of some macro definitions */
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif /* HAVE_CONFIG_H */
 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+#include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -47,19 +53,197 @@
 
 #include "java_net_VMNetworkInterface.h"
 
-#include "javanet.h"
+
+static jmethodID java_net_VMNetworkInterface_init;
+static jmethodID java_net_VMNetworkInterface_addAddress;
+
+/*
+ * Initialize our static method ID's.
+ *
+ * Class:     java_net_VMNetworkInterface
+ * Method:    initIds
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_VMNetworkInterface_initIds (JNIEnv *env, jclass clazz)
+{
+  java_net_VMNetworkInterface_init =
+    (*env)->GetMethodID (env, clazz, "<init>", "(Ljava/lang/String;)V");
+  if (java_net_VMNetworkInterface_init == NULL)
+    {
+      if (!(*env)->ExceptionCheck (env))
+        JCL_ThrowException (env, "java/lang/NoSuchMethodError",
+                            "VMNetworkinterface.addAddress");
+      return;
+    }
+  java_net_VMNetworkInterface_addAddress =
+    (*env)->GetMethodID (env, clazz, "addAddress", "(Ljava/nio/ByteBuffer;)V");
+  if (java_net_VMNetworkInterface_addAddress == NULL)
+    {
+      if (!(*env)->ExceptionCheck (env))
+        JCL_ThrowException (env, "java/lang/NoSuchMethodError",
+                            "VMNetworkinterface.addAddress");
+    }
+}
+
+struct netif_entry
+{
+  char *name;
+  jobject netif;
+  int numaddrs;
+  struct netif_entry *next;
+};
+
+static void
+free_netif_list (JNIEnv *env, struct netif_entry *list)
+{
+  while (list != NULL)
+    {
+      struct netif_entry *e = list->next;
+      JCL_free (env, list);
+      list = e;
+    }
+}
 
 /*
- * Returns all local network interfaces as vector
+ * Returns all local network interfaces as an array.
  */
-JNIEXPORT jobject JNICALL
-Java_java_net_VMNetworkInterface_getInterfaces (JNIEnv * env,
-                                               jclass class
-                                               __attribute__ ((__unused__)))
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_VMNetworkInterface_getVMInterfaces (JNIEnv * env, jclass clazz)
 {
-  JCL_ThrowException (env, IO_EXCEPTION,
-                     "java.net.VMNetworkInterface.getInterfaces(): not 
implemented");
-  return 0;
+#ifdef HAVE_GETIFADDRS
+  struct ifaddrs *ifaddrs, *i;
+  struct netif_entry *iflist = NULL, *e;
+  jobjectArray netifs;
+  int numifs = 0;
+  int k;
+
+  if (getifaddrs (&ifaddrs) == -1)
+    {
+      JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
+      return NULL;
+    }
+
+  for (i = ifaddrs; i != NULL; i = i->ifa_next)
+    {
+      if (iflist == NULL)
+        {
+          iflist = JCL_malloc (env, sizeof (struct netif_entry));
+          if (iflist == NULL)
+            {
+              freeifaddrs (ifaddrs);
+              return NULL;
+            }
+          iflist->name = i->ifa_name;
+          iflist->numaddrs = 0;
+          iflist->next = NULL;
+          iflist->netif = (*env)->NewObject (env, clazz, 
java_net_VMNetworkInterface_init,
+                                             (*env)->NewStringUTF (env, 
i->ifa_name));
+          if (iflist->netif == NULL)
+            {
+              freeifaddrs (ifaddrs);
+              JCL_free (env, iflist);
+              return NULL;
+            }
+          e = iflist;
+        }
+      else
+        {
+          struct netif_entry *p = NULL;
+          for (e = iflist; e != NULL; e = e->next)
+            {
+              if (strcmp (e->name, i->ifa_name) == 0)
+                break;
+              p = e;
+            }
+
+          if (e == NULL)
+            {
+              p->next = (struct netif_entry *) JCL_malloc (env, sizeof (struct 
netif_entry));
+              if (p->next == NULL)
+                {
+                  free_netif_list (env, iflist);
+                  freeifaddrs (ifaddrs);
+                  return NULL;
+                }
+              e = p->next;
+              e->name = i->ifa_name;
+              e->numaddrs = 0;
+              e->next = NULL;
+              e->netif = (*env)->NewObject (env, clazz, 
java_net_VMNetworkInterface_init,
+                                            (*env)->NewStringUTF (env, 
i->ifa_name));
+              if (e->netif == NULL)
+                {
+                  free_netif_list (env, iflist);
+                  freeifaddrs (ifaddrs);
+                  return NULL;
+                }
+            }
+        }
+
+      if (i->ifa_addr == NULL)
+        continue;
+
+      if (i->ifa_addr->sa_family == AF_INET)
+        {
+          struct sockaddr_in *sin = (struct sockaddr_in *) i->ifa_addr;
+          jobject buffer = (*env)->NewDirectByteBuffer (env, 
&(sin->sin_addr.s_addr), 4);
+          (*env)->CallVoidMethod (env, e->netif, 
java_net_VMNetworkInterface_addAddress,
+                                  buffer);
+          if ((*env)->ExceptionCheck (env))
+            {
+              free_netif_list (env, iflist);
+              freeifaddrs (ifaddrs);
+              return NULL;
+            }
+          (*env)->DeleteLocalRef (env, buffer);
+          e->numaddrs++;
+        }
+#ifdef HAVE_INET6
+      else if (i->ifa_addr->sa_family == AF_INET6)
+        {
+          struct sockaddr_in6 *sin = (struct sockaddr_in6 *) i->ifa_addr;
+          jobject buffer = (*env)->NewDirectByteBuffer (env, 
&(sin->sin6_addr.s6_addr), 16);
+          (*env)->CallVoidMethod (env, e->netif, 
java_net_VMNetworkInterface_addAddress,
+                                  buffer);
+          if ((*env)->ExceptionCheck (env))
+            {
+              free_netif_list (env, iflist);
+              freeifaddrs (ifaddrs);
+              return NULL;
+            }
+          (*env)->DeleteLocalRef (env, buffer);
+          e->numaddrs++;
+        }
+#endif /* HAVE_INET6 */
+    }
+
+  /* Count how many interfaces we have that have addresses. */
+  for (e = iflist; e != NULL; e = e->next)
+    {
+      if (e->numaddrs != 0)
+        numifs++;
+    }
+
+  netifs = (*env)->NewObjectArray (env, numifs, clazz, NULL);
+  k = 0;
+  for (e = iflist; e != NULL && k < numifs; e = e->next)
+    {
+      if (e->numaddrs != 0)
+        {
+          (*env)->SetObjectArrayElement (env, netifs, k, e->netif);
+          (*env)->DeleteLocalRef (env, e->netif);
+          k++;
+        }
+    }
+
+  free_netif_list (env, iflist);
+  freeifaddrs (ifaddrs);
+  return netifs;
+#else
+  JCL_ThrowException (env, "java/net/SocketException", "getifaddrs not 
supported");
+  return NULL;
+#endif /* HAVE_GETIFADDRS */
 }
 
 /* end of file */

Reply via email to