/*
 * 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 <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef MACOSX
#include <ifaddrs.h>
#include <net/if.h>
#include <unistd.h> /* gethostname */
#endif

#include "jvm.h"
#include "jni_util.h"
#include "net_util.h"
#ifndef IPV6_DEFS_H
#include <netinet/icmp6.h>
#endif

#include "java_net_Inet4AddressImpl.h"
#include "java_net_Inet6AddressImpl.h"

/* the initial size of our hostent buffers */
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif


/************************************************************************
 * Inet6AddressImpl
 */

/*
 * Class:     java_net_Inet6AddressImpl
 * Method:    getLocalHostName
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL
Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
    char hostname[NI_MAXHOST+1];

    hostname[0] = '\0';
    if (JVM_GetHostName(hostname, sizeof(hostname))) {
        /* Something went wrong, maybe networking is not setup? */
        strcpy(hostname, "localhost");
    } else {
        // ensure null-terminated
        hostname[NI_MAXHOST] = '\0';
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
        /* On Linux/FreeBSD gethostname() says "host.domain.sun.com".  On
         * Solaris gethostname() says "host", so extra work is needed.
         */
#else
        /* Solaris doesn't want to give us a fully qualified domain name.
         * We do a reverse lookup to try and get one.  This works
         * if DNS occurs before NIS in /etc/resolv.conf, but fails
         * if NIS comes first (it still gets only a partial name).
         * We use thread-safe system calls.
         */
#ifdef AF_INET6
        struct addrinfo  hints, *res;
        int error;

        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = AI_CANONNAME;
        hints.ai_family = AF_UNSPEC;

        error = getaddrinfo(hostname, NULL, &hints, &res);

        if (error == 0) {
            /* host is known to name service */
            error = getnameinfo(res->ai_addr,
                                res->ai_addrlen,
                                hostname,
                                NI_MAXHOST,
                                NULL,
                                0,
                                NI_NAMEREQD);

            /* if getnameinfo fails hostname is still the value
               from gethostname */

            freeaddrinfo(res);
        }
#endif /* AF_INET6 */
#endif /* __linux__ || _ALLBSD_SOURCE */
    }
    return (*env)->NewStringUTF(env, hostname);
}

static jclass ni_iacls;
static jclass ni_ia4cls;
static jclass ni_ia6cls;
static jmethodID ni_ia4ctrID;
static jmethodID ni_ia6ctrID;
static jboolean preferIPv6Address;

