/*
 * Copyright (c) 2003, 2015, 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 <limits.h>

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

#include "NetworkInterface.h"
#include "net_util.h"

/*
 * Windows implementation of the java.net.NetworkInterface native methods.
 * This module provides the implementations of getAll, getByName, getByIndex,
 * and getByAddress.
 */

extern int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP);
int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);

#ifdef DEBUG
void printnif (netif *nif) {
#ifdef _WIN64
        printf ("nif:0x%I64x name:%s\n", nif,nif->name);
#else
        printf ("nif:0x%x name:%s\n", nif,nif->name);
#endif
        if (nif->dNameIsUnicode) {
            printf ("dName:%S index:%d ", nif->displayName,nif->index);
        } else {
            printf ("dName:%s index:%d ", nif->displayName,nif->index);
        }
        printf ("naddrs:%d\n", nif->naddrs);
}

void printnifs (netif *netifPP, char *str) {
    netif *nif;
    printf ("%s\n", str);
    for (nif=netifPP; nif!=NULL; nif=nif->next) {
        printnif (nif);
    }
    printf("-----------------\n");
}

#endif

static int bufsize = 4096;

/*
 * return an array of IP_ADAPTER_ADDRESSES containing one element
 * for each adapter on the system. Returned in *adapters.
 * Buffer is malloc'd and must be freed (unless error returned)
 */
static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) {
    DWORD ret, flags;
    IP_ADAPTER_ADDRESSES *adapterInfo;
    ULONG len;
    adapterInfo = (IP_ADAPTER_ADDRESSES *)malloc (bufsize);
    if (adapterInfo == NULL) {
        JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
        return -1;
    }

    len = bufsize;
    flags = GAA_FLAG_SKIP_DNS_SERVER;
    flags |= GAA_FLAG_SKIP_MULTICAST;
    flags |= GAA_FLAG_INCLUDE_PREFIX;
    ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);

    if (ret == ERROR_BUFFER_OVERFLOW) {
        IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
        if (len  < (ULONG_MAX - bufsize)) {
            len = len + bufsize;
        }
        newAdapterInfo =
                (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
        if (newAdapterInfo == NULL) {
            free(adapterInfo);
            JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
            return -1;
        }

        adapterInfo = newAdapterInfo;

        ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
    }

    if (ret != ERROR_SUCCESS) {
        free (adapterInfo);
        JNU_ThrowByName(env, "java/lang/Error",
                "IP Helper Library GetAdaptersAddresses function failed");
        return -1;
    }
    *adapters = adapterInfo;
    return ERROR_SUCCESS;
}

/*
 * return an array of IP_ADAPTER_ADDRESSES containing one element
 * for each adapter on the system. Returned in *adapters.
 * Buffer is malloc'd and must be freed (unless error returned)
 */
IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env,  jint index) {
    DWORD flags, val;
    IP_ADAPTER_ADDRESSES *adapterInfo, *ptr, *ret;
    ULONG len;
    adapterInfo = (IP_ADAPTER_ADDRESSES *)malloc (bufsize);
    if (adapterInfo == NULL) {
        JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
        return NULL;
    }
    len = bufsize;
    flags = GAA_FLAG_SKIP_DNS_SERVER;
    flags |= GAA_FLAG_SKIP_MULTICAST;
    flags |= GAA_FLAG_INCLUDE_PREFIX;
    val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
    if (val == ERROR_BUFFER_OVERFLOW) {
        IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
        if (len  < (ULONG_MAX - bufsize)) {
            len = len + bufsize;
        }
        newAdapterInfo =
                (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
        if (newAdapterInfo == NULL) {
            free(adapterInfo);
            JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
            return NULL;
        }

        adapterInfo = newAdapterInfo;

        val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
    }

    if (val != ERROR_SUCCESS) {
        free (adapterInfo);
        JNU_ThrowByName(env, "java/lang/Error",
                "IP Helper Library GetAdaptersAddresses function failed");
        return NULL;
    }
    ptr = adapterInfo;
    ret = NULL;
    while (ptr != NULL) {
      // in theory the IPv4 index and the IPv6 index can be the same
      // where an interface is enabled for v4 and v6
      // IfIndex == 0 IPv4 not available on this interface
      // Ipv6IfIndex == 0 IPv6 not available on this interface
      if (((ptr->IfIndex != 0)&&(ptr->IfIndex == index)) ||
          ((ptr->Ipv6IfIndex !=0) && (ptr->Ipv6IfIndex == index))) {
        ret = (IP_ADAPTER_ADDRESSES *) malloc(sizeof(IP_ADAPTER_ADDRESSES));
        if (ret == NULL) {
            free(adapterInfo);
            JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
            return NULL;
        }

        //copy the memory and break out of the while loop.
        memcpy(ret, ptr, sizeof(IP_ADAPTER_ADDRESSES));
        break;

      }
      ptr=ptr->Next;
    }
    free(adapterInfo);
    return ret;
}

static int ipinflen = 2048;

/*
 */
int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
{
    DWORD ret;
    IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
    ULONG len=ipinflen, count=0;
    netif *nif=NULL, *dup_nif, *last=NULL, *loopif=NULL, *curr;
    int tun=0, net=0;

    *netifPP = NULL;
   /*
    * Get the IPv4 interfaces. This information is the same
    * as what previous JDK versions would return.
    */

    ret = enumInterfaces(env, netifPP);
    if (ret == -1) {
        return -1;
    } else {
        count = ret;
    }

    /* locate the loopback (and the last) interface */
    for (nif=*netifPP, last=nif; nif!=NULL; nif=nif->next) {
        if (nif->ifType == MIB_IF_TYPE_LOOPBACK) {
            loopif = nif;
        }
        last = nif;
    }

    // Retrieve IPv4 addresses with the IP Helper API
    curr = *netifPP;
    while (curr != NULL) {
        netaddr *netaddrP;
        ret = enumAddresses_win(env, curr, &netaddrP);
        if (ret == -1) {
            return -1;
        }
        curr->addrs = netaddrP;
        curr->naddrs += ret;
        curr = curr->next;
    }

    ret = getAdapters (env, &adapters);
    if (ret != ERROR_SUCCESS) {
        goto err;
    }

    /* Now get the IPv6 information. This includes:
     *  (a)  IPv6 information associated with interfaces already found
     *  (b)  IPv6 information for IPv6 only interfaces (probably tunnels)
     *
     * For compatibility with previous releases we use the naming
     * information gotten from enumInterfaces() for (a) entries
     * However, the index numbers are taken from the new API.
     *
     * The procedure is to go through the list of adapters returned
     * by the new API looking for entries that correspond to IPv4 interfaces
     * already found.
     */

    ptr = adapters;
    while (ptr != NULL) {
        int c;
        netif *nif0;
        if (ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK && (loopif != NULL)) {
            c = getAddrsFromAdapter(ptr, &loopif->addrs);
            if (c == -1) {
                goto err;
            }
            loopif->naddrs += c;
        } else {
            int index = ptr->IfIndex;
            if (index != 0) {
                /* This entry is associated with an IPv4 interface */
                for (nif=*netifPP; nif!=NULL; nif=nif->next) {
                    if (nif->index == index) {
                        /* found the interface entry
                         * set the index to the IPv6 index and add the
                         * IPv6 addresses
                         */
                        nif->ipv6Index = ptr->Ipv6IfIndex;
                        c = getAddrsFromAdapter(ptr, &nif->addrs);
                        nif->naddrs += c;
                        break;
                    }
                }
            } else {
                /* This entry is IPv6 only */
                char newname [128];
                int c;

                /* Windows allocates duplicate adapter entries
                 * for tunnel interfaces when there are multiple
                 * physical adapters. Need to check
                 * if this is a duplicate (ipv6Index is the same)
                 */
                dup_nif = 0;
                for (nif0=*netifPP; nif0!=NULL; nif0=nif0->next) {
                    if (nif0->hasIpv6Address &&
                                ptr->Ipv6IfIndex == nif0->ipv6Index) {
                        dup_nif = nif0;
                        break;
                    }
                }
                if (dup_nif == 0) {
                    /* new interface */
                        nif = (netif *) calloc (1, sizeof(netif));
                        if (nif == 0) {
                            goto err;
                        }
                        if (ptr->IfType == IF_TYPE_TUNNEL) {
                                sprintf (newname, "tun%d", tun);
                                tun ++;
                        } else {
                                sprintf (newname, "net%d", net);
                                net ++;
                        }
                        nif->name = malloc (strlen(newname)+1);
                        nif->displayName = malloc (wcslen(ptr->FriendlyName)*2+2);
                        if (nif->name == 0 || nif->displayName == 0) {
                                goto err;
                        }
                        strcpy (nif->name, newname);
                        wcscpy ((PWCHAR)nif->displayName, ptr->FriendlyName);
                        nif->dNameIsUnicode = TRUE;

                        // the java.net.NetworkInterface abstraction only has index
                        // so the Ipv6IfIndex needs to map onto index
                        nif->index = ptr->Ipv6IfIndex;
                        nif->ipv6Index = ptr->Ipv6IfIndex;
                        nif->hasIpv6Address = TRUE;

                        last->next = nif;
                        last = nif;
                        count++;
                        c = getAddrsFromAdapter(ptr, &nif->addrs);
                        if (c == -1) {
                                goto err;
                        }
                        nif->naddrs += c;
                 } else {
                        /* add the addresses from this adapter to the
                         * original (dup_nif)
                         */
                        c = getAddrsFromAdapter(ptr, &dup_nif->addrs);
                        if (c == -1) {
                                goto err;
                        }
                        dup_nif->naddrs += c;
                }
            }
        }
        ptr=ptr->Next;
    }

    free (adapters);
    return count;

err:
    if (*netifPP) {
        free_netif (*netifPP);
    }
    if (adapters) {
        free (adapters);
    }
    return -1;
}

/* If *netaddrPP is null, then the addresses are allocated and the beginning
 * of the allocated chain is returned in *netaddrPP.
 * If *netaddrPP is not null, then the addresses allocated here are appended
 * to the existing chain.
 *
 * Returns count of addresses or -1 on error.
 */

static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP) {
        LPSOCKADDR sock;
        int        count = 0;
        netaddr    *curr, *start = NULL, *prev = NULL;
        PIP_ADAPTER_UNICAST_ADDRESS uni_addr;
        PIP_ADAPTER_ANYCAST_ADDRESS any_addr;
        PIP_ADAPTER_PREFIX prefix;

        /* If chain passed in, find end */
        if (*netaddrPP != NULL) {
            for (start=*netaddrPP; start->next!=NULL; start=start->next)
                ;

            prev=start;
        }

        prefix = ptr->FirstPrefix;
        /* Unicast */
        uni_addr = ptr->FirstUnicastAddress;
        while (uni_addr != NULL) {
        /* address is only usable if dad state is preferred or deprecated */
                if (uni_addr->DadState == IpDadStateDeprecated ||
                                uni_addr->DadState == IpDadStatePreferred) {
                        sock = uni_addr->Address.lpSockaddr;

                        // IPv4 addresses already retrieved with enumAddresses_win
                        if (sock->sa_family == AF_INET) {
                                uni_addr = uni_addr->Next;
                                continue;
                        }

            curr = (netaddr *)calloc (1, sizeof (netaddr));

            if (curr == NULL)
                goto freeAllocatedMemory;

            if (start == NULL)
                start = curr;

            if (prev != NULL)
               prev->next = curr;

            prev = curr;
            SOCKETADDRESS_COPY (&curr->addr, sock);
            if (prefix != NULL) {
              curr->mask = (short)prefix->PrefixLength;
              prefix = prefix->Next;
            }
            count ++;
        }
        uni_addr = uni_addr->Next;
    }
    /* Anycast */
    any_addr = ptr->FirstAnycastAddress;
    while (any_addr != NULL) {
        curr = (netaddr *)calloc (1, sizeof (netaddr));

        if (curr == NULL)
            goto freeAllocatedMemory;

        if (start == NULL)
            start = curr;

        if (prev != NULL)
            prev->next = curr;

        prev = curr;
        sock = any_addr->Address.lpSockaddr;
        SOCKETADDRESS_COPY (&curr->addr, sock);
        count ++;
        any_addr = any_addr->Next;
    }
    if (*netaddrPP == NULL) {
        *netaddrPP = start;
    }
    return count;

freeAllocatedMemory:

    if (*netaddrPP != NULL) {
        //N.B. the variable "start" cannot be NULL at this point because we started with an
        //existing list.
        curr=start->next;
        start->next = NULL;
        start = curr;
    }
    // otherwise, "start" points to the beginning of an incomplete list that we must deallocate.

    while (start != NULL) {
        curr = start->next;
        free(start);
        start = curr;
    }

    return -1;
}

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

    /*
     * Create a NetworkInterface object and populate it
     */
    netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
    name = (*env)->NewStringUTF(env, ifs->name);
    if (ifs->dNameIsUnicode) {
        displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName,
                                        (jsize)wcslen ((PWCHAR)ifs->displayName));
    } else {
        displayName = (*env)->NewStringUTF(env, ifs->displayName);
    }
    if (netifObj == NULL || name == NULL || displayName == NULL) {
        return 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) {
        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) {
                return NULL;
            }
            /* default ctor will set family to AF_INET */

            setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));

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

    /*
     * 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;
}

JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0_XP
    (JNIEnv *env, jclass cls, jstring name)
{
    netif *ifList, *curr;
    jboolean isCopy;
    const char *name_utf;
    jobject netifObj = NULL;

    if (getAllInterfacesAndAddresses (env, &ifList) < 0) {
        return NULL;
    }

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

    /* 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 = createNetworkInterfaceXP(env, curr);
    }

    /* release the UTF string */
    (*env)->ReleaseStringUTFChars(env, name, name_utf);

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

    return netifObj;
}

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

    if (getAllInterfacesAndAddresses (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 = createNetworkInterfaceXP(env, curr);
    }

    /* 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_XP
    (JNIEnv *env, jclass cls, jobject iaObj)
{
    netif *ifList, *curr;
    jobject netifObj = NULL;

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

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

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

        while (addrP != NULL) {
            if (NET_SockaddrEqualsInetAddress(env,
                                (struct sockaddr*)&addrP->addr, iaObj)) {
                break;
            }
            addrP = addrP->next;
        }

        /*
         * Address matched so create NetworkInterface for this interface
         * and address list.
         */
        if (addrP != NULL) {
            netifObj = createNetworkInterfaceXP(env, curr);
            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_XP
    (JNIEnv *env, jclass cls)
{
    int count;
    netif *ifList, *curr;
    jobjectArray netIFArr;
    jint arr_index;

    /*
     * Get list of interfaces
     */
    count = getAllInterfacesAndAddresses (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 = createNetworkInterfaceXP(env, curr);
        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:    supportsMulticast0
 * Signature: (Ljava/lang/String;I)Z
 */
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0_XP
    (JNIEnv *env, jclass cls, jstring name, jint index) {
      IP_ADAPTER_ADDRESSES *ptr;
      jboolean val = JNI_TRUE;

      ptr = getAdapter(env, index);
      if (ptr != NULL) {
        val = ptr->Flags & IP_ADAPTER_NO_MULTICAST ? JNI_FALSE : JNI_TRUE;
        free(ptr);
      }
      return val;
}

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

      ptr = getAdapter(env, index);
      if (ptr != NULL) {
        val = ptr->OperStatus == IfOperStatusUp ? JNI_TRUE : JNI_FALSE;
        free(ptr);
      }
      return val;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    getMacAddr0
 * Signature: (Ljava/lang/String;I)Z
 */
JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0_XP
    (JNIEnv *env, jclass cls, jstring name, jint index) {
      IP_ADAPTER_ADDRESSES *ptr;
      jbyteArray ret = NULL;
      int len;

      ptr = getAdapter(env, index);
      if (ptr != NULL) {
        len = ptr->PhysicalAddressLength;
        if (len > 0) {
          ret = (*env)->NewByteArray(env, len);
          if (!IS_NULL(ret)) {
            (*env)->SetByteArrayRegion(env, ret, 0, len,
                                       (jbyte*) ptr->PhysicalAddress);
          }
        }
        free(ptr);
      }
      return ret;
}

/*
 * Class:       java_net_NetworkInterface
 * Method:      getMTU0
 * Signature:   ([bLjava/lang/String;I)I
 */
JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0_XP
    (JNIEnv *env, jclass cls, jstring name, jint index) {
      IP_ADAPTER_ADDRESSES *ptr;
      jint ret = -1;

      ptr = getAdapter(env, index);
      if (ptr != NULL) {
        ret = ptr->Mtu;
        free(ptr);
      }
      return ret;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    isLoopback0
 * Signature: (Ljava/lang/String;I)Z
 */
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
    (JNIEnv *env, jclass cls, jstring name, jint index) {
      IP_ADAPTER_ADDRESSES *ptr;
      jboolean val = JNI_FALSE;

      ptr = getAdapter(env, index);
      if (ptr != NULL) {
        val = ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK ? JNI_TRUE : JNI_FALSE;
        free(ptr);
      }
      return val;
}

/*
 * Class:     java_net_NetworkInterface
 * Method:    isP2P0
 * Signature: (Ljava/lang/String;I)Z
 */
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0_XP
    (JNIEnv *env, jclass cls, jstring name, jint index) {
      IP_ADAPTER_ADDRESSES *ptr;
      jboolean val = JNI_FALSE;

      ptr = getAdapter(env, index);
      if (ptr != NULL) {
        if (ptr->IfType == IF_TYPE_PPP || ptr->IfType == IF_TYPE_SLIP ||
           ptr->IfType == IF_TYPE_TUNNEL) {
          val = JNI_TRUE;
        }
        free(ptr);
      }
      return val;
}
