Switch NetworkInterface to one getifaddrs call.

Based on yikong@ changeset 70da41603ee0dc5ab547c778003b3ed03ce3e6a1

Refactored the enumInterfaces to enumerate all network interfaces
using getigaddrs, and gather their associated network addresses and
their hw address.

The OpenJDK implementation is incorrect since it does not return all
the interfaces on the machine, rather only interfaces with either IPv4
or IPv6 addresses associated with them. This fix restores the libcore
behaviour.

Removed solaris, BSD and non-IPv6 related code.

Bug: 26238832
Change-Id: I4bb0a7be99ccdcb2aa0f1b90bc854f8be60776ab
diff --git a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
index ef3a228..73cb7ac 100644
--- a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
+++ b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
@@ -31,6 +31,9 @@
 import java.util.Set;
 import libcore.io.IoUtils;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 public class NetworkInterfaceTest extends TestCase {
     // http://code.google.com/p/android/issues/detail?id=13784
     private final static int ARPHRD_ETHER = 1; // from if_arp.h
@@ -143,13 +146,9 @@
         }
     }
 
-    // Returns true if interface by name ifName is Ethernet
-    private boolean isEthernet(String ifName) throws Exception {
-        String s = IoUtils.readFileAsString("/sys/class/net/" + ifName + "/type").trim();
-        if (s.startsWith("0x")) {
-            return (Integer.parseInt(s.substring(2), 16) == ARPHRD_ETHER);
-        } else {
-            return (Integer.parseInt(s) == ARPHRD_ETHER);
-        }
+    // Is ifName a name of a Ethernet device?
+    private static Pattern ethernetNamePattern = Pattern.compile("^(eth|wlan)[0-9]+$");
+    private static boolean isEthernet(String ifName) throws Exception {
+        return ethernetNamePattern.matcher(ifName).matches();
     }
 }
diff --git a/ojluni/src/main/java/java/net/NetworkInterface.java b/ojluni/src/main/java/java/net/NetworkInterface.java
index b641b5c..1f5825f 100755
--- a/ojluni/src/main/java/java/net/NetworkInterface.java
+++ b/ojluni/src/main/java/java/net/NetworkInterface.java
@@ -49,6 +49,7 @@
     private NetworkInterface childs[];
     private NetworkInterface parent = null;
     private boolean virtual = false;
+    private byte[] hardwareAddr;
     private static final NetworkInterface defaultInterface;
     private static final int defaultIndex; /* index of defaultInterface */
 