static jboolean initializeInetClasses(JNIEnv *env)
{
    jfieldID ni_preferIPv6AddressID;
    static int initialized = 0;
    if (!initialized) {
        ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
        CHECK_NULL_RETURN(ni_iacls, JNI_FALSE);
        ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
        CHECK_NULL_RETURN(ni_iacls, JNI_FALSE);
        ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
        CHECK_NULL_RETURN(ni_ia4cls, JNI_FALSE);
        ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
        CHECK_NULL_RETURN(ni_ia4cls, JNI_FALSE);
        ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
        CHECK_NULL_RETURN(ni_ia6cls, JNI_FALSE);
        ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
        CHECK_NULL_RETURN(ni_ia6cls, JNI_FALSE);
        ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
        CHECK_NULL_RETURN(ni_ia4ctrID, JNI_FALSE);
        ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
        CHECK_NULL_RETURN(ni_ia6ctrID, JNI_FALSE);
        ni_preferIPv6AddressID =
            (*env)->GetStaticFieldID(env, ni_iacls, "preferIPv6Address", "Z");
        CHECK_NULL_RETURN(ni_preferIPv6AddressID, JNI_FALSE);
        preferIPv6Address =
            (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
        initialized = 1;
    }
    return JNI_TRUE;
}

#ifdef MACOSX
/* also called from Inet4AddressImpl.c */
__private_extern__ jobjectArray
lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6)
{
    jobjectArray result = NULL;
    char myhostname[NI_MAXHOST+1];
    struct ifaddrs *ifa = NULL;
    int familyOrder = 0;
    int count = 0, i, j;
    int addrs4 = 0, addrs6 = 0, numV4Loopbacks = 0, numV6Loopbacks = 0;
    jboolean includeLoopback = JNI_FALSE;
    jobject name;

    // Make sure static variables we need are set.
    if (!initializeInetClasses(env))
        return NULL;

    /* If the requested name matches this host's hostname, return IP addresses
     * from all attached interfaces. (#2844683 et al) This prevents undesired
     * PPP dialup, but may return addresses that don't actually correspond to
     * the name (if the name actually matches something in DNS etc.
     */
    myhostname[0] = '\0';
    if (JVM_GetHostName(myhostname, NI_MAXHOST)) {
        /* Something went wrong, maybe networking is not setup? */
        return NULL;
    }
    myhostname[NI_MAXHOST] = '\0';

    if (strcmp(myhostname, hostname) != 0) {
        // Non-self lookup
        return NULL;
    }

    if (getifaddrs(&ifa) != 0) {
        NET_ThrowNew(env, errno, "Can't get local interface addresses");
        return NULL;
    }

    name = (*env)->NewStringUTF(env, hostname);
    if (name == NULL) {
        freeifaddrs(ifa);
        return NULL;
    }

    /* Iterate over the interfaces, and total up the number of IPv4 and IPv6
     * addresses we have. Also keep a count of loopback addresses. We need to
     * exclude them in the normal case, but return them if we don't get an IP
     * address.
     */
    struct ifaddrs *iter = ifa;
    while (iter) {
        int family = iter->ifa_addr->sa_family;
        if (iter->ifa_name[0] != '\0'  &&  iter->ifa_addr)
        {
            jboolean isLoopback = iter->ifa_flags & IFF_LOOPBACK;
            if (family == AF_INET) {
                addrs4++;
                if (isLoopback) numV4Loopbacks++;
            } else if (family == AF_INET6 && includeV6) {
                addrs6++;
                if (isLoopback) numV6Loopbacks++;
            } else {
                /* We don't care e.g. AF_LINK */
            }
        }
        iter = iter->ifa_next;
    }

    if (addrs4 == numV4Loopbacks && addrs6 == numV6Loopbacks) {
        // We don't have a real IP address, just loopback. We need to include
        // loopback in our results.
        includeLoopback = JNI_TRUE;
    }

    /* Create and fill the Java array. */
    int arraySize = addrs4 + addrs6 -
        (includeLoopback ? 0 : (numV4Loopbacks + numV6Loopbacks));
    result = (*env)->NewObjectArray(env, arraySize, ni_iacls, NULL);
    if (!result) goto done;

    if (preferIPv6Address) {
        i = includeLoopback ? addrs6 : (addrs6 - numV6Loopbacks);
        j = 0;
    } else {
        i = 0;
        j = includeLoopback ? addrs4 : (addrs4 - numV4Loopbacks);
    }

    // Now loop around the ifaddrs
    iter = ifa;
    while (iter != NULL) {
        jboolean isLoopback = iter->ifa_flags & IFF_LOOPBACK;
        int family = iter->ifa_addr->sa_family;

        if (iter->ifa_name[0] != '\0'  &&  iter->ifa_addr
            && (family == AF_INET || (family == AF_INET6 && includeV6))
            && (!isLoopback || includeLoopback))
        {
            int port;
            int index = (family == AF_INET) ? i++ : j++;
            jobject o = NET_SockaddrToInetAddress(env, iter->ifa_addr, &port);
            if (!o) {
                freeifaddrs(ifa);
                if (!(*env)->ExceptionCheck(env))
                    JNU_ThrowOutOfMemoryError(env, "Object allocation failed");
                return NULL;
            }
            setInetAddress_hostName(env, o, name);
            (*env)->SetObjectArrayElement(env, result, index, o);
            (*env)->DeleteLocalRef(env, o);
        }
        iter = iter->ifa_next;
    }

  done:
    freeifaddrs(ifa);

    return result;
}
#endif

/*
 * Find an internet address for a given hostname.  Note that this
 * code only works for addresses of type INET. The translation
 * of %d.%d.%d.%d to an address (int) occurs in java now, so the
 * String "host" shouldn't *ever* be a %d.%d.%d.%d string
 *
 * Class:     java_net_Inet6AddressImpl
 * Method:    lookupAllHostAddr
 * Signature: (Ljava/lang/String;)[[B
 */

