/*
 * Copyright (c) 2000, 2013, 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_iacls;            /* InetAddress */

jclass ni_ia4cls;           /* Inet4Address */
jmethodID ni_ia4Ctor;       /* Inet4Address() */

jclass ni_ia6cls;           /* Inet6Address */
jmethodID ni_ia6ctrID;      /* Inet6Address() */

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);
                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_iacls = (*env)->FindClass(env, "java/net/InetAddress");
    CHECK_NULL(ni_iacls);
    ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
    CHECK_NULL(ni_iacls);

    ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
    CHECK_NULL(ni_ia4cls);
    ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
    CHECK_NULL(ni_ia4cls);
    ni_ia4Ctor = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
    CHECK_NULL(ni_ia4Ctor);

    ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
    CHECK_NULL(ni_ia6cls);
    ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
    CHECK_NULL(ni_ia6cls);
    ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
    CHECK_NULL(ni_ia6ctrID);

    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");
}

/*
 * 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, ni_iacls, 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, ni_ia4cls, ni_ia4Ctor);
            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 (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, ni_ia4cls, ni_ia4Ctor);
              if (ia2Obj == NULL) {
                free_netaddr(netaddrP);
                return NULL;
              }
              setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
              (*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, ni_ia6cls, ni_ia6ctrID);
            if (iaObj) {
                int ret = setInet6Address_ipaddress(env, iaObj,  (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
                if (ret == JNI_FALSE) {
                    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;
    jint addr = getInetAddress_addr(env, iaObj);
    jobject netifObj = 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;
  }
}
