/*
 * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>           /* needed for htonl */
#include <iprtrmib.h>
#include <assert.h>

#include "java_net_NetworkInterface.h"
#include "jni_util.h"

#include "NetworkInterface.h"

/*
 * Windows implementation of the java.net.NetworkInterface native methods.
 * This module provides the implementations of getAll, getByName, getByIndex,
 * and getByAddress.
 *
 * Interfaces and addresses are enumerated using the IP helper routines
 * GetIfTable, GetIfAddrTable resp. These routines are available on Windows
 * 98, NT SP+4, 2000, and XP. They are also available on Windows 95 if
 * IE is upgraded to 5.x.
 *
 * Windows does not have any standard for device names so we are forced
 * to use our own convention which is based on the normal Unix naming
 * convention ("lo" for the loopback, eth0, eth1, .. for ethernet devices,
 * tr0, tr1, .. for token ring, and so on). This convention gives us
 * consistency across multiple Windows editions and also consistency with
 * Solaris/Linux device names. Note that we always enumerate in index
 * order and this ensures consistent device number across invocations.
 */

/* various JNI ids */

jclass ni_class;            /* NetworkInterface */

jmethodID ni_ctor;          /* NetworkInterface() */

jfieldID ni_indexID;        /* NetworkInterface.index */
jfieldID ni_addrsID;        /* NetworkInterface.addrs */
jfieldID ni_bindsID;        /* NetworkInterface.bindings */
jfieldID ni_nameID;         /* NetworkInterface.name */
jfieldID ni_displayNameID;  /* NetworkInterface.displayName */
jfieldID ni_childsID;       /* NetworkInterface.childs */

jclass ni_ibcls;            /* InterfaceAddress */
jmethodID ni_ibctrID;       /* InterfaceAddress() */
jfieldID ni_ibaddressID;        /* InterfaceAddress.address */
jfieldID ni_ibbroadcastID;      /* InterfaceAddress.broadcast */
jfieldID ni_ibmaskID;           /* InterfaceAddress.maskLength */

/*
 * Support routines to free netif and netaddr lists
 */
void free_netif(netif *netifP) {
    netif *curr = netifP;
    while (curr != NULL) {
        if (curr->name != NULL)
            free(curr->name);
        if (curr->displayName != NULL)
            free(curr->displayName);
        if (curr->addrs != NULL)
            free_netaddr (curr->addrs);
        netifP = netifP->next;
        free(curr);
        curr = netifP;
    }
}

void free_netaddr(netaddr *netaddrP) {
    netaddr *curr = netaddrP;
    while (curr != NULL) {
        netaddrP = netaddrP->next;
        free(curr);
        curr = netaddrP;
    }
}

/*
 * Returns the interface structure from the table with the matching index.
 */
MIB_IFROW *getIF(jint index) {
    MIB_IFTABLE *tableP;
    MIB_IFROW *ifrowP, *ret = NULL;
    ULONG size;
    DWORD i, count;
    jint ifindex;

    /*
     * Ask the IP Helper library to enumerate the adapters
     */
    size = sizeof(MIB_IFTABLE);
    tableP = (MIB_IFTABLE *)malloc(size);
    if(tableP == NULL)
        return NULL;

    count = GetIfTable(tableP, &size, TRUE);
    if (count == ERROR_INSUFFICIENT_BUFFER || count == ERROR_BUFFER_OVERFLOW) {
        MIB_IFTABLE* newTableP =  (MIB_IFTABLE *)realloc(tableP, size);
        if (newTableP == NULL) {
            free(tableP);
            return NULL;
        }
        tableP = newTableP;

        count = GetIfTable(tableP, &size, TRUE);
    }

    if (count != NO_ERROR) {
        free(tableP);
        return NULL;
    }

    {
    ifrowP = tableP->table;
    for (i=0; i<tableP->dwNumEntries; i++) {
    /*
     * Warning: the real index is obtained by GetFriendlyIfIndex()
    */
        ifindex = GetFriendlyIfIndex(ifrowP->dwIndex);
        if (ifindex == index) {
          /*
           * Create a copy of the entry so that we can free the table.
           */
            ret = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
            if (ret == NULL) {
                free(tableP);
                return NULL;
            }
            memcpy(ret, ifrowP, sizeof(MIB_IFROW));
            break;
        }

        /* onto the next interface */
        ifrowP++;
      }
      free(tableP);
    }
    return ret;
}

