Search in sources :

Example 1 with Ifaddrs

use of com.oracle.svm.core.posix.headers.Ifaddrs in project graal by oracle.

the class Util_jni method lookupIfLocalhost.

static InetAddress[] lookupIfLocalhost(CCharPointer hostname, boolean includeV6) throws SocketException, InterruptedException {
    /* #ifdef MACOSX */
    if (IsDefined.MACOSX()) {
        /* also called from Inet4AddressImpl.c */
        InetAddress[] result = null;
        CCharPointer myhostname = StackValue.get(Netdb.NI_MAXHOST() + 1, SizeOf.get(CCharPointer.class));
        Ifaddrs.ifaddrs ifa = WordFactory.nullPointer();
        Ifaddrs.ifaddrsPointer ifaPointer = StackValue.get(SizeOf.get(Ifaddrs.ifaddrsPointer.class));
        int i;
        int j;
        int addrs4 = 0;
        int addrs6 = 0;
        int numV4Loopbacks = 0;
        int numV6Loopbacks = 0;
        boolean includeLoopback = false;
        String name;
        /*
             * 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.write(0, (byte) '\0');
        if (Unistd.gethostname(myhostname, WordFactory.unsigned(Netdb.NI_MAXHOST())) == 0) {
            /* Something went wrong, maybe networking is not setup? */
            return null;
        }
        myhostname.write(Netdb.NI_MAXHOST(), (byte) '\0');
        if (LibC.strcmp(myhostname, hostname) != 0) {
            // Non-self lookup
            return null;
        }
        try {
            if (Ifaddrs.getifaddrs(ifaPointer) != 0) {
                JavaNetNetUtilMD.NET_ThrowNew(Errno.errno(), "Can't get local interface addresses");
                return null;
            }
            ifa = ifaPointer.read();
            name = CTypeConversion.toJavaString(hostname);
            /*
                 * 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.
                 */
            Ifaddrs.ifaddrs iter = ifa;
            while (iter.isNonNull()) {
                int family = iter.ifa_addr().sa_family();
                if ((iter.ifa_name().read(0) != '\0') && iter.ifa_addr().isNonNull()) {
                    boolean isLoopback = ((iter.ifa_flags() & NetIf.IFF_LOOPBACK()) != 0);
                    if (family == Socket.AF_INET()) {
                        addrs4++;
                        if (isLoopback) {
                            numV4Loopbacks++;
                        }
                    } else if ((family == Socket.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 = true;
            }
            /* Create and fill the Java array. */
            int arraySize = addrs4 + addrs6 - (includeLoopback ? 0 : (numV4Loopbacks + numV6Loopbacks));
            result = new InetAddress[arraySize];
            if (Target_java_net_InetAddress.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.isNonNull()) {
                boolean isLoopback = ((iter.ifa_flags() & NetIf.IFF_LOOPBACK()) != 0);
                int family = iter.ifa_addr().sa_family();
                if ((iter.ifa_name().read(0) != '\0') && (iter.ifa_addr().isNonNull()) && ((family == Socket.AF_INET()) || ((family == Socket.AF_INET6() && includeV6))) && ((!isLoopback) || includeLoopback)) {
                    int index = (family == Socket.AF_INET()) ? i++ : j++;
                    // The space pointed to by portPointer is unused here,
                    // but I have to allocate it because it gets written by the call.
                    CIntPointer portPointer = StackValue.get(SizeOf.get(CIntPointer.class));
                    InetAddress o = JavaNetNetUtil.NET_SockaddrToInetAddress(iter.ifa_addr(), portPointer);
                    if (o != null) {
                        throw new OutOfMemoryError("Object allocation failed");
                    }
                    JavaNetNetUtil.setInetAddress_hostName(o, name);
                    result[index] = o;
                }
                iter = iter.ifa_next();
            }
        } finally {
            /* done: */
            Ifaddrs.freeifaddrs(ifa);
        }
        return result;
    // #endif MACOSX
    } else {
        return null;
    }
}
Also used : CIntPointer(org.graalvm.nativeimage.c.type.CIntPointer) InetAddress(java.net.InetAddress) CCharPointer(org.graalvm.nativeimage.c.type.CCharPointer) Ifaddrs(com.oracle.svm.core.posix.headers.Ifaddrs)

Aggregations

Ifaddrs (com.oracle.svm.core.posix.headers.Ifaddrs)1 InetAddress (java.net.InetAddress)1 CCharPointer (org.graalvm.nativeimage.c.type.CCharPointer)1 CIntPointer (org.graalvm.nativeimage.c.type.CIntPointer)1