@@ -431,23 +432,7 @@
      * @since 1.6
      */
     public byte[] getHardwareAddress() throws SocketException {
-        SecurityManager sec = System.getSecurityManager();
-        if (sec != null) {
-            try {
-                sec.checkPermission(new NetPermission("getNetworkInformation"));
-            } catch (SecurityException e) {
-                if (!getInetAddresses().hasMoreElements()) {
-                    // don't have connect permission to any local address
-                    return null;
-                }
-            }
-        }
-        for (InetAddress addr : addrs) {
-            if (addr instanceof Inet4Address) {
-                return getMacAddr0(((Inet4Address)addr).getAddress(), name, index);
-            }
-        }
-        return getMacAddr0(null, name, index);
+        return (hardwareAddr != null) ? hardwareAddr.clone() : null;
     }
 
     /**
@@ -482,7 +467,6 @@
     private native static boolean isLoopback0(String name, int ind) throws SocketException;
     private native static boolean supportsMulticast0(String name, int ind) throws SocketException;
     private native static boolean isP2P0(String name, int ind) throws SocketException;
-    private native static byte[] getMacAddr0(byte[] inAddr, String name, int ind) throws SocketException;
     private native static int getMTU0(String name, int ind) throws SocketException;
 
     /**
diff --git a/ojluni/src/main/native/NetworkInterface.c b/ojluni/src/main/native/NetworkInterface.c
index 83ab1b8..0c98458 100755
--- a/ojluni/src/main/native/NetworkInterface.c
+++ b/ojluni/src/main/native/NetworkInterface.c
@@ -37,37 +37,13 @@
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <net/if_arp.h>
+#include <linux/if_packet.h>
 
-#ifdef __solaris__
-#include <sys/dlpi.h>
-#include <fcntl.h>
-#include <stropts.h>
-#include <sys/sockio.h>
-#endif
-
-#ifdef __linux__
 #include <sys/ioctl.h>
 //#include <bits/ioctls.h>
 #include <sys/utsname.h>
 #include <stdio.h>
-#endif
-
-#ifdef __linux__
-#define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
-#endif
-
-#if defined(_ALLBSD_SOURCE)
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/sockio.h>
-#if defined(__APPLE__)
-#include <net/ethernet.h>
-#include <net/if_var.h>
-#include <net/if_dl.h>
-#include <netinet/in_var.h>
 #include <ifaddrs.h>
-#endif
-#endif
 
 #include "jvm.h"
 #include "jni_util.h"
@@ -89,6 +65,9 @@
     char *name;
     int index;
     char virtual;
+
+    uint8_t hwAddrLen;
+    uint8_t *hwAddr;
     netaddr *addr;
     struct _netif *childs;
     struct _netif *next;
@@ -112,6 +91,7 @@
 jfieldID ni_childsID;
 jfieldID ni_parentID;
 jfieldID ni_defaultIndexID;
+jfieldID ni_hardwareAddrID;
 jmethodID ni_ctrID;
 
 static jclass ni_iacls;
@@ -131,39 +111,18 @@
 static int     getFlags0(JNIEnv *env, jstring  ifname);
 
 static netif  *enumInterfaces(JNIEnv *env);
-static netif  *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs);
 
-#ifdef AF_INET6
-static netif  *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
-#endif
-
-static netif  *addif(JNIEnv *env, int sock, const char * if_name, netif *ifs, struct sockaddr* ifr_addrP, int family, short prefix);
+static netif  *addif(JNIEnv *env, int sock, struct ifaddrs *ifa, netif *ifs);
 static void    freeif(netif *ifs);
 
 static int     openSocket(JNIEnv *env, int proto);
 static int     openSocketWithFallback(JNIEnv *env, const char *ifname);
 
-
-static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, struct sockaddr *brdcast_store);
-static short   getSubnet(JNIEnv *env, int sock, const char *ifname);
 static int     getIndex(int sock, const char *ifname);
 
 static int     getFlags(int sock, const char *ifname, int *flags);
-static int     getMacAddress(JNIEnv *env, int sock,  const char* ifname, const struct in_addr* addr, unsigned char *buf);
 static int     getMTU(JNIEnv *env, int sock, const char *ifname);
 
-
-
-#ifdef __solaris__
-static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family);
-static int    getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf);
-
-#ifndef SIOCGLIFHWADDR
-#define SIOCGLIFHWADDR  _IOWR('i', 192, struct lifreq)
-#endif
-
-#endif
-
 /******************* Java entry points *****************************/
 
 /*
@@ -183,6 +142,7 @@
     ni_virutalID = (*env)->GetFieldID(env, ni_class, "virtual", "Z");
     ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
     ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", "Ljava/net/NetworkInterface;");
+    ni_hardwareAddrID = (*env)->GetFieldID(env, ni_class, "hardwareAddr", "[B");
     ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
 
     ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
@@ -298,11 +258,7 @@
 
     netif *ifs, *curr;
 
-#ifdef AF_INET6
     int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6;
-#else
-    int family =  AF_INET;
-#endif
 
     jobject obj = NULL;
     jboolean match = JNI_FALSE;
@@ -332,7 +288,6 @@
                     }
                 }
 
-#ifdef AF_INET6
                 if (family == AF_INET6) {
                     jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr);
                     jbyteArray ipaddress = (*env)->GetObjectField(env, iaObj, ni_ia6ipaddressID);
@@ -352,8 +307,6 @@
                         break;
                     }
                 }
-#endif
-
             }
 
             if (match) {
@@ -477,57 +430,6 @@
 }
 
 /*
- * Class:     java_net_NetworkInterface
- * Method:    getMacAddr0
- * Signature: ([bLjava/lang/String;I)[b
- */
-JNIEXPORT jbyteArray JNICALL NetworkInterface_getMacAddr0(JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) {
-  jint addr;
-  jbyte caddr[4];
-  struct in_addr iaddr;
-  jbyteArray ret = NULL;
-  unsigned char mac[16];
-  int len;
-  int sock;
-  jboolean isCopy;
-  const char* name_utf;
-
-  name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
-
-  if ((sock =openSocketWithFallback(env, name_utf)) < 0) {
-    (*env)->ReleaseStringUTFChars(env, name, name_utf);
-    return JNI_FALSE;
-  }
-
-
-  if (!IS_NULL(addrArray)) {
-    (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
-    addr = ((caddr[0]<<24) & 0xff000000);
-    addr |= ((caddr[1] <<16) & 0xff0000);
-    addr |= ((caddr[2] <<8) & 0xff00);
-    addr |= (caddr[3] & 0xff);
-    iaddr.s_addr = htonl(addr);
-    len = getMacAddress(env, sock, name_utf, &iaddr, mac);
-  } else {
-    len = getMacAddress(env, sock, name_utf,NULL, mac);
-  }
-  if (len > 0) {
-    ret = (*env)->NewByteArray(env, len);
-    if (IS_NULL(ret)) {
-      /* we may have memory to free at the end of this */
-      goto fexit;
-    }
-    (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) (mac));
-  }
-fexit:
-  /* release the UTF string and interface list */
-  (*env)->ReleaseStringUTFChars(env, name, name_utf);
-
-  close(sock);
-  return ret;
-}
-
-/*
  * Class:       java_net_NetworkInterface
  * Method:      getMTU0
  * Signature:   ([bLjava/lang/String;I)I
@@ -619,6 +521,18 @@
   (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE);
 
   /*
+   * Set the hardware address
+   */
+  if (ifs->hwAddrLen > 0 && ifs->hwAddr != NULL) {
+    jbyteArray hardwareAddr = (*env)->NewByteArray(env, ifs->hwAddrLen);
+    if (hardwareAddr == NULL) {
+      return NULL;
+    }
+    (*env)->SetByteArrayRegion(env, hardwareAddr, 0, ifs->hwAddrLen, (jbyte *)ifs->hwAddr);
+    (*env)->SetObjectField(env, netifObj, ni_hardwareAddrID, hardwareAddr);
+  }
+
+  /*
    * Count the number of address on this interface
    */
   addr_count = 0;