/*
 * Enumerate network interfaces using IP Helper Library routine GetIfTable.
 * We use GetIfTable rather than other IP helper routines because it's
 * available on 98 & NT SP4+.
 *
 * Returns the number of interfaces found or -1 if error. If no error
 * occurs then netifPP be returned as list of netif structures or NULL
 * if no interfaces are found.
 */
int enumInterfaces(JNIEnv *env, netif **netifPP)
{
    MIB_IFTABLE *tableP;
    MIB_IFROW *ifrowP;
    ULONG size;
    DWORD ret;
    int count;
    netif *netifP;
    DWORD i;
    int lo=0, eth=0, tr=0, fddi=0, ppp=0, sl=0, wlan=0, net=0, wlen=0;

    /*
     * Ask the IP Helper library to enumerate the adapters
     */
    size = sizeof(MIB_IFTABLE);
    tableP = (MIB_IFTABLE *)malloc(size);
    if (tableP == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
        return -1;
    }

    ret = GetIfTable(tableP, &size, TRUE);
    if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
        MIB_IFTABLE * newTableP = (MIB_IFTABLE *)realloc(tableP, size);
        if (newTableP == NULL) {
            free(tableP);
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
            return -1;
        }
        tableP = newTableP;
        ret = GetIfTable(tableP, &size, TRUE);
    }

    if (ret != NO_ERROR) {
        free(tableP);

        JNU_ThrowByName(env, "java/lang/Error",
                "IP Helper Library GetIfTable function failed");

        return -1;
    }

    /*
     * Iterate through the list of adapters
     */
    count = 0;
    netifP = NULL;

    ifrowP = tableP->table;
    for (i=0; i<tableP->dwNumEntries; i++) {
        char dev_name[8];
        netif *curr;

        /*
         * Generate a name for the device as Windows doesn't have any
         * real concept of a device name.
         */
        switch (ifrowP->dwType) {
            case MIB_IF_TYPE_ETHERNET:
                _snprintf_s(dev_name, 8, _TRUNCATE, "eth%d", eth++);
                break;

            case MIB_IF_TYPE_TOKENRING:
                _snprintf_s(dev_name, 8, _TRUNCATE, "tr%d", tr++);
                break;

            case MIB_IF_TYPE_FDDI:
                _snprintf_s(dev_name, 8, _TRUNCATE, "fddi%d", fddi++);
                break;

            case MIB_IF_TYPE_LOOPBACK:
                /* There should only be only IPv4 loopback address */
                if (lo > 0) {
                    continue;
                }
                strncpy_s(dev_name, 8, "lo", _TRUNCATE);
                lo++;
                break;

            case MIB_IF_TYPE_PPP:
                _snprintf_s(dev_name, 8, _TRUNCATE, "ppp%d", ppp++);
                break;

            case MIB_IF_TYPE_SLIP:
                _snprintf_s(dev_name, 8, _TRUNCATE, "sl%d", sl++);
                break;

            case IF_TYPE_IEEE80211:
                _snprintf_s(dev_name, 8, _TRUNCATE, "wlan%d", wlan++);
                break;

            default:
                _snprintf_s(dev_name, 8, _TRUNCATE, "net%d", net++);
        }

        /*
         * Allocate a netif structure and space for the name and
         * display name (description in this case).
         */
        curr = (netif *)calloc(1, sizeof(netif));
        if (curr != NULL) {
            wlen = MultiByteToWideChar(CP_OEMCP, 0, ifrowP->bDescr,
                       ifrowP->dwDescrLen, NULL, 0);
            if(wlen == 0) {
                // MultiByteToWideChar should not fail
                // But in rare case it fails, we allow 'char' to be displayed
                curr->displayName = (char *)malloc(ifrowP->dwDescrLen + 1);
            } else {
                curr->displayName = (wchar_t *)malloc(wlen*(sizeof(wchar_t))+1);
            }

            curr->name = (char *)malloc(strlen(dev_name) + 1);

            if (curr->name == NULL || curr->displayName == NULL) {
                if (curr->name) free(curr->name);
                if (curr->displayName) free(curr->displayName);
                free(curr);
                curr = NULL;
            }
        }
        if (curr == NULL) {
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
            free_netif(netifP);
            free(tableP);
            return -1;
        }

        /*
         * Populate the interface. Note that we need to convert the
         * index into its "friendly" value as otherwise we will expose
         * 32-bit numbers as index values.
         */
        strcpy(curr->name, dev_name);
        if (wlen == 0) {
            // display char type in case of MultiByteToWideChar failure
            strncpy(curr->displayName, ifrowP->bDescr, ifrowP->dwDescrLen);
            curr->displayName[ifrowP->dwDescrLen] = '\0';
        } else {
            // call MultiByteToWideChar again to fill curr->displayName
            // it should not fail, because we have called it once before
            if (MultiByteToWideChar(CP_OEMCP, 0, ifrowP->bDescr,
                   ifrowP->dwDescrLen, curr->displayName, wlen) == 0) {
                JNU_ThrowByName(env, "java/lang/Error",
                       "Cannot get multibyte char for interface display name");
                free_netif(netifP);
                free(tableP);
                free(curr->name);
                free(curr->displayName);
                free(curr);
                return -1;
            } else {
                curr->displayName[wlen*(sizeof(wchar_t))] = '\0';
                curr->dNameIsUnicode = TRUE;
            }
        }

        curr->dwIndex = ifrowP->dwIndex;
        curr->ifType = ifrowP->dwType;
        curr->index = GetFriendlyIfIndex(ifrowP->dwIndex);

        /*
         * Put the interface at tail of list as GetIfTable(,,TRUE) is
         * returning the interfaces in index order.
         */
        count++;
        if (netifP == NULL) {
            netifP = curr;
        } else {
            netif *tail = netifP;
            while (tail->next != NULL) {
                tail = tail->next;
            }
            tail->next = curr;
        }

        /* onto the next interface */
        ifrowP++;
    }

    /*
     * Free the interface table and return the interface list
     */
    if (tableP) {
        free(tableP);
    }
    *netifPP = netifP;
    return count;
}

