1 /*
2 * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.net;
26
27 import java.io.IOException;
28 import static java.net.InetAddress.PREFER_IPV6_VALUE;
29 import static java.net.InetAddress.PREFER_SYSTEM_VALUE;
30
31 /*
32 * Package private implementation of InetAddressImpl for dual
33 * IPv4/IPv6 stack.
34 * <p>
35 * If InetAddress.preferIPv6Address is true then anyLocalAddress(),
36 * loopbackAddress(), and localHost() will return IPv6 addresses,
37 * otherwise IPv4 addresses.
38 *
39 * @since 1.4
40 */
41 class Inet6AddressImpl implements InetAddressImpl {
42
43 public native String getLocalHostName() throws UnknownHostException;
44
45 public native InetAddress[] lookupAllHostAddr(String hostname)
46 throws UnknownHostException;
47
48 public native String getHostByAddr(byte[] addr) throws UnknownHostException;
49
50 private native boolean isReachable0(byte[] addr, int scope, int timeout,
51 byte[] inf, int ttl, int if_scope)
52 throws IOException;
53
54 public boolean isReachable(InetAddress addr, int timeout,
55 NetworkInterface netif, int ttl)
56 throws IOException
57 {
58 byte[] ifaddr = null;
59 int scope = -1;
60 int netif_scope = -1;
61 if (netif != null) {
62 /*
63 * Let's make sure we bind to an address of the proper family.
64 * Which means same family as addr because at this point it could
65 * be either an IPv6 address or an IPv4 address (case of a dual
66 * stack system).
67 */
68 java.util.Enumeration<InetAddress> it = netif.getInetAddresses();
69 InetAddress inetaddr = null;
70 while (it.hasMoreElements()) {
71 inetaddr = it.nextElement();
72 if (inetaddr.getClass().isInstance(addr)) {
73 ifaddr = inetaddr.getAddress();
74 if (inetaddr instanceof Inet6Address) {
75 netif_scope = ((Inet6Address) inetaddr).getScopeId();
76 }
77 break;
78 }
79 }
80 if (ifaddr == null) {
81 // Interface doesn't support the address family of
82 // the destination
83 return false;
84 }
85 }
86 if (addr instanceof Inet6Address)
87 scope = ((Inet6Address) addr).getScopeId();
88 return isReachable0(addr.getAddress(), scope, timeout, ifaddr, ttl, netif_scope);
89 }
90
91 public synchronized InetAddress anyLocalAddress() {
92 if (anyLocalAddress == null) {
93 if (InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
94 InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE) {
95 anyLocalAddress = new Inet6Address();
96 anyLocalAddress.holder().hostName = "::";
97 } else {
98 anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress();
99 }
100 }
101 return anyLocalAddress;
102 }
103
104 public synchronized InetAddress loopbackAddress() {
105 if (loopbackAddress == null) {
106 if (InetAddress.preferIPv6Address == PREFER_IPV6_VALUE ||
107 InetAddress.preferIPv6Address == PREFER_SYSTEM_VALUE) {
108 byte[] loopback =
109 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
111 loopbackAddress = new Inet6Address("localhost", loopback);
112 } else {
113 loopbackAddress = (new Inet4AddressImpl()).loopbackAddress();
114 }
115 }
116 return loopbackAddress;
117 }
118
119 private InetAddress anyLocalAddress;
120 private InetAddress loopbackAddress;
121 }
122