@@ -661,14 +575,13 @@
           if (ia2Obj) {
             setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
             (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
-            (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
           }
         }
+        (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
         (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj);
       }
     }
 
-#ifdef AF_INET6
     if (addrP->family == AF_INET6) {
       int scope=0;
       iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
@@ -696,7 +609,6 @@
         (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj);
       }
     }
-#endif
 
     if (iaObj == NULL) {
       return NULL;
@@ -745,56 +657,54 @@
 }
 
 /*
+ * Determines the mask length for IPV4/v6 addresses.
+ */
+static
+int mask_address_to_mask_length(uint8_t *val, int size) {
+  int byte, bit, plen = 0;
+
+  for (byte = 0; byte < size && val[byte] == 0xff; byte++) {
+    plen += 8;
+  }
+  if (byte < size) {
+    for (bit = 7; bit > 0; bit--) {
+      if (val[byte] & (1 << bit)) plen++;
+    }
+  }
+  return plen;
+}
+
+/*
  * Enumerates all interfaces
  */
 static netif *enumInterfaces(JNIEnv *env) {
-  netif *ifs;
-  int sock;
+  netif *ifs = NULL;
+  struct ifaddrs *ifa, *origifa;
 
-  /*
-   * Enumerate IPv4 addresses
-   */
-
-  sock = openSocket(env, AF_INET);
+  int sock = openSocket(env, AF_INET);
   if (sock < 0 && (*env)->ExceptionOccurred(env)) {
     return NULL;
   }
 
-  ifs = enumIPv4Interfaces(env, sock, NULL);
-  close(sock);
-
-  if (ifs == NULL && (*env)->ExceptionOccurred(env)) {
+  if (getifaddrs(&origifa) != 0) {
+    NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
+                                 "getifaddrs() function failed");
     return NULL;
   }
 
-  /* return partial list if exception occure in the middle of process ???*/
-
-  /*
-   * If IPv6 is available then enumerate IPv6 addresses.
-   */
-#ifdef AF_INET6
-
-  /* User can disable ipv6 expicitly by -Djava.net.preferIPv4Stack=true,
-   * so we have to call ipv6_available()
-   */
-  if (ipv6_available()) {
-
-    sock =  openSocket(env, AF_INET6);
-    if (sock < 0 && (*env)->ExceptionOccurred(env)) {
-      freeif(ifs);
-      return NULL;
+  for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ifa->ifa_addr != NULL) {
+      switch (ifa->ifa_addr->sa_family) {
+        case AF_PACKET:
+        case AF_INET:
+        case AF_INET6:
+          ifs = addif(env, sock, ifa, ifs);
+          break;
+      }
     }
-
-    ifs = enumIPv6Interfaces(env, sock, ifs);
-    close(sock);
-
-    if ((*env)->ExceptionOccurred(env)) {
-      freeif(ifs);
-      return NULL;
-    }
-
   }
-#endif
+
+  close(sock);
 
   return ifs;
 }
@@ -831,26 +741,25 @@
       freeif(currif->childs);
     }
 
+    /*
+     * Remove mac address
+     */
+    if (currif->hwAddr != NULL) {
+      free(currif->hwAddr);
+    }
+
     ifs = currif->next;
     free(currif);
     currif = ifs;
   }
 }
 
-netif *addif(JNIEnv *env, int sock, const char * if_name,
-             netif *ifs, struct sockaddr* ifr_addrP, int family,
-             short prefix)
+netif *addif(JNIEnv *env, int sock, struct ifaddrs *ifa, netif *ifs)
 {
   netif *currif = ifs, *parent;
-  netaddr *addrP;
+  netaddr *addrP = NULL;
 
-#ifdef LIFNAMSIZ
-  int ifnam_size = LIFNAMSIZ;
-  char name[LIFNAMSIZ], vname[LIFNAMSIZ];
-#else
-  int ifnam_size = IFNAMSIZ;
   char name[IFNAMSIZ], vname[IFNAMSIZ];
-#endif
 
   char  *name_colonP;
   int mask;
@@ -865,39 +774,58 @@
    * currently doesn't have any concept of physical vs.
    * logical interfaces.
    */
-  strncpy(name, if_name, ifnam_size);
-  name[ifnam_size - 1] = '\0';
+  strncpy(name, ifa->ifa_name, sizeof(name));
+  name[sizeof(name) - 1] = '\0';
   *vname = 0;
 
   /*
    * Create and populate the netaddr node. If allocation fails
    * return an un-updated list.
    */
-  /*Allocate for addr and brdcast at once*/
+  switch(ifa->ifa_addr->sa_family) {
+    case AF_INET:
+      addr_size = sizeof(struct sockaddr_in);
+      break;
+    case AF_INET6:
+      addr_size = sizeof(struct sockaddr_in6);
+      break;
+    case AF_PACKET:
+      // Don't add an address entry, will extract data to netif struct
+      addr_size = 0;
+      break;
+    default:
+      return NULL;
+  }
 
-#ifdef AF_INET6
-  addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
-#else
-  addr_size = sizeof(struct sockaddr_in);
-#endif
+  if (addr_size > 0) {
+    /*Allocate for addr and brdcast at once*/
+    CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr)+2*addr_size);
+    addrP->addr = (struct sockaddr *)( (char *) addrP+sizeof(netaddr) );
+    memcpy(addrP->addr, ifa->ifa_addr, addr_size);
 