/*
 * Enumerate the IP addresses on an interface using the IP helper library
 * routine GetIfAddrTable and matching based on the index name. There are
 * more efficient routines but we use GetIfAddrTable because it's avaliable
 * on 98 and NT.
 *
 * Returns the count of addresses, or -1 if error. If no error occurs then
 * netaddrPP will return a list of netaddr structures with the IP addresses.
 */
int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP)
{
    MIB_IPADDRTABLE *tableP;
    ULONG size;
    DWORD ret;
    DWORD i;
    netaddr *netaddrP;
    int count = 0;
    unsigned long mask;

    /*
     * Use GetIpAddrTable to enumerate the IP Addresses
     */
    size = sizeof(MIB_IPADDRTABLE);
    tableP = (MIB_IPADDRTABLE *)malloc(size);
    if (tableP == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
        return -1;
    }

    ret = GetIpAddrTable(tableP, &size, FALSE);
    if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
        MIB_IPADDRTABLE * newTableP = (MIB_IPADDRTABLE *)realloc(tableP, size);
        if (newTableP == NULL) {
            free(tableP);
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
            return -1;
        }
        tableP = newTableP;

        ret = GetIpAddrTable(tableP, &size, FALSE);
    }
    if (ret != NO_ERROR) {
        if (tableP) {
            free(tableP);
        }
        JNU_ThrowByName(env, "java/lang/Error",
                "IP Helper Library GetIpAddrTable function failed");
        return -1;
    }

    /*
     * Iterate through the table to find the addresses with the
     * matching dwIndex. Ignore 0.0.0.0 addresses.
     */
    count = 0;
    netaddrP = NULL;

    i = 0;
    while (i<tableP->dwNumEntries) {
        if (tableP->table[i].dwIndex == netifP->dwIndex &&
            tableP->table[i].dwAddr != 0) {

            netaddr *curr = (netaddr *)malloc(sizeof(netaddr));
            if (curr == NULL) {
                JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
                free_netaddr(netaddrP);
                free(tableP);
                return -1;
            }

            curr->addr.him4.sin_family = AF_INET;
            curr->addr.him4.sin_addr.s_addr = tableP->table[i].dwAddr;
            /*
             * Get netmask / broadcast address
             */
            switch (netifP->ifType) {
            case MIB_IF_TYPE_ETHERNET:
            case MIB_IF_TYPE_TOKENRING:
            case MIB_IF_TYPE_FDDI:
            case MIB_IF_TYPE_LOOPBACK:
            case IF_TYPE_IEEE80211:
              /**
               * Contrary to what it seems to indicate, dwBCastAddr doesn't
               * contain the broadcast address but 0 or 1 depending on whether
               * the broadcast address should set the bits of the host part
               * to 0 or 1.
               * Yes, I know it's stupid, but what can I say, it's MSFTs API.
               */
              curr->brdcast.him4.sin_family = AF_INET;
              if (tableP->table[i].dwBCastAddr == 1)
                curr->brdcast.him4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask);
              else
                curr->brdcast.him4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask);
              mask = ntohl(tableP->table[i].dwMask);
              curr->mask = 0;
              while (mask) {
                mask <<= 1;
                curr->mask++;
              }
              break;
            case MIB_IF_TYPE_PPP:
            case MIB_IF_TYPE_SLIP:
            default:
              /**
               * these don't have broadcast/subnet
               */
              curr->mask = -1;
                break;
            }

            curr->next = netaddrP;
            netaddrP = curr;
            count++;
        }
        i++;
    }

    *netaddrPP = netaddrP;
    free(tableP);
    return count;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    init
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls)
{
    /*
     * Get the various JNI ids that we require
     */
    ni_class = (*env)->NewGlobalRef(env, cls);
    CHECK_NULL(ni_class);
    ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
    CHECK_NULL(ni_nameID);
    ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
    CHECK_NULL(ni_displayNameID);
    ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
    CHECK_NULL(ni_indexID);
    ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
    CHECK_NULL(ni_addrsID);
    ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
    CHECK_NULL(ni_bindsID);
    ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
    CHECK_NULL(ni_childsID);
    ni_ctor = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
    CHECK_NULL(ni_ctor);
    ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
    CHECK_NULL(ni_ibcls);
    ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
    CHECK_NULL(ni_ibcls);
    ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
    CHECK_NULL(ni_ibctrID);
    ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
    CHECK_NULL(ni_ibaddressID);
    ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
    CHECK_NULL(ni_ibbroadcastID);
    ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
    CHECK_NULL(ni_ibmaskID);

    initInetAddressIDs(env);
}