JNIEXPORT jobjectArray JNICALL
Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
                                                jstring host) {
    const char *hostname;
    jobjectArray ret = 0;
    int retLen = 0;

    int getaddrinfo_error=0;
#ifdef AF_INET6
    struct addrinfo hints, *res, *resNew = NULL;
#endif /* AF_INET6 */

    if (!initializeInetClasses(env))
        return NULL;

    if (IS_NULL(host)) {
        JNU_ThrowNullPointerException(env, "host is null");
        return 0;
    }
    hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
    CHECK_NULL_RETURN(hostname, NULL);

#ifdef AF_INET6
    /* Try once, with our static buffer. */
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_CANONNAME;
    hints.ai_family = AF_UNSPEC;

#ifdef __solaris__
    /*
     * Workaround for Solaris bug 4160367 - if a hostname contains a
     * white space then 0.0.0.0 is returned
     */
    if (isspace((unsigned char)hostname[0])) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
                        hostname);
        JNU_ReleaseStringPlatformChars(env, host, hostname);
        return NULL;
    }
#endif

    getaddrinfo_error = getaddrinfo(hostname, NULL, &hints, &res);

#ifdef MACOSX
    if (getaddrinfo_error) {
        /*
         * If getaddrinfo fails looking up the local machine, attempt to get the
         * address from getifaddrs. This ensures we get an IPv6 address for the
         * local machine.
         */
        ret = lookupIfLocalhost(env, hostname, JNI_TRUE);
        if (ret != NULL || (*env)->ExceptionCheck(env)) {
            JNU_ReleaseStringPlatformChars(env, host, hostname);
            return ret;
        }
    }
#endif

    if (getaddrinfo_error) {
        /* report error */
        ThrowUnknownHostExceptionWithGaiError(
            env, hostname, getaddrinfo_error);
        JNU_ReleaseStringPlatformChars(env, host, hostname);
        return NULL;
    } else {
        int i = 0;
        int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
        struct addrinfo *itr, *last = NULL, *iterator = res;
        while (iterator != NULL) {
            int skip = 0;
            itr = resNew;
            while (itr != NULL) {
                if (iterator->ai_family == itr->ai_family &&
                    iterator->ai_addrlen == itr->ai_addrlen) {
                    if (itr->ai_family == AF_INET) { /* AF_INET */
                        struct sockaddr_in *addr1, *addr2;
                        addr1 = (struct sockaddr_in *)iterator->ai_addr;
                        addr2 = (struct sockaddr_in *)itr->ai_addr;
                        if (addr1->sin_addr.s_addr ==
                            addr2->sin_addr.s_addr) {
                            skip = 1;
                            break;
                        }
                    } else {
                        int t;
                        struct sockaddr_in6 *addr1, *addr2;
                        addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
                        addr2 = (struct sockaddr_in6 *)itr->ai_addr;

                        for (t = 0; t < 16; t++) {
                            if (addr1->sin6_addr.s6_addr[t] !=
                                addr2->sin6_addr.s6_addr[t]) {
                                break;
                            }
                        }
                        if (t < 16) {
                            itr = itr->ai_next;
                            continue;
                        } else {
                            skip = 1;
                            break;
                        }
                    }
                } else if (iterator->ai_family != AF_INET &&
                           iterator->ai_family != AF_INET6) {
                    /* we can't handle other family types */
                    skip = 1;
                    break;
                }
                itr = itr->ai_next;
            }

            if (!skip) {
                struct addrinfo *next
                    = (struct addrinfo*) malloc(sizeof(struct addrinfo));
                if (!next) {
                    JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
                    ret = NULL;
                    goto cleanupAndReturn;
                }
                memcpy(next, iterator, sizeof(struct addrinfo));
                next->ai_next = NULL;
                if (resNew == NULL) {
                    resNew = next;
                } else {
                    last->ai_next = next;
                }
                last = next;
                i++;
                if (iterator->ai_family == AF_INET) {
                    inetCount ++;
                } else if (iterator->ai_family == AF_INET6) {
                    inet6Count ++;
                }
            }
            iterator = iterator->ai_next;
        }
        retLen = i;
        iterator = resNew;

        ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);

        if (IS_NULL(ret)) {
            /* we may have memory to free at the end of this */
            goto cleanupAndReturn;
        }

        if (preferIPv6Address) {
            /* AF_INET addresses will be offset by inet6Count */
            inetIndex = inet6Count;
            inet6Index = 0;
        } else {
            /* AF_INET6 addresses will be offset by inetCount */
            inetIndex = 0;
            inet6Index = inetCount;
        }

        while (iterator != NULL) {
            int ret1;
            if (iterator->ai_family == AF_INET) {
                jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
                if (IS_NULL(iaObj)) {
                    ret = NULL;
                    goto cleanupAndReturn;
                }
                setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
                setInetAddress_hostName(env, iaObj, host);
                (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
                inetIndex++;
            } else if (iterator->ai_family == AF_INET6) {
                jint scope = 0;

                jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
                if (IS_NULL(iaObj)) {
                    ret = NULL;
                    goto cleanupAndReturn;
                }
                ret1 = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
                if (!ret1) {
                    ret = NULL;
                    goto cleanupAndReturn;
                }

                scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
                if (scope != 0) { /* zero is default value, no need to set */
                    setInet6Address_scopeid(env, iaObj, scope);
                }
                setInetAddress_hostName(env, iaObj, host);
                (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
                inet6Index++;
            }
            iterator = iterator->ai_next;
        }
    }

 cleanupAndReturn:
    {
      struct addrinfo *iterator, *tmp;
        iterator = resNew;
        while (iterator != NULL) {
            tmp = iterator;
            iterator = iterator->ai_next;
            free(tmp);
        }
        JNU_ReleaseStringPlatformChars(env, host, hostname);
    }

    freeaddrinfo(res);
#endif /* AF_INET6 */

    return ret;
}