-  CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr)+2*addr_size);
-  addrP->addr = (struct sockaddr *)( (char *) addrP+sizeof(netaddr) );
-  memcpy(addrP->addr, ifr_addrP, addr_size);
+    addrP->family = ifa->ifa_addr->sa_family;
+    addrP->next = 0;
 
-  addrP->family = family;
-  addrP->brdcast = NULL;
-  addrP->mask = prefix;
-  addrP->next = 0;
-  if (family == AF_INET) {
-    /*
-     * Deal with brodcast addr & subnet mask
-     */
-    struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
-    addrP->brdcast = getBroadcast(env, sock, name,  brdcast_to );
+    if (ifa->ifa_broadaddr && (ifa->ifa_flags & IFF_BROADCAST)) {
+      struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
+      addrP->brdcast = brdcast_to;
+      memcpy(brdcast_to, ifa->ifa_broadaddr, sizeof(struct sockaddr));
+    } else {
+      addrP->brdcast = NULL;
+    }
 
-    if (addrP->brdcast && (mask = getSubnet(env, sock, name)) != -1) {
-      addrP->mask = mask;
+    if (ifa->ifa_netmask) {
+      if (ifa->ifa_netmask->sa_family == AF_INET) {
+        addrP->mask = mask_address_to_mask_length(
+            (uint8_t*)&(((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr),
+            sizeof(struct in_addr));
+      } else if (ifa->ifa_netmask->sa_family == AF_INET6) {
+        addrP->mask = mask_address_to_mask_length(
+            (uint8_t*)&((struct sockaddr_in6*)ifa->ifa_netmask)->sin6_addr,
+            sizeof(struct in6_addr));
+      }
+    } else {
+      addrP->mask = 0;
     }
   }
 
@@ -943,23 +871,51 @@
    * insert it onto the list.
    */
   if (currif == NULL) {
-    CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
+    CHECKED_MALLOC3(currif, netif *, sizeof(netif) + sizeof(name));
     currif->name = (char *) currif+sizeof(netif);
-    strncpy(currif->name, name, ifnam_size);
-    currif->name[ifnam_size - 1] = '\0';
+    strncpy(currif->name, name, sizeof(name));
+    currif->name[sizeof(name) - 1] = '\0';
     currif->index = getIndex(sock, name);
     currif->addr = NULL;
     currif->childs = NULL;
     currif->virtual = isVirtual;
+    currif->hwAddrLen = 0;
+    currif->hwAddr = NULL;
     currif->next = ifs;
     ifs = currif;
   }
 
   /*
+   * Insert the mac address on the interface
+   */
+  if (ifa->ifa_addr->sa_family == AF_PACKET) {
+    struct sockaddr_ll *s = (struct sockaddr_ll*)ifa->ifa_addr;
+
+    if (s->sll_halen > 0) {
+      /*
+       * All bytes to 0 means no hardware address.
+       */
+      int i;
+      for (i = 0;i < s->sll_halen; ++i) {
+        if (s->sll_addr[i] != 0) {
+          break;
+        }
+      }
+      if (i != s->sll_halen && currif->hwAddr == NULL) {
+        CHECKED_MALLOC3(currif->hwAddr, uint8_t *, s->sll_halen);
+        memcpy(currif->hwAddr, s->sll_addr, s->sll_halen);
+        currif->hwAddrLen = s->sll_halen;
+      }
+    }
+  }
+
+  /*
    * Finally insert the address on the interface
    */
-  addrP->next = currif->addr;
-  currif->addr = addrP;
+  if (addrP != NULL) {
+    addrP->next = currif->addr;
+    currif->addr = addrP;
+  }
 
   parent = currif;
 
@@ -979,10 +935,10 @@
     }
 
     if (currif == NULL) {
-      CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
+      CHECKED_MALLOC3(currif, netif *, sizeof(netif) + sizeof(name));
       currif->name = (char *) currif + sizeof(netif);
-      strncpy(currif->name, vname, ifnam_size);
-      currif->name[ifnam_size - 1] = '\0';
+      strncpy(currif->name, vname, sizeof(name));
+      currif->name[sizeof(name) - 1] = '\0';
       currif->index = getIndex(sock, vname);
       currif->addr = NULL;
       /* Need to duplicate the addr entry? */
@@ -1033,12 +989,11 @@
 
 
 /** Linux **/
-#ifdef __linux__
+
 /* Open socket for further ioct calls, try v4 socket first and
  * if it falls return v6 socket
  */
 
-#ifdef AF_INET6
 static int openSocketWithFallback(JNIEnv *env, const char *ifname){
   int sock;
   struct ifreq if2;
@@ -1062,114 +1017,6 @@
   return sock;
 }
 
-#else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
-  return openSocket(env,AF_INET);
-}
-#endif
-
-static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
-  struct ifconf ifc;
-  struct ifreq *ifreqP;
-  char *buf;
-  int numifs;
-  unsigned i;
-
-
-  /* need to do a dummy SIOCGIFCONF to determine the buffer size.
-   * SIOCGIFCOUNT doesn't work
-   */
-  ifc.ifc_buf = NULL;
-  if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
-    NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
-    return ifs;
-  }
-
-  CHECKED_MALLOC3(buf,char *, ifc.ifc_len);
-
-  ifc.ifc_buf = buf;
-  if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
-    NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
-    (void) free(buf);
-    return ifs;
-  }
-
-  /*
-   * Iterate through each interface
-   */
-  ifreqP = ifc.ifc_req;
-  for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) {
-    /*
-     * Add to the list
-     */
-    ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0);
-
-    /*
-     * If an exception occurred then free the list
-     */
-    if ((*env)->ExceptionOccurred(env)) {
-      free(buf);
-      freeif(ifs);
-      return NULL;
-    }
-  }
-
-  /*
-   * Free socket and buffer
-   */
-  free(buf);
-  return ifs;
-}
-
-
-/*
- * Enumerates and returns all IPv6 interfaces on Linux
- */
-
-#ifdef AF_INET6
-static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
-  FILE *f;
-  char addr6[40], devname[21];
-  char addr6p[8][5];
-  int plen, scope, dad_status, if_idx;
-  uint8_t ipv6addr[16];
-
-  if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
-    while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
-                  addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7],
-                  &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
-
-      struct netif *ifs_ptr = NULL;
-      struct netif *last_ptr = NULL;
-      struct sockaddr_in6 addr;
-
-      sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
-              addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
-      inet_pton(AF_INET6, addr6, ipv6addr);
-
-      memset(&addr, 0, sizeof(struct sockaddr_in6));
-      memcpy((void*)addr.sin6_addr.s6_addr, (const void*)ipv6addr, 16);
-
-      addr.sin6_scope_id = if_idx;
-
-      ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, AF_INET6, plen);
-
-
-      /*
-       * If an exception occurred then return the list as is.
-       */
-      if ((*env)->ExceptionOccurred(env)) {
-        fclose(f);
-        return ifs;
-      }
-    }
-    fclose(f);
-  }
-  return ifs;
-}
-#endif
-
-
 static int getIndex(int sock, const char *name){
   /*
    * Try to get the interface index
@@ -1185,93 +1032,6 @@
   return if2.ifr_ifindex;
 }
 
-/**
- * Returns the IPv4 broadcast address of a named interface, if it exists.
- * Returns 0 if it doesn't have one.
- */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
-  struct sockaddr *ret = NULL;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  /* Let's make sure the interface does have a broadcast address */
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2)  < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGIFFLAGS failed");
-    return ret;
-  }
-
-  if (if2.ifr_flags & IFF_BROADCAST) {
-    /* It does, let's retrieve it*/
-    if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
-      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
-      return ret;
-    }
-
-    ret = brdcast_store;
-    memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
-  }
-
-  return ret;
-}
-
-/**
- * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
- * interface, if it has one, otherwise return -1.
- */
-static short getSubnet(JNIEnv *env, int sock, const char *ifname) {
-  unsigned int mask;
-  short ret;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
-    return -1;
-  }
-
-  mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr);
-  ret = 0;
-  while (mask) {
-    mask <<= 1;
-    ret++;
-  }
-
-  return ret;
-}
-
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
- * return puts the data in buf, and returns the length, in byte, of the
- * MAC address. Returns -1 if there is no hardware address on that interface.
- */
-static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
-  static struct ifreq ifr;
-  int i;
-
-  strcpy(ifr.ifr_name, ifname);
-  if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFHWADDR failed");
-    return -1;
-  }
-
-  memcpy(buf, &ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
-
-  /*
-   * All bytes to 0 means no hardware address.
-   */
-
-  for (i = 0; i < IFHWADDRLEN; i++) {
-    if (buf[i] != 0)
-      return IFHWADDRLEN;
-  }
-
-  return -1;
-}
-
 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
   struct ifreq if2;
 
