diff --git a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c index 0fcfa9fddef..e8402f6b6b0 100644 --- a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c +++ b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c @@ -172,7 +172,7 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP) DWORD ret; IP_ADAPTER_ADDRESSES *ptr, *adapters=0; ULONG len=ipinflen, count=0; - netif *nif=0, *dup_nif, *last=0, *loopif=0; + netif *nif=0, *dup_nif, *last=0, *loopif=0, *curr; int tun=0, net=0; *netifPP = 0; @@ -197,6 +197,20 @@ int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP) last = nif; } + // Retrieve IPv4 addresses with the IP Helper API + curr = *netifPP; + while (curr != NULL) { + netaddr *netaddrP; + ret = enumAddresses_win(env, curr, &netaddrP); + if ((*env)->ExceptionOccurred(env)) { + free_netaddr(netaddrP); + return -1; + } + curr->addrs = netaddrP; + curr->naddrs += ret; + curr = curr->next; + } + ret = getAdapters (env, &adapters); if (ret != ERROR_SUCCESS) { goto err; @@ -350,6 +364,14 @@ static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP) { /* 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 == 0) { return -1; @@ -361,15 +383,9 @@ static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP) { prev->next = curr; } prev = curr; - sock = uni_addr->Address.lpSockaddr; SOCKETADDRESS_COPY (&curr->addr, sock); if (prefix != NULL) { curr->mask = (short)prefix->PrefixLength; - if (sock->sa_family == AF_INET) { - sock = prefix->Address.lpSockaddr; - SOCKETADDRESS_COPY(&curr->brdcast, sock); - curr->brdcast.him4.sin_addr.s_addr |= htonl((0xffffffff >> curr->mask)); - } prefix = prefix->Next; } count ++; diff --git a/jdk/test/java/net/InterfaceAddress/NetworkPrefixLength.java b/jdk/test/java/net/InterfaceAddress/NetworkPrefixLength.java new file mode 100644 index 00000000000..7b7f95852b8 --- /dev/null +++ b/jdk/test/java/net/InterfaceAddress/NetworkPrefixLength.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6707289 + * @summary InterfaceAddress.getNetworkPrefixLength() does not conform to Javadoc + */ + +import java.net.InetAddress; +import java.net.Inet4Address; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.util.Enumeration; +import static java.lang.System.out; + +public class NetworkPrefixLength { + static boolean passed = true; + + public static void main(String[] args) throws Exception { + Enumeration nics = NetworkInterface.getNetworkInterfaces(); + + while (nics.hasMoreElements()) { + NetworkInterface nic = nics.nextElement(); + for (InterfaceAddress iaddr : nic.getInterfaceAddresses()) { + boolean valid = checkPrefix(iaddr); + if (!valid) { + passed = false; + debug(nic.getName(), iaddr); + } + } + } + + if (!passed) + throw new RuntimeException("Failed: some interfaces have invalid prefix lengths"); + } + + static boolean checkPrefix(InterfaceAddress iaddr) { + InetAddress addr = iaddr.getAddress(); + + if (addr instanceof Inet4Address) + return checkIPv4PrefixLength(iaddr.getNetworkPrefixLength()); + else + return checkIPv6PrefixLength(iaddr.getNetworkPrefixLength()); + } + + static boolean checkIPv4PrefixLength(int prefix) { + if (prefix >=0 && prefix <= 32) + return true; + + return false; + } + + static boolean checkIPv6PrefixLength(int prefix) { + if (prefix >=0 && prefix <= 128) + return true; + + return false; + } + + static void debug(String nicName, InterfaceAddress iaddr) { + out.println("NIC " + nicName + " has an address with an invalid prefix length:\n" + iaddr); + } +} +