/*
 * Class:     java_net_Inet6AddressImpl
 * Method:    getHostByAddr
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL
Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
                                            jbyteArray addrArray) {

    jstring ret = NULL;

#ifdef AF_INET6
    char host[NI_MAXHOST+1];
    int error = 0;
    int len = 0;
    jbyte caddr[16];

    struct sockaddr_in him4;
    struct sockaddr_in6 him6;
    struct sockaddr *sa;

    /*
     * For IPv4 addresses construct a sockaddr_in structure.
     */
    if ((*env)->GetArrayLength(env, addrArray) == 4) {
        jint addr;
        (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
        addr = ((caddr[0]<<24) & 0xff000000);
        addr |= ((caddr[1] <<16) & 0xff0000);
        addr |= ((caddr[2] <<8) & 0xff00);
        addr |= (caddr[3] & 0xff);
        memset((void *) &him4, 0, sizeof(him4));
        him4.sin_addr.s_addr = (uint32_t) htonl(addr);
        him4.sin_family = AF_INET;
        sa = (struct sockaddr *) &him4;
        len = sizeof(him4);
    } else {
        /*
         * For IPv6 address construct a sockaddr_in6 structure.
         */
        (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
        memset((void *) &him6, 0, sizeof(him6));
        memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
        him6.sin6_family = AF_INET6;
        sa = (struct sockaddr *) &him6 ;
        len = sizeof(him6) ;
    }

    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
                        NI_NAMEREQD);

    if (!error) {
        ret = (*env)->NewStringUTF(env, host);
    }
#endif /* AF_INET6 */

    if (ret == NULL) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
    }

    return ret;
}

#define SET_NONBLOCKING(fd) {           \
        int flags = fcntl(fd, F_GETFL); \
        flags |= O_NONBLOCK;            \
        fcntl(fd, F_SETFL, flags);      \
}