@@ -1304,707 +1064,8 @@
   return 0;
 }
 
-#endif
-
-/** Solaris **/
-#ifdef __solaris__
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
- */
-
-#ifdef AF_INET6
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
-  int sock, alreadyV6 = 0;
-  struct lifreq if2;
-
-  if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-    if (errno == EPROTONOSUPPORT){
-      if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-        return -1;
-      }
-
-      alreadyV6=1;
-    }
-    else{ // errno is not NOSUPPORT
-      NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
-      return -1;
-    }
-  }
-
-  /**
-   * Solaris requires that we have IPv6 socket to query an
-   * interface without IPv4 address - check it here
-   * POSIX 1 require the kernell to return ENOTTY if the call is
-   * unappropriate for device e.g. NETMASK for device having IPv6
-   * only address but not all devices follows the standart so
-   * fallback on any error.  It's not an ecology friendly but more
-   * reliable.
-   */
-
-  if (! alreadyV6 ){
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.lifr_name, ifname);
-    if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
-      close(sock);
-      if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-        return -1;
-      }
-    }
-  }
-
-  return sock;
-}
-
-#else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
-  return openSocket(env,AF_INET);
-}
-#endif
-
-/*
- * Enumerates and returns all IPv4 interfaces
- * (linux verison)
- */
-
-static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
-  return enumIPvXInterfaces(env,sock, ifs, AF_INET);
-}
-
-#ifdef AF_INET6
-static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
-  return enumIPvXInterfaces(env,sock, ifs, AF_INET6);
-}
-#endif
-
-/*
-   Enumerates and returns all interfaces on Solaris
-   use the same code for IPv4 and IPv6
-   */
-static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family) {
-  struct lifconf ifc;
-  struct lifreq *ifr;
-  int n;
-  char *buf;
-  struct lifnum numifs;
-  unsigned bufsize;
-
-  /*
-   * Get the interface count
-   */
-  numifs.lifn_family = family;
-  numifs.lifn_flags = 0;
-  if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
-    NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFNUM failed");
-    return ifs;
-  }
-
-  /*
-   *  Enumerate the interface configurations
-   */
-  bufsize = numifs.lifn_count * sizeof (struct lifreq);
-  CHECKED_MALLOC3(buf, char *, bufsize);
-
-  ifc.lifc_family = family;
-  ifc.lifc_flags = 0;
-  ifc.lifc_len = bufsize;
-  ifc.lifc_buf = buf;
-  if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
-    NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFCONF failed");
-    free(buf);
-    return ifs;
-  }
-
-  /*
-   * Iterate through each interface
-   */
-  ifr = ifc.lifc_req;
-  for (n=0; n<numifs.lifn_count; n++, ifr++) {
-    int index = -1;
-    struct lifreq if2;
-
-    /*
-     * Ignore either IPv4 or IPv6 addresses
-     */
-    if (ifr->lifr_addr.ss_family != family) {
-      continue;
-    }
-
-#ifdef AF_INET6
-    if (ifr->lifr_addr.ss_family == AF_INET6) {
-      struct sockaddr_in6 *s6= (struct sockaddr_in6 *)&(ifr->lifr_addr);
-      s6->sin6_scope_id = getIndex(sock, ifr->lifr_name);
-    }
-#endif
-
-    /* add to the list */
-    ifs = addif(env, sock,ifr->lifr_name, ifs, (struct sockaddr *)&(ifr->lifr_addr),family, (short) ifr->lifr_addrlen);
-
-    /*
-     * If an exception occurred we return immediately
-     */
-    if ((*env)->ExceptionOccurred(env)) {
-      free(buf);
-      return ifs;
-    }
-
-  }
-
-  free(buf);
-  return ifs;
-}
-
-static int getIndex(int sock, const char *name){
-  /*
-   * Try to get the interface index
-   * (Not supported on Solaris 2.6 or 7)
-   */
-  struct lifreq if2;
-  strcpy(if2.lifr_name, name);
-
-  if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) {
-    return -1;
-  }
-
-  return if2.lifr_index;
-}
-
-/**
- * Returns the IPv4 broadcast address of a named interface, if it exists.
- * Returns 0 if it doesn't have one.
- */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
-  struct sockaddr *ret = NULL;
-  struct lifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.lifr_name, ifname);
-
-  /* Let's make sure the interface does have a broadcast address */
-  if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2)  < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGLIFFLAGS failed");
-    return ret;
-  }
-
-  if (if2.lifr_flags & IFF_BROADCAST) {
-    /* It does, let's retrieve it*/
-    if (ioctl(sock, SIOCGLIFBRDADDR, (char *)&if2) < 0) {
-      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFBRDADDR failed");
-      return ret;
-    }
-
-    ret = brdcast_store;
-    memcpy(ret, &if2.lifr_broadaddr, sizeof(struct sockaddr));
-  }
-
-  return ret;
-}
-
-/**
- * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
- * interface, if it has one, otherwise return -1.
- */
-static short getSubnet(JNIEnv *env, int sock, const char *ifname) {
-  unsigned int mask;
-  short ret;
-  struct lifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.lifr_name, ifname);
-
-  if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFNETMASK failed");
-    return -1;
-  }
-
-  mask = ntohl(((struct sockaddr_in*)&(if2.lifr_addr))->sin_addr.s_addr);
-  ret = 0;
-
-  while (mask) {
-    mask <<= 1;
-    ret++;
-  }
-
-  return ret;
-}
-
-
-
-#define DEV_PREFIX  "/dev/"
-
-/**
- * Solaris specific DLPI code to get hardware address from a device.
- * Unfortunately, at least up to Solaris X, you have to have special
- * privileges (i.e. be root).
- */
-static int getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf) {
-  char style1dev[MAXPATHLEN];
-  int fd;
-  dl_phys_addr_req_t dlpareq;
-  dl_phys_addr_ack_t *dlpaack;
-  struct strbuf msg;
-  char buf[128];
-  int flags = 0;
-
-  /**
-   * Device is in /dev
-   * e.g.: /dev/bge0
-   */
-  strcpy(style1dev, DEV_PREFIX);
-  strcat(style1dev, ifname);
-  if ((fd = open(style1dev, O_RDWR)) < 0) {
-    /*
-     * Can't open it. We probably are missing the privilege.
-     * We'll have to try something else
-     */
-    return 0;
-  }
-
-  dlpareq.dl_primitive = DL_PHYS_ADDR_REQ;
-  dlpareq.dl_addr_type = DL_CURR_PHYS_ADDR;
-
-  msg.buf = (char *)&dlpareq;
-  msg.len = DL_PHYS_ADDR_REQ_SIZE;
-
-  if (putmsg(fd, &msg, NULL, 0) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "putmsg failed");
-    return -1;
-  }
-
-  dlpaack = (dl_phys_addr_ack_t *)buf;
-
-  msg.buf = (char *)buf;
-  msg.len = 0;
-  msg.maxlen = sizeof (buf);
-  if (getmsg(fd, &msg, NULL, &flags) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "getmsg failed");
-    return -1;
-  }
-
-  if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) {
-    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Couldn't obtain phys addr\n");
-    return -1;
-  }
-
-  memcpy(retbuf, &buf[dlpaack->dl_addr_offset], dlpaack->dl_addr_length);
-  return dlpaack->dl_addr_length;
-}
-
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
- * return puts the data in buf, and returns the length, in byte, of the
- * MAC address. Returns -1 if there is no hardware address on that interface.
- */
-static int getMacAddress(JNIEnv *env, int sock, const char *ifname,  const struct in_addr* addr, unsigned char *buf) {
-  struct arpreq arpreq;
-  struct sockaddr_in* sin;
-  struct sockaddr_in ipAddr;
-  int len, i;
-  struct lifreq lif;
-
-  /* First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails
-   * try the old way.
-   */
-  memset(&lif, 0, sizeof(lif));
-  strlcpy(lif.lifr_name, ifname, sizeof(lif.lifr_name));
-
-  if (ioctl(sock, SIOCGLIFHWADDR, &lif) != -1) {
-    struct sockaddr_dl *sp;
-    sp = (struct sockaddr_dl *)&lif.lifr_addr;
-    memcpy(buf, &sp->sdl_data[0], sp->sdl_alen);
-    return sp->sdl_alen;
-  }
-
-  /**
-   * On Solaris we have to use DLPI, but it will only work if we have
-   * privileged access (i.e. root). If that fails, we try a lookup
-   * in the ARP table, which requires an IPv4 address.
-   */
-  if ((len = getMacFromDevice(env, ifname, buf))  == 0) {
-    /*DLPI failed - trying to do arp lookup*/
-
-    if (addr == NULL) {
-      /**
-       * No IPv4 address for that interface, so can't do an ARP lookup.
-       */
-      return -1;
-    }
-
-    len = 6; //???
-
-    sin = (struct sockaddr_in *) &arpreq.arp_pa;
-    memset((char *) &arpreq, 0, sizeof(struct arpreq));
-    ipAddr.sin_port = 0;
-    ipAddr.sin_family = AF_INET;
-    memcpy(&ipAddr.sin_addr, addr, sizeof(struct in_addr));
-    memcpy(&arpreq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
-    arpreq.arp_flags= ATF_PUBL;
-
-    if (ioctl(sock, SIOCGARP, &arpreq) < 0) {
-      return -1;
-    }
-
-    memcpy(buf, &arpreq.arp_ha.sa_data[0], len );
-  }
-
-  /*
-   * All bytes to 0 means no hardware address.
-   */
-
-  for (i = 0; i < len; i++) {
-    if (buf[i] != 0)
-      return len;
-  }
-
-  return -1;
-}
-
-static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
-  struct lifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.lifr_name, ifname);
-
-  if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFMTU failed");
-    return -1;
-  }
-
-  return  if2.lifr_mtu;
-}
-
-
-static int getFlags(int sock, const char *ifname, int *flags) {
-  struct   lifreq lifr;
-  memset((caddr_t)&lifr, 0, sizeof(lifr));
-  strcpy((caddr_t)&(lifr.lifr_name), ifname);
-
-  if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
-    return -1;
-  }
-
-  *flags = lifr.lifr_flags;
-  return 0;
-}
-
-
-#endif
-
-
-/** BSD **/
-#ifdef _ALLBSD_SOURCE
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
- */
-
-#ifdef AF_INET6
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
-  int sock;
-  struct ifreq if2;
-
-  if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-    if (errno == EPROTONOSUPPORT){
-      if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-        return -1;
-      }
-    }
-    else{ // errno is not NOSUPPORT
-      NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
-      return -1;
-    }
-  }
-
-  return sock;
-}
-
-#else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
-  return openSocket(env,AF_INET);
-}
-#endif
-
-/*
- * Enumerates and returns all IPv4 interfaces
- */
-static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
-  struct ifaddrs *ifa, *origifa;
-
-  if (getifaddrs(&origifa) != 0) {
-    NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                                 "getifaddrs() function failed");
-    return ifs;
-  }
-
-  for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
-
-    /*
-     * Skip non-AF_INET entries.
-     */
-    if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
-      continue;
-
-    /*
-     * Add to the list.
-     */
-    ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET, 0);
-
-    /*
-     * If an exception occurred then free the list.
-     */
-    if ((*env)->ExceptionOccurred(env)) {
-      freeifaddrs(origifa);
-      freeif(ifs);
-      return NULL;
-    }
-  }
-
-  /*
-   * Free socket and buffer
-   */
-  freeifaddrs(origifa);
-  return ifs;
-}
-
-
-/*
- * Enumerates and returns all IPv6 interfaces on Linux
- */
-
-#ifdef AF_INET6
-/*
- * Determines the prefix on BSD for IPv6 interfaces.
- */
-static
-int prefix(void *val, int size) {
-  u_char *name = (u_char *)val;
-  int byte, bit, plen = 0;
-
-  for (byte = 0; byte < size; byte++, plen += 8)
-    if (name[byte] != 0xff)
-      break;
-  if (byte == size)
-    return (plen);
-  for (bit = 7; bit != 0; bit--, plen++)
-    if (!(name[byte] & (1 << bit)))
-      break;
-  for (; bit != 0; bit--)
-    if (name[byte] & (1 << bit))
-      return (0);
-  byte++;
-  for (; byte < size; byte++)
-    if (name[byte])
-      return (0);
-  return (plen);
-}
-
-/*
- * Enumerates and returns all IPv6 interfaces on BSD
- */
-static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
-  struct ifaddrs *ifa, *origifa;
-  struct sockaddr_in6 *sin6;
-  struct in6_ifreq ifr6;
-
-  if (getifaddrs(&origifa) != 0) {
-    NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                                 "getifaddrs() function failed");
-    return ifs;
-  }
-
-  for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
-
-    /*
-     * Skip non-AF_INET6 entries.
-     */
-    if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6)
-      continue;
-
-    memset(&ifr6, 0, sizeof(ifr6));
-    strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
-    memcpy(&ifr6.ifr_addr, ifa->ifa_addr, MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len));
-
-    if (ioctl(sock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) < 0) {
-      NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                                   "ioctl SIOCGIFNETMASK_IN6 failed");
-      freeifaddrs(origifa);
-      freeif(ifs);
-      return NULL;
-    }
-
-    /* Add to the list.  */
-    sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
-    ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET6,
-                prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
-
-    /* If an exception occurred then free the list.  */
-    if ((*env)->ExceptionOccurred(env)) {
-      freeifaddrs(origifa);
-      freeif(ifs);
-      return NULL;
-    }
-  }
-
-  /*
-   * Free socket and ifaddrs buffer
-   */
-  freeifaddrs(origifa);
-  return ifs;
-}
-#endif
-
-static int getIndex(int sock, const char *name){
-#ifdef __FreeBSD__
-  /*
-   * Try to get the interface index
-   * (Not supported on Solaris 2.6 or 7)
-   */
-  struct ifreq if2;
-  strcpy(if2.ifr_name, name);
-
-  if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
-    return -1;
-  }
-
-  return if2.ifr_index;
-#else
-  /*
-   * Try to get the interface index using BSD specific if_nametoindex
-   */
-  int index = if_nametoindex(name);
-  return (index == 0) ? -1 : index;
-#endif
-}
-
-/**
- * Returns the IPv4 broadcast address of a named interface, if it exists.
- * Returns 0 if it doesn't have one.
- */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
-  struct sockaddr *ret = NULL;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  /* Let's make sure the interface does have a broadcast address */
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFFLAGS failed");
-    return ret;
-  }
-
-  if (if2.ifr_flags & IFF_BROADCAST) {
-    /* It does, let's retrieve it*/
-    if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
-      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
-      return ret;
-    }
-
-    ret = brdcast_store;
-    memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
-  }
-
-  return ret;
-}
-
-/**
- * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
- * interface, if it has one, otherwise return -1.
- */
-static short getSubnet(JNIEnv *env, int sock, const char *ifname) {
-  unsigned int mask;
-  short ret;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
-    return -1;
-  }
-
-  mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr);
-  ret = 0;
-  while (mask) {
-    mask <<= 1;
-    ret++;
-  }
-
-  return ret;
-}
-
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
- * return puts the data in buf, and returns the length, in byte, of the
- * MAC address. Returns -1 if there is no hardware address on that interface.
- */
-static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
-  struct ifaddrs *ifa0, *ifa;
-  struct sockaddr *saddr;
-  int i;
-
-  /* Grab the interface list */
-  if (!getifaddrs(&ifa0)) {
-    /* Cycle through the interfaces */
-    for (i = 0, ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next, i++) {
-      saddr = ifa->ifa_addr;
-      /* Link layer contains the MAC address */
-      if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) {
-        struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr;
-        /* Check the address is the correct length */
-        if (sadl->sdl_alen == ETHER_ADDR_LEN) {
-          memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN);
-          freeifaddrs(ifa0);
-          return ETHER_ADDR_LEN;
-        }
-      }
-    }
-    freeifaddrs(ifa0);
-  }
-
-  return -1;
-}
-
-static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
-    NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
-    return -1;
-  }
-
-  return  if2.ifr_mtu;
-}
-
-static int getFlags(int sock, const char *ifname, int *flags) {
-  struct ifreq if2;
-  int ret = -1;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){
-    return -1;
-  }
-
-  if (sizeof(if2.ifr_flags) == sizeof(short)) {
-    *flags = (if2.ifr_flags & 0xffff);
-  } else {
-    *flags = if2.ifr_flags;
-  }
-  return 0;
-}
-
-#endif
-
 static JNINativeMethod gMethods[] = {
   NATIVE_METHOD(NetworkInterface, getMTU0, "(Ljava/lang/String;I)I"),
-  NATIVE_METHOD(NetworkInterface, getMacAddr0, "([BLjava/lang/String;I)[B"),
   NATIVE_METHOD(NetworkInterface, supportsMulticast0, "(Ljava/lang/String;I)Z"),
   NATIVE_METHOD(NetworkInterface, isLoopback0, "(Ljava/lang/String;I)Z"),
   NATIVE_METHOD(NetworkInterface, isP2P0, "(Ljava/lang/String;I)Z"),