/*
 * Create a NetworkInterface object, populate the name and index, and
 * populate the InetAddress array based on the IP addresses for this
 * interface.
 */
jobject createNetworkInterface
    (JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP)
{
    jobject netifObj;
    jobject name, displayName;
    jobjectArray addrArr, bindsArr, childArr;
    netaddr *addrs;
    jint addr_index;
    jint bind_index;

    /*
     * Create a NetworkInterface object and populate it
     */
    netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
    CHECK_NULL_RETURN(netifObj, NULL);
    name = (*env)->NewStringUTF(env, ifs->name);
    CHECK_NULL_RETURN(name, NULL);
    if (ifs->dNameIsUnicode) {
        displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName,
                                       (jsize)wcslen ((PWCHAR)ifs->displayName));
    } else {
        displayName = (*env)->NewStringUTF(env, ifs->displayName);
    }
    CHECK_NULL_RETURN(displayName, NULL);
    (*env)->SetObjectField(env, netifObj, ni_nameID, name);
    (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
    (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);

    /*
     * Get the IP addresses for this interface if necessary
     * Note that 0 is a valid number of addresses.
     */
    if (netaddrCount < 0) {
        netaddrCount = enumAddresses_win(env, ifs, &netaddrP);
        if (netaddrCount == -1) {
            return NULL;
        }
    }
    addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
    if (addrArr == NULL) {
        free_netaddr(netaddrP);
        return NULL;
    }

    bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
    if (bindsArr == NULL) {
      free_netaddr(netaddrP);
      return NULL;
    }
    addrs = netaddrP;
    addr_index = 0;
    bind_index = 0;
    while (addrs != NULL) {
        jobject iaObj, ia2Obj;
        jobject ibObj = NULL;
        if (addrs->addr.him.sa_family == AF_INET) {
            iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
            if (iaObj == NULL) {
                free_netaddr(netaddrP);
                return NULL;
            }
            /* default ctor will set family to AF_INET */

            setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));
            if ((*env)->ExceptionCheck(env)) {
                free_netaddr(netaddrP);
                return NULL;
            }
            if (addrs->mask != -1) {
              ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
              if (ibObj == NULL) {
                free_netaddr(netaddrP);
                return NULL;
              }
              (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
              ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
              if (ia2Obj == NULL) {
                free_netaddr(netaddrP);
                return NULL;
              }
              setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
              if ((*env)->ExceptionCheck(env)) {
                  free_netaddr(netaddrP);
                  return NULL;
              }
              (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
              (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
              (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
            }
        } else /* AF_INET6 */ {
            int scope;
            iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
            if (iaObj) {
                int ret = setInet6Address_ipaddress(env, iaObj,  (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
                if (ret == JNI_FALSE) {
                    free_netaddr(netaddrP);
                    return NULL;
                }

                scope = addrs->addr.him6.sin6_scope_id;
                if (scope != 0) { /* zero is default value, no need to set */
                    setInet6Address_scopeid(env, iaObj, scope);
                    setInet6Address_scopeifname(env, iaObj, netifObj);
                }
                ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
                if (ibObj == NULL) {
                  free_netaddr(netaddrP);
                  return NULL;
                }
                (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
                (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
                (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
            }
        }
        (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
        addrs = addrs->next;
        addr_index++;
    }
    (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
    (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);

    free_netaddr(netaddrP);

    /*
     * Windows doesn't have virtual interfaces, so child array
     * is always empty.
     */
    childArr = (*env)->NewObjectArray(env, 0, ni_class, NULL);
    if (childArr == NULL) {
      return NULL;
    }
    (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);

    /* return the NetworkInterface */
    return netifObj;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    getByName0
 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
 */
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0
    (JNIEnv *env, jclass cls, jstring name)
{
    netif *ifList, *curr;
    jboolean isCopy;
    const char *name_utf;
    jobject netifObj = NULL;

    // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
    if (ipv6_available()) {
        return Java_java_net_NetworkInterface_getByName0_XP (env, cls, name);
    }

    /* get the list of interfaces */
    if (enumInterfaces(env, &ifList) < 0) {
        return NULL;
    }

    /* get the name as a C string */
    name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
    if (name_utf != NULL) {

        /* Search by name */
        curr = ifList;
        while (curr != NULL) {
            if (strcmp(name_utf, curr->name) == 0) {
                break;
            }
            curr = curr->next;
        }

        /* if found create a NetworkInterface */
        if (curr != NULL) {;
            netifObj = createNetworkInterface(env, curr, -1, NULL);
        }

        /* release the UTF string */
        (*env)->ReleaseStringUTFChars(env, name, name_utf);
    } else {
        if (!(*env)->ExceptionCheck(env))
            JNU_ThrowOutOfMemoryError(env, NULL);
    }

    /* release the interface list */
    free_netif(ifList);

    return netifObj;
}

/*
 * Class:     NetworkInterface
 * Method:    getByIndex0
 * Signature: (I)LNetworkInterface;
 */
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0
  (JNIEnv *env, jclass cls, jint index)
{
    netif *ifList, *curr;
    jobject netifObj = NULL;

    // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
    if (ipv6_available()) {
        return Java_java_net_NetworkInterface_getByIndex0_XP (env, cls, index);
    }

    /* get the list of interfaces */
    if (enumInterfaces(env, &ifList) < 0) {
        return NULL;
    }

    /* search by index */
    curr = ifList;
    while (curr != NULL) {
        if (index == curr->index) {
            break;
        }
        curr = curr->next;
    }

    /* if found create a NetworkInterface */
    if (curr != NULL) {
        netifObj = createNetworkInterface(env, curr, -1, NULL);
    }

    /* release the interface list */
    free_netif(ifList);

    return netifObj;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    getByInetAddress0
 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
 */
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
    (JNIEnv *env, jclass cls, jobject iaObj)
{
    netif *ifList, *curr;
    jobject netifObj = NULL;
    jint addr = getInetAddress_addr(env, iaObj);
    JNU_CHECK_EXCEPTION_RETURN(env, NULL);

    // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
    if (ipv6_available()) {
        return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
    }

    /* get the list of interfaces */
    if (enumInterfaces(env, &ifList) < 0) {
        return NULL;
    }

    /*
     * Enumerate the addresses on each interface until we find a
     * matching address.
     */
    curr = ifList;
    while (curr != NULL) {
        int count;
        netaddr *addrList;
        netaddr *addrP;

        /* enumerate the addresses on this interface */
        count = enumAddresses_win(env, curr, &addrList);
        if (count < 0) {
            free_netif(ifList);
            return NULL;
        }

        /* iterate through each address */
        addrP = addrList;

        while (addrP != NULL) {
            if ((unsigned long)addr == ntohl(addrP->addr.him4.sin_addr.s_addr)) {
                break;
            }
            addrP = addrP->next;
        }

        /*
         * Address matched so create NetworkInterface for this interface
         * and address list.
         */
        if (addrP != NULL) {
            /* createNetworkInterface will free addrList */
            netifObj = createNetworkInterface(env, curr, count, addrList);
            break;
        }

        /* on next interface */
        curr = curr->next;
    }

    /* release the interface list */
    free_netif(ifList);

    return netifObj;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    getAll
 * Signature: ()[Ljava/net/NetworkInterface;
 */
JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
    (JNIEnv *env, jclass cls)
{
    int count;
    netif *ifList, *curr;
    jobjectArray netIFArr;
    jint arr_index;

    // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
    if (ipv6_available()) {
        return Java_java_net_NetworkInterface_getAll_XP (env, cls);
    }

    /*
     * Get list of interfaces
     */
    count = enumInterfaces(env, &ifList);
    if (count < 0) {
        return NULL;
    }

    /* allocate a NetworkInterface array */
    netIFArr = (*env)->NewObjectArray(env, count, cls, NULL);
    if (netIFArr == NULL) {
        return NULL;
    }

    /*
     * Iterate through the interfaces, create a NetworkInterface instance
     * for each array element and populate the object.
     */
    curr = ifList;
    arr_index = 0;
    while (curr != NULL) {
        jobject netifObj;

        netifObj = createNetworkInterface(env, curr, -1, NULL);
        if (netifObj == NULL) {
            return NULL;
        }

        /* put the NetworkInterface into the array */
        (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);

        curr = curr->next;
    }

    /* release the interface list */
    free_netif(ifList);

    return netIFArr;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    isUp0
 * Signature: (Ljava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0
    (JNIEnv *env, jclass cls, jstring name, jint index) {
  jboolean ret = JNI_FALSE;

  // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
  if (ipv6_available()) {
    return Java_java_net_NetworkInterface_isUp0_XP(env, cls, name, index);
  } else {
    MIB_IFROW *ifRowP;
    ifRowP = getIF(index);
    if (ifRowP != NULL) {
      ret = ifRowP->dwAdminStatus == MIB_IF_ADMIN_STATUS_UP &&
            (ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL ||
             ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED);
      free(ifRowP);
    }
  }
    return ret;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    isP2P0
 * Signature: (Ljava/lang/String;I)Z
 */
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0
    (JNIEnv *env, jclass cls, jstring name, jint index) {
  MIB_IFROW *ifRowP;
  jboolean ret = JNI_FALSE;

  // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
  if (ipv6_available()) {
    return Java_java_net_NetworkInterface_isP2P0_XP(env, cls, name, index);
  } else {
    ifRowP = getIF(index);
    if (ifRowP != NULL) {
      switch(ifRowP->dwType) {
      case MIB_IF_TYPE_PPP:
      case MIB_IF_TYPE_SLIP:
        ret = JNI_TRUE;
        break;
      }
      free(ifRowP);
    }
  }
  return ret;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    isLoopback0
 * Signature: (Ljava/lang/String;I)Z
 */
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0
    (JNIEnv *env, jclass cls, jstring name, jint index) {
  MIB_IFROW *ifRowP;
  jboolean ret = JNI_FALSE;

  // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
  if (ipv6_available()) {
    return Java_java_net_NetworkInterface_isLoopback0_XP(env, cls, name, index);
  } else {
    ifRowP = getIF(index);
    if (ifRowP != NULL) {
      if (ifRowP->dwType == MIB_IF_TYPE_LOOPBACK)
        ret = JNI_TRUE;
      free(ifRowP);
    }
    return ret;
  }
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    supportsMulticast0
 * Signature: (Ljava/lang/String;I)Z
 */
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0
    (JNIEnv *env, jclass cls, jstring name, jint index) {
    return Java_java_net_NetworkInterface_supportsMulticast0_XP(env, cls,
                                                               name, index);
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    getMacAddr0
 * Signature: ([bLjava/lang/String;I)[b
 */
JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0
    (JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) {
  jbyteArray ret = NULL;
  int len;
  MIB_IFROW *ifRowP;

  // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
  if (ipv6_available()) {
    return Java_java_net_NetworkInterface_getMacAddr0_XP(env, class, name, index);
  } else {
    ifRowP = getIF(index);
    if (ifRowP != NULL) {
      switch(ifRowP->dwType) {
      case MIB_IF_TYPE_ETHERNET:
      case MIB_IF_TYPE_TOKENRING:
      case MIB_IF_TYPE_FDDI:
      case IF_TYPE_IEEE80211:
        len = ifRowP->dwPhysAddrLen;
        if (len > 0) {
            ret = (*env)->NewByteArray(env, len);
            if (!IS_NULL(ret)) {
              (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
            }
        }
        break;
      }
      free(ifRowP);
    }
    return ret;
  }
}

/*
 * Class:       java_net_NetworkInterface
 * Method:      getMTU0
 * Signature:   ([bLjava/lang/String;I)I
 */
JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0
    (JNIEnv *env, jclass class, jstring name, jint index) {
  jint ret = -1;
  MIB_IFROW *ifRowP;

  // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
  if (ipv6_available()) {
    return Java_java_net_NetworkInterface_getMTU0_XP(env, class, name, index);
  } else {
    ifRowP = getIF(index);
    if (ifRowP != NULL) {
      ret = ifRowP->dwMtu;
      free(ifRowP);
    }
    return ret;
  }
}