#ifdef AF_INET6
static jboolean
ping6(JNIEnv *env, jint fd, struct sockaddr_in6* him, jint timeout,
      struct sockaddr_in6* netif, jint ttl) {
    jint size;
    jint n;
    socklen_t len;
    char sendbuf[1500];
    unsigned char recvbuf[1500];
    struct icmp6_hdr *icmp6;
    struct sockaddr_in6 sa_recv;
    jbyte *caddr, *recv_caddr;
    jchar pid;
    jint tmout2, seq = 1;
    struct timeval tv;
    size_t plen;

#ifdef __linux__
    {
    int csum_offset;
    /**
     * For some strange reason, the linux kernel won't calculate the
     * checksum of ICMPv6 packets unless you set this socket option
     */
    csum_offset = 2;
    setsockopt(fd, SOL_RAW, IPV6_CHECKSUM, &csum_offset, sizeof(int));
    }
#endif

    caddr = (jbyte *)&(him->sin6_addr);

    /* icmp_id is a 16 bit data type, therefore down cast the pid */
    pid = (jchar)getpid();
    size = 60*1024;
    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
    if (ttl > 0) {
      setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
    }
    if (netif != NULL) {
      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) <0) {
        NET_ThrowNew(env, errno, "Can't bind socket");
        close(fd);
        return JNI_FALSE;
      }
    }
    SET_NONBLOCKING(fd);

    do {
      icmp6 = (struct icmp6_hdr *) sendbuf;
      icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
      icmp6->icmp6_code = 0;
      /* let's tag the ECHO packet with our pid so we can identify it */
      icmp6->icmp6_id = htons(pid);
      icmp6->icmp6_seq = htons(seq);
      seq++;
      icmp6->icmp6_cksum = 0;
      gettimeofday(&tv, NULL);
      memcpy(sendbuf + sizeof(struct icmp6_hdr), &tv, sizeof(tv));
      plen = sizeof(struct icmp6_hdr) + sizeof(tv);
      n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6));
      if (n < 0 && errno != EINPROGRESS) {
#ifdef __linux__
        if (errno != EINVAL && errno != EHOSTUNREACH)
          /*
           * On some Linux versions, when a socket is  bound to the
           * loopback interface, sendto will fail and errno will be
           * set to EINVAL or EHOSTUNREACH.
           * When that happens, don't throw an exception, just return false.
           */
#endif /*__linux__ */
        NET_ThrowNew(env, errno, "Can't send ICMP packet");
        close(fd);
        return JNI_FALSE;
      }

      tmout2 = timeout > 1000 ? 1000 : timeout;
      do {
        tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);

        if (tmout2 >= 0) {
          len = sizeof(sa_recv);
          n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &sa_recv, &len);
          icmp6 = (struct icmp6_hdr *) (recvbuf);
          recv_caddr = (jbyte *)&(sa_recv.sin6_addr);
          /*
           * We did receive something, but is it what we were expecting?
           * I.E.: An ICMP6_ECHO_REPLY packet with the proper PID and
           *       from the host that we are trying to determine is reachable.
           */
          if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY &&
              (ntohs(icmp6->icmp6_id) == pid)) {
            if (NET_IsEqual(caddr, recv_caddr)) {
              close(fd);
              return JNI_TRUE;
            }
            if (NET_IsZeroAddr(caddr)) {
              close(fd);
              return JNI_TRUE;
            }
          }
        }
      } while (tmout2 > 0);
      timeout -= 1000;
    } while (timeout > 0);
    close(fd);
    return JNI_FALSE;
}
#endif /* AF_INET6 */

/*
 * Class:     java_net_Inet6AddressImpl
 * Method:    isReachable0
 * Signature: ([bII[bI)Z
 */
