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;
}
}
Aggregations