diff --git a/src/windows/native/java/net/Inet4AddressImpl.c b/src/windows/native/java/net/Inet4AddressImpl.c index 11c3392c301a01a7c998a653148e795db2ba330c..71d26820e684909a061c216ca8b9d82c4ecb7a76 100644 --- a/src/windows/native/java/net/Inet4AddressImpl.c +++ b/src/windows/native/java/net/Inet4AddressImpl.c @@ -299,8 +299,11 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this, * Returns true is an ECHO_REPLY is received, otherwise, false. */ static jboolean -ping4(JNIEnv *env, unsigned long ipaddr, jint timeout) { - +ping4(JNIEnv *env, + unsigned long src_addr, + unsigned long dest_addr, + jint timeout) +{ // See https://msdn.microsoft.com/en-us/library/aa366050%28VS.85%29.aspx HANDLE hIcmpFile; @@ -323,14 +326,29 @@ ping4(JNIEnv *env, unsigned long ipaddr, jint timeout) { return JNI_FALSE; } - dwRetVal = IcmpSendEcho(hIcmpFile, // HANDLE IcmpHandle, - ipaddr, // IPAddr DestinationAddress, - SendData, // LPVOID RequestData, - sizeof(SendData), // WORD RequestSize, - NULL, // PIP_OPTION_INFORMATION RequestOptions, - ReplyBuffer,// LPVOID ReplyBuffer, - ReplySize, // DWORD ReplySize, - timeout); // DWORD Timeout + if (src_addr == 0) { + dwRetVal = IcmpSendEcho(hIcmpFile, // HANDLE IcmpHandle, + dest_addr, // IPAddr DestinationAddress, + SendData, // LPVOID RequestData, + sizeof(SendData), // WORD RequestSize, + NULL, // PIP_OPTION_INFORMATION RequestOptions, + ReplyBuffer,// LPVOID ReplyBuffer, + ReplySize, // DWORD ReplySize, + timeout); // DWORD Timeout + } else { + dwRetVal = IcmpSendEcho2Ex(hIcmpFile, // HANDLE IcmpHandle, + NULL, // HANDLE Event + NULL, // PIO_APC_ROUTINE ApcRoutine + NULL, // ApcContext + src_addr, // IPAddr SourceAddress, + dest_addr, // IPAddr DestinationAddress, + SendData, // LPVOID RequestData, + sizeof(SendData), // WORD RequestSize, + NULL, // PIP_OPTION_INFORMATION RequestOptions, + ReplyBuffer,// LPVOID ReplyBuffer, + ReplySize, // DWORD ReplySize, + timeout); // DWORD Timeout + } free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); @@ -353,9 +371,9 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this, jint timeout, jbyteArray ifArray, jint ttl) { - jint addr; + jint src_addr = 0; + jint dest_addr = 0; jbyte caddr[4]; - struct sockaddr_in him; int sz; /** @@ -365,13 +383,27 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this, if (sz != 4) { return JNI_FALSE; } - memset((char *) &him, 0, sizeof(him)); memset((char *) caddr, 0, sizeof(caddr)); (*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); - addr = htonl(addr); - return ping4(env, addr, timeout); + dest_addr = ((caddr[0]<<24) & 0xff000000); + dest_addr |= ((caddr[1] <<16) & 0xff0000); + dest_addr |= ((caddr[2] <<8) & 0xff00); + dest_addr |= (caddr[3] & 0xff); + dest_addr = htonl(dest_addr); + + /** + * If a network interface was specified, let's convert its address + * as well. + */ + if (!(IS_NULL(ifArray))) { + memset((char *) caddr, 0, sizeof(caddr)); + (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr); + src_addr = ((caddr[0]<<24) & 0xff000000); + src_addr |= ((caddr[1] <<16) & 0xff0000); + src_addr |= ((caddr[2] <<8) & 0xff00); + src_addr |= (caddr[3] & 0xff); + src_addr = htonl(src_addr); + } + + return ping4(env, src_addr, dest_addr, timeout); } diff --git a/test/java/net/InetAddress/IsReachableViaLoopbackTest.java b/test/java/net/InetAddress/IsReachableViaLoopbackTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4d7f266ec1d647f933e45fc4791ac70a63e0f622 --- /dev/null +++ b/test/java/net/InetAddress/IsReachableViaLoopbackTest.java @@ -0,0 +1,40 @@ +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * @test + * @bug 8135305 + * @summary ensure we can't ping external hosts via loopback if + */ + +public class IsReachableViaLoopbackTest { + public static void main(String[] args) { + try { + InetAddress addr = InetAddress.getByName("localhost"); + InetAddress remoteAddr = InetAddress.getByName("bugs.openjdk.java.net"); + if (!addr.isReachable(10000)) + throw new RuntimeException("Localhost should always be reachable"); + NetworkInterface inf = NetworkInterface.getByInetAddress(addr); + if (inf != null) { + if (!addr.isReachable(inf, 20, 10000)) { + throw new RuntimeException("Localhost should always be reachable"); + } else { + System.out.println(addr + " is reachable"); + } + if (remoteAddr.isReachable(inf, 20, 10000)) { + throw new RuntimeException(remoteAddr + " is reachable"); + } else { + System.out.println(remoteAddr + " is NOT reachable"); + } + } else { + System.out.println("inf == null"); + } + + } catch (IOException e) { + throw new RuntimeException("Unexpected exception:" + e); + } + System.out.println("IsReachableViaLoopbackTest EXIT"); + } +} +