JNIEXPORT jboolean JNICALL
Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
                                           jbyteArray addrArray,
                                           jint scope,
                                           jint timeout,
                                           jbyteArray ifArray,
                                           jint ttl, jint if_scope) {
#ifdef AF_INET6
    jbyte caddr[16];
    jint fd, sz;
    struct sockaddr_in6 him6;
    struct sockaddr_in6 inf6;
    struct sockaddr_in6* netif = NULL;
    int len = 0;
    int connect_rv = -1;

    /*
     * If IPv6 is not enable, then we can't reach an IPv6 address, can we?
     */
    if (!ipv6_available()) {
      return JNI_FALSE;
    }
    /*
     * If it's an IPv4 address, ICMP won't work with IPv4 mapped address,
     * therefore, let's delegate to the Inet4Address method.
     */
    sz = (*env)->GetArrayLength(env, addrArray);
    if (sz == 4) {
      return Java_java_net_Inet4AddressImpl_isReachable0(env, this,
                                                         addrArray,
                                                         timeout,
                                                         ifArray, ttl);
    }

    memset((void *) caddr, 0, 16);
    memset((void *) &him6, 0, sizeof(him6));
    (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
    memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
    him6.sin6_family = AF_INET6;
#ifdef __linux__
    if (scope > 0)
      him6.sin6_scope_id = scope;
    else
      him6.sin6_scope_id = getDefaultIPv6Interface( &(him6.sin6_addr));
    len = sizeof(struct sockaddr_in6);
#else
    if (scope > 0)
      him6.sin6_scope_id = scope;
    len = sizeof(struct sockaddr_in6);
#endif
    /*
     * If a network interface was specified, let's create the address
     * for it.
     */
    if (!(IS_NULL(ifArray))) {
      memset((void *) caddr, 0, 16);
      memset((void *) &inf6, 0, sizeof(inf6));
      (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
      memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
      inf6.sin6_family = AF_INET6;
      inf6.sin6_scope_id = if_scope;
      netif = &inf6;
    }
    /*
     * If we can create a RAW socket, then when can use the ICMP ECHO_REQUEST
     * otherwise we'll try a tcp socket to the Echo port (7).
     * Note that this is empiric, and not connecting could mean it's blocked
     * or the echo service has been disabled.
     */

    fd = JVM_Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);

    if (fd != -1) { /* Good to go, let's do a ping */
        return ping6(env, fd, &him6, timeout, netif, ttl);
    }

    /* No good, let's fall back on TCP */
    fd = JVM_Socket(AF_INET6, SOCK_STREAM, 0);
    if (fd == JVM_IO_ERR) {
        /* note: if you run out of fds, you may not be able to load
         * the exception class, and get a NoClassDefFoundError
         * instead.
         */
        NET_ThrowNew(env, errno, "Can't create socket");
        return JNI_FALSE;
    }
    if (ttl > 0) {
      setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
    }

    /*
     * A network interface was specified, so let's bind to it.
     */
    if (netif != NULL) {
      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) <0) {
        NET_ThrowNew(env, errno, "Can't bind socket");
        close(fd);
        return JNI_FALSE;
      }
    }
    SET_NONBLOCKING(fd);

    /* no need to use NET_Connect as non-blocking */
    him6.sin6_port = htons((short) 7); /* Echo port */
    connect_rv = JVM_Connect(fd, (struct sockaddr *)&him6, len);

    /**
     * connection established or refused immediately, either way it means
     * we were able to reach the host!
     */
    if (connect_rv == 0 || errno == ECONNREFUSED) {
        close(fd);
        return JNI_TRUE;
    } else {
        int optlen;

        switch (errno) {
        case ENETUNREACH: /* Network Unreachable */
        case EAFNOSUPPORT: /* Address Family not supported */
        case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
#ifdef __linux__
        case EINVAL:
        case EHOSTUNREACH:
          /*
           * On some Linux versions, when  a socket is bound to the
           * loopback interface, connect will fail and errno will
           * be set to EINVAL or EHOSTUNREACH.  When that happens,
           * don't throw an exception, just return false.
           */
#endif /* __linux__ */
          close(fd);
          return JNI_FALSE;
        }

        if (errno != EINPROGRESS) {
            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
                                         "connect failed");
            close(fd);
            return JNI_FALSE;
        }

        timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);

        if (timeout >= 0) {
          /* has connection been established */
          optlen = sizeof(connect_rv);
          if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
                             &optlen) <0) {
            connect_rv = errno;
          }
          if (connect_rv == 0 || ECONNREFUSED) {
            close(fd);
            return JNI_TRUE;
          }
        }
        close(fd);
        return JNI_FALSE;
    }
#else /* AF_INET6 */
    return JNI_FALSE;
#endif /* AF_INET6 */
}
