/* * Copyright (C) 2014 The Android Open Source Project * Copyright (c) 1995, 2015, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.net; import java.io.ObjectStreamException; import java.io.ObjectStreamField; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectInputStream.GetField; import java.io.ObjectOutputStream; import java.io.ObjectOutputStream.PutField; import sun.net.util.IPAddressUtil; import sun.net.spi.nameservice.*; import android.system.GaiException; import android.system.StructAddrinfo; import libcore.io.Libcore; import static android.system.OsConstants.*; /** * This class represents an Internet Protocol (IP) address. * *

An IP address is either a 32-bit or 128-bit unsigned number * used by IP, a lower-level protocol on which protocols like UDP and * TCP are built. The IP address architecture is defined by RFC 790: * Assigned Numbers, RFC 1918: * Address Allocation for Private Internets, RFC 2365: * Administratively Scoped IP Multicast, and RFC 2373: IP * Version 6 Addressing Architecture. An instance of an * InetAddress consists of an IP address and possibly its * corresponding host name (depending on whether it is constructed * with a host name or whether it has already done reverse host name * resolution). * *

Address types

* *
* * * * *
unicastAn identifier for a single interface. A packet sent to * a unicast address is delivered to the interface identified by * that address. * *

The Unspecified Address -- Also called anylocal or wildcard * address. It must never be assigned to any node. It indicates the * absence of an address. One example of its use is as the target of * bind, which allows a server to accept a client connection on any * interface, in case the server host has multiple interfaces. * *

The unspecified address must not be used as * the destination address of an IP packet. * *

The Loopback Addresses -- This is the address * assigned to the loopback interface. Anything sent to this * IP address loops around and becomes IP input on the local * host. This address is often used when testing a * client.

multicastAn identifier for a set of interfaces (typically belonging * to different nodes). A packet sent to a multicast address is * delivered to all interfaces identified by that address.
* *

IP address scope

* *

Link-local addresses are designed to be used for addressing * on a single link for purposes such as auto-address configuration, * neighbor discovery, or when no routers are present. * *

Site-local addresses are designed to be used for addressing * inside of a site without the need for a global prefix. * *

Global addresses are unique across the internet. * *

Textual representation of IP addresses

* * The textual representation of an IP address is address family specific. * *

* * For IPv4 address format, please refer to Inet4Address#format; For IPv6 * address format, please refer to Inet6Address#format. * *

There is a couple of * System Properties affecting how IPv4 and IPv6 addresses are used.

* *

Host Name Resolution

* * Host name-to-IP address resolution is accomplished through * the use of a combination of local machine configuration information * and network naming services such as the Domain Name System (DNS) * and Network Information Service(NIS). The particular naming * services(s) being used is by default the local machine configured * one. For any host name, its corresponding IP address is returned. * *

Reverse name resolution means that for any IP address, * the host associated with the IP address is returned. * *

The InetAddress class provides methods to resolve host names to * their IP addresses and vice versa. * *

InetAddress Caching

* * The InetAddress class has a cache to store successful as well as * unsuccessful host name resolutions. * *

By default, when a security manager is installed, in order to * protect against DNS spoofing attacks, * the result of positive host name resolutions are * cached forever. When a security manager is not installed, the default * behavior is to cache entries for a finite (implementation dependent) * period of time. The result of unsuccessful host * name resolution is cached for a very short period of time (10 * seconds) to improve performance. * *

If the default behavior is not desired, then a Java security property * can be set to a different Time-to-live (TTL) value for positive * caching. Likewise, a system admin can configure a different * negative caching TTL value when needed. * *

Two Java security properties control the TTL values used for * positive and negative host name resolution caching: * *

*
*
networkaddress.cache.ttl
*
Indicates the caching policy for successful name lookups from * the name service. The value is specified as as integer to indicate * the number of seconds to cache the successful lookup. The default * setting is to cache for an implementation specific period of time. *

* A value of -1 indicates "cache forever". *

*
networkaddress.cache.negative.ttl (default: 10)
*
Indicates the caching policy for un-successful name lookups * from the name service. The value is specified as as integer to * indicate the number of seconds to cache the failure for * un-successful lookups. *

* A value of 0 indicates "never cache". * A value of -1 indicates "cache forever". *

*
*
* * @author Chris Warth * @see java.net.InetAddress#getByAddress(byte[]) * @see java.net.InetAddress#getByAddress(java.lang.String, byte[]) * @see java.net.InetAddress#getAllByName(java.lang.String) * @see java.net.InetAddress#getByName(java.lang.String) * @see java.net.InetAddress#getLocalHost() * @since JDK1.0 */ public class InetAddress implements java.io.Serializable { static class InetAddressHolder { /** * Reserve the original application specified hostname. * * The original hostname is useful for domain-based endpoint * identification (see RFC 2818 and RFC 6125). If an address * was created with a raw IP address, a reverse name lookup * may introduce endpoint identification security issue via * DNS forging. * * Oracle JSSE provider is using this original hostname, via * sun.misc.JavaNetAccess, for SSL/TLS endpoint identification. * * Note: May define a new public method in the future if necessary. */ private String originalHostName; InetAddressHolder() {} InetAddressHolder(String hostName, int address, int family) { this.originalHostName = hostName; this.hostName = hostName; this.address = address; this.family = family; } void init(String hostName, int family) { this.originalHostName = hostName; this.hostName = hostName; if (family != -1) { this.family = family; } } String hostName; String getHostName() { return hostName; } String getOriginalHostName() { return originalHostName; } /** * Holds a 32-bit IPv4 address. */ int address; int getAddress() { return address; } /** * Specifies the address family type, for instance, AF_INET for IPv4 * addresses, and AF_INET6 for IPv6 addresses. */ int family; int getFamily() { return family; } } transient InetAddressHolder holder; InetAddressHolder holder() { return holder; } /* The implementation is always dual stack IPv6/IPv4 on android */ static final InetAddressImpl impl = new Inet6AddressImpl(); /* Used to store the name service provider */ private static final NameService nameService = new NameService() { public InetAddress[] lookupAllHostAddr(String host, int netId) throws UnknownHostException { return impl.lookupAllHostAddr(host, netId); } public String getHostByAddr(byte[] addr) throws UnknownHostException { return impl.getHostByAddr(addr); } }; /* Used to store the best available hostname */ private transient String canonicalHostName = null; /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = 3286316764910316507L; /** * Constructor for the Socket.accept() method. * This creates an empty InetAddress, which is filled in by * the accept() method. This InetAddress, however, is not * put in the address cache, since it is not created by name. */ InetAddress() { holder = new InetAddressHolder(); } /** * Replaces the de-serialized object with an Inet4Address object. * * @return the alternate object to the de-serialized object. * * @throws ObjectStreamException if a new object replacing this * object could not be created */ private Object readResolve() throws ObjectStreamException { // will replace the deserialized 'this' object return new Inet4Address(holder().getHostName(), holder().getAddress()); } /** * Utility routine to check if the InetAddress is an * IP multicast address. * @return a {@code boolean} indicating if the InetAddress is * an IP multicast address * @since JDK1.1 */ public boolean isMulticastAddress() { return false; } /** * Utility routine to check if the InetAddress in a wildcard address. * @return a {@code boolean} indicating if the Inetaddress is * a wildcard address. * @since 1.4 */ public boolean isAnyLocalAddress() { return false; } /** * Utility routine to check if the InetAddress is a loopback address. * * @return a {@code boolean} indicating if the InetAddress is * a loopback address; or false otherwise. * @since 1.4 */ public boolean isLoopbackAddress() { return false; } /** * Utility routine to check if the InetAddress is an link local address. * * @return a {@code boolean} indicating if the InetAddress is * a link local address; or false if address is not a link local unicast address. * @since 1.4 */ public boolean isLinkLocalAddress() { return false; } /** * Utility routine to check if the InetAddress is a site local address. * * @return a {@code boolean} indicating if the InetAddress is * a site local address; or false if address is not a site local unicast address. * @since 1.4 */ public boolean isSiteLocalAddress() { return false; } /** * Utility routine to check if the multicast address has global scope. * * @return a {@code boolean} indicating if the address has * is a multicast address of global scope, false if it is not * of global scope or it is not a multicast address * @since 1.4 */ public boolean isMCGlobal() { return false; } /** * Utility routine to check if the multicast address has node scope. * * @return a {@code boolean} indicating if the address has * is a multicast address of node-local scope, false if it is not * of node-local scope or it is not a multicast address * @since 1.4 */ public boolean isMCNodeLocal() { return false; } /** * Utility routine to check if the multicast address has link scope. * * @return a {@code boolean} indicating if the address has * is a multicast address of link-local scope, false if it is not * of link-local scope or it is not a multicast address * @since 1.4 */ public boolean isMCLinkLocal() { return false; } /** * Utility routine to check if the multicast address has site scope. * * @return a {@code boolean} indicating if the address has * is a multicast address of site-local scope, false if it is not * of site-local scope or it is not a multicast address * @since 1.4 */ public boolean isMCSiteLocal() { return false; } /** * Utility routine to check if the multicast address has organization scope. * * @return a {@code boolean} indicating if the address has * is a multicast address of organization-local scope, * false if it is not of organization-local scope * or it is not a multicast address * @since 1.4 */ public boolean isMCOrgLocal() { return false; } /** * Test whether that address is reachable. Best effort is made by the * implementation to try to reach the host, but firewalls and server * configuration may block requests resulting in a unreachable status * while some specific ports may be accessible. * A typical implementation will use ICMP ECHO REQUESTs if the * privilege can be obtained, otherwise it will try to establish * a TCP connection on port 7 (Echo) of the destination host. *

* The timeout value, in milliseconds, indicates the maximum amount of time * the try should take. If the operation times out before getting an * answer, the host is deemed unreachable. A negative value will result * in an IllegalArgumentException being thrown. * * @param timeout the time, in milliseconds, before the call aborts * @return a {@code boolean} indicating if the address is reachable. * @throws IOException if a network error occurs * @throws IllegalArgumentException if {@code timeout} is negative. * @since 1.5 */ public boolean isReachable(int timeout) throws IOException { return isReachable(null, 0, timeout); } /** * Test whether that address is reachable. Best effort is made by the * implementation to try to reach the host, but firewalls and server * configuration may block requests resulting in a unreachable status * while some specific ports may be accessible. *

* Android implementation attempts ICMP ECHO REQUESTs first, on failure it * will fall back to TCP ECHO REQUESTs. Success on either protocol will * return true. *

* The {@code network interface} and {@code ttl} parameters * let the caller specify which network interface the test will go through * and the maximum number of hops the packets should go through. * A negative value for the {@code ttl} will result in an * IllegalArgumentException being thrown. *

* The timeout value, in milliseconds, indicates the maximum amount of time * the try should take. If the operation times out before getting an * answer, the host is deemed unreachable. A negative value will result * in an IllegalArgumentException being thrown. * * @param netif the NetworkInterface through which the * test will be done, or null for any interface * @param ttl the maximum numbers of hops to try or 0 for the * default * @param timeout the time, in milliseconds, before the call aborts * @throws IllegalArgumentException if either {@code timeout} * or {@code ttl} are negative. * @return a {@code boolean}indicating if the address is reachable. * @throws IOException if a network error occurs * @since 1.5 */ public boolean isReachable(NetworkInterface netif, int ttl, int timeout) throws IOException { if (ttl < 0) throw new IllegalArgumentException("ttl can't be negative"); if (timeout < 0) throw new IllegalArgumentException("timeout can't be negative"); return impl.isReachable(this, timeout, netif, ttl); } /** * @hide For testing only */ public boolean isReachableByICMP(int timeout) throws IOException { return ((Inet6AddressImpl) impl).icmpEcho(this, timeout, null, 0); } /** * Gets the host name for this IP address. * *

If this InetAddress was created with a host name, * this host name will be remembered and returned; * otherwise, a reverse name lookup will be performed * and the result will be returned based on the system * configured name lookup service. If a lookup of the name service * is required, call * {@link #getCanonicalHostName() getCanonicalHostName}. * *

If there is a security manager, its * {@code checkConnect} method is first called * with the hostname and {@code -1} * as its arguments to see if the operation is allowed. * If the operation is not allowed, it will return * the textual representation of the IP address. * * @return the host name for this IP address, or if the operation * is not allowed by the security check, the textual * representation of the IP address. * * @see InetAddress#getCanonicalHostName * @see SecurityManager#checkConnect */ public String getHostName() { if (holder().getHostName() == null) { holder().hostName = InetAddress.getHostFromNameService(this); } return holder().getHostName(); } /** * Gets the fully qualified domain name for this IP address. * Best effort method, meaning we may not be able to return * the FQDN depending on the underlying system configuration. * *

If there is a security manager, this method first * calls its {@code checkConnect} method * with the hostname and {@code -1} * as its arguments to see if the calling code is allowed to know * the hostname for this IP address, i.e., to connect to the host. * If the operation is not allowed, it will return * the textual representation of the IP address. * * @return the fully qualified domain name for this IP address, * or if the operation is not allowed by the security check, * the textual representation of the IP address. * * @see SecurityManager#checkConnect * * @since 1.4 */ public String getCanonicalHostName() { if (canonicalHostName == null) { canonicalHostName = InetAddress.getHostFromNameService(this); } return canonicalHostName; } /** * Returns the hostname for this address. * *

If there is a security manager, this method first * calls its {@code checkConnect} method * with the hostname and {@code -1} * as its arguments to see if the calling code is allowed to know * the hostname for this IP address, i.e., to connect to the host. * If the operation is not allowed, it will return * the textual representation of the IP address. * * @return the host name for this IP address, or if the operation * is not allowed by the security check, the textual * representation of the IP address. * * @see SecurityManager#checkConnect */ private static String getHostFromNameService(InetAddress addr) { String host = null; try { // first lookup the hostname host = nameService.getHostByAddr(addr.getAddress()); /* now get all the IP addresses for this hostname, * and make sure one of them matches the original IP * address. We do this to try and prevent spoofing. */ InetAddress[] arr = nameService.lookupAllHostAddr(host, NETID_UNSET); boolean ok = false; if (arr != null) { for(int i = 0; !ok && i < arr.length; i++) { ok = addr.equals(arr[i]); } } //XXX: if it looks a spoof just return the address? if (!ok) { host = addr.getHostAddress(); return host; } } catch (UnknownHostException e) { host = addr.getHostAddress(); } return host; } /** * Returns the raw IP address of this {@code InetAddress} * object. The result is in network byte order: the highest order * byte of the address is in {@code getAddress()[0]}. * * @return the raw IP address of this object. */ public byte[] getAddress() { return null; } /** * Returns the IP address string in textual presentation. * * @return the raw IP address in a string format. * @since JDK1.0.2 */ public String getHostAddress() { return null; } /** * Returns a hashcode for this IP address. * * @return a hash code value for this IP address. */ public int hashCode() { return -1; } /** * Compares this object against the specified object. * The result is {@code true} if and only if the argument is * not {@code null} and it represents the same IP address as * this object. *

* Two instances of {@code InetAddress} represent the same IP * address if the length of the byte arrays returned by * {@code getAddress} is the same for both, and each of the * array components is the same for the byte arrays. * * @param obj the object to compare against. * @return {@code true} if the objects are the same; * {@code false} otherwise. * @see java.net.InetAddress#getAddress() */ public boolean equals(Object obj) { return false; } /** * Converts this IP address to a {@code String}. The * string returned is of the form: hostname / literal IP * address. * * If the host name is unresolved, no reverse name service lookup * is performed. The hostname part will be represented by an empty string. * * @return a string representation of this IP address. */ public String toString() { String hostName = holder().getHostName(); return ((hostName != null) ? hostName : "") + "/" + getHostAddress(); } /** * Creates an InetAddress based on the provided host name and IP address. * No name service is checked for the validity of the address. * *

The host name can either be a machine name, such as * "{@code java.sun.com}", or a textual representation of its IP * address. *

No validity checking is done on the host name either. * *

If addr specifies an IPv4 address an instance of Inet4Address * will be returned; otherwise, an instance of Inet6Address * will be returned. * *

IPv4 address byte array must be 4 bytes long and IPv6 byte array * must be 16 bytes long * * @param host the specified host * @param addr the raw IP address in network byte order * @return an InetAddress object created from the raw IP address. * @exception UnknownHostException if IP address is of illegal length * @since 1.4 */ public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException { return getByAddress(host, addr, -1 /* scopeId */); } // Do not delete. Called from native code. private static InetAddress getByAddress(String host, byte[] addr, int scopeId) throws UnknownHostException { if (host != null && host.length() > 0 && host.charAt(0) == '[') { if (host.charAt(host.length()-1) == ']') { host = host.substring(1, host.length() -1); } } if (addr != null) { if (addr.length == Inet4Address.INADDRSZ) { return new Inet4Address(host, addr); } else if (addr.length == Inet6Address.INADDRSZ) { byte[] newAddr = IPAddressUtil.convertFromIPv4MappedAddress(addr); if (newAddr != null) { return new Inet4Address(host, newAddr); } else { return new Inet6Address(host, addr, scopeId); } } } throw new UnknownHostException("addr is of illegal length"); } /** * Determines the IP address of a host, given the host's name. * *

The host name can either be a machine name, such as * "{@code java.sun.com}", or a textual representation of its * IP address. If a literal IP address is supplied, only the * validity of the address format is checked. * *

For {@code host} specified in literal IPv6 address, * either the form defined in RFC 2732 or the literal IPv6 address * format defined in RFC 2373 is accepted. IPv6 scoped addresses are also * supported. See here for a description of IPv6 * scoped addresses. * *

If the host is {@code null} then an {@code InetAddress} * representing an address of the loopback interface is returned. * See RFC 3330 * section 2 and RFC 2373 * section 2.5.3.

* * @param host the specified host, or {@code null}. * @return an IP address for the given host name. * @exception UnknownHostException if no IP address for the * {@code host} could be found, or if a scope_id was specified * for a global IPv6 address. * @exception SecurityException if a security manager exists * and its checkConnect method doesn't allow the operation */ public static InetAddress getByName(String host) throws UnknownHostException { return impl.lookupAllHostAddr(host, NETID_UNSET)[0]; } /** * Given the name of a host, returns an array of its IP addresses, * based on the configured name service on the system. * *

The host name can either be a machine name, such as * "{@code java.sun.com}", or a textual representation of its IP * address. If a literal IP address is supplied, only the * validity of the address format is checked. * *

For {@code host} specified in literal IPv6 address, * either the form defined in RFC 2732 or the literal IPv6 address * format defined in RFC 2373 is accepted. A literal IPv6 address may * also be qualified by appending a scoped zone identifier or scope_id. * The syntax and usage of scope_ids is described * here. *

If the host is {@code null} then an {@code InetAddress} * representing an address of the loopback interface is returned. * See RFC 3330 * section 2 and RFC 2373 * section 2.5.3.

* *

If there is a security manager and {@code host} is not * null and {@code host.length() } is not equal to zero, the * security manager's * {@code checkConnect} method is called * with the hostname and {@code -1} * as its arguments to see if the operation is allowed. * * @param host the name of the host, or {@code null}. * @return an array of all the IP addresses for a given host name. * * @exception UnknownHostException if no IP address for the * {@code host} could be found, or if a scope_id was specified * for a global IPv6 address. * @exception SecurityException if a security manager exists and its * {@code checkConnect} method doesn't allow the operation. * * @see SecurityManager#checkConnect */ public static InetAddress[] getAllByName(String host) throws UnknownHostException { return impl.lookupAllHostAddr(host, NETID_UNSET).clone(); } /** * Returns the loopback address. *

* The InetAddress returned will represent the IPv4 * loopback address, 127.0.0.1, or the IPv6 loopback * address, ::1. The IPv4 loopback address returned * is only one of many in the form 127.*.*.* * * @return the InetAddress loopback instance. * @since 1.7 */ public static InetAddress getLoopbackAddress() { return impl.loopbackAddresses()[0]; } /** * Returns an {@code InetAddress} object given the raw IP address . * The argument is in network byte order: the highest order * byte of the address is in {@code getAddress()[0]}. * *

This method doesn't block, i.e. no reverse name service lookup * is performed. * *

IPv4 address byte array must be 4 bytes long and IPv6 byte array * must be 16 bytes long * * @param addr the raw IP address in network byte order * @return an InetAddress object created from the raw IP address. * @exception UnknownHostException if IP address is of illegal length * @since 1.4 */ public static InetAddress getByAddress(byte[] addr) throws UnknownHostException { return getByAddress(null, addr); } /** * Returns the address of the local host. This is achieved by retrieving * the name of the host from the system, then resolving that name into * an {@code InetAddress}. * *

Note: The resolved address may be cached for a short period of time. *

* *

If there is a security manager, its * {@code checkConnect} method is called * with the local host name and {@code -1} * as its arguments to see if the operation is allowed. * If the operation is not allowed, an InetAddress representing * the loopback address is returned. * * @return the address of the local host. * * @exception UnknownHostException if the local host name could not * be resolved into an address. * * @see SecurityManager#checkConnect * @see java.net.InetAddress#getByName(java.lang.String) */ public static InetAddress getLocalHost() throws UnknownHostException { String local = Libcore.os.uname().nodename; return impl.lookupAllHostAddr(local, NETID_UNSET)[0]; } /* * Returns the InetAddress representing anyLocalAddress * (typically 0.0.0.0 or ::0) */ static InetAddress anyLocalAddress() { return impl.anyLocalAddress(); } private void readObjectNoData (ObjectInputStream s) throws IOException, ClassNotFoundException { // Android-changed: Don't use null to mean the boot classloader. if (getClass().getClassLoader() != BOOT_CLASSLOADER) { throw new SecurityException ("invalid address type"); } } // Android-changed: Don't use null to mean the boot classloader. private static final ClassLoader BOOT_CLASSLOADER = Object.class.getClassLoader(); private void readObject (ObjectInputStream s) throws IOException, ClassNotFoundException { // Android-changed: Don't use null to mean the boot classloader. if (getClass().getClassLoader() != BOOT_CLASSLOADER) { throw new SecurityException ("invalid address type"); } GetField gf = s.readFields(); String host = (String)gf.get("hostName", null); int address= gf.get("address", 0); int family= gf.get("family", 0); holder = new InetAddressHolder(host, address, family); } /* needed because the serializable fields no longer exist */ /** * @serialField hostName String * @serialField address int * @serialField family int */ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("hostName", String.class), new ObjectStreamField("address", int.class), new ObjectStreamField("family", int.class), }; private void writeObject (ObjectOutputStream s) throws IOException { // Android-changed: Don't use null to mean the boot classloader. if (getClass().getClassLoader() != BOOT_CLASSLOADER) { throw new SecurityException ("invalid address type"); } PutField pf = s.putFields(); pf.put("hostName", holder().hostName); pf.put("address", holder().address); pf.put("family", holder().family); s.writeFields(); s.flush(); } static final int NETID_UNSET = 0; /** * Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1"). * This copes with all forms of address that Java supports, detailed in the {@link InetAddress} * class documentation. * * @hide used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup. */ public static boolean isNumeric(String address) { InetAddress inetAddress = parseNumericAddressNoThrow(address); return inetAddress != null && disallowDeprecatedFormats(address, inetAddress) != null; } static InetAddress parseNumericAddressNoThrow(String address) { // Accept IPv6 addresses (only) in square brackets for compatibility. if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) { address = address.substring(1, address.length() - 1); } StructAddrinfo hints = new StructAddrinfo(); hints.ai_flags = AI_NUMERICHOST; InetAddress[] addresses = null; try { addresses = Libcore.os.android_getaddrinfo(address, hints, NETID_UNSET); } catch (GaiException ignored) { } return (addresses != null) ? addresses[0] : null; } static InetAddress disallowDeprecatedFormats(String address, InetAddress inetAddress) { // Only IPv4 addresses are problematic. if (!(inetAddress instanceof Inet4Address) || address.indexOf(':') != -1) { return inetAddress; } // If inet_pton(3) can't parse it, it must have been a deprecated format. // We need to return inet_pton(3)'s result to ensure that numbers assumed to be octal // by getaddrinfo(3) are reinterpreted by inet_pton(3) as decimal. return Libcore.os.inet_pton(AF_INET, address); } /** * Returns an InetAddress corresponding to the given numeric address (such * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}). * This method will never do a DNS lookup. Non-numeric addresses are errors. * * @hide used by frameworks/base's NetworkUtils.numericToInetAddress * @throws IllegalArgumentException if {@code numericAddress} is not a numeric address */ public static InetAddress parseNumericAddress(String numericAddress) { if (numericAddress == null || numericAddress.isEmpty()) { return Inet6Address.LOOPBACK; } InetAddress result = parseNumericAddressNoThrow(numericAddress); result = disallowDeprecatedFormats(numericAddress, result); if (result == null) { throw new IllegalArgumentException("Not a numeric address: " + numericAddress); } return result; } /** * Removes all entries from the VM's DNS cache. This does not affect the C library's DNS * cache, nor any caching DNS servers between you and the canonical server. * @hide */ public static void clearDnsCache() { impl.clearAddressCache(); } /** * Operates identically to {@code getByName} except host resolution is * performed on the network designated by {@code netId}. * * @param host * the hostName to be resolved to an address or {@code null}. * @param netId the network to use for host resolution. * @return the {@code InetAddress} instance representing the host. * @throws UnknownHostException if the address lookup fails. * @hide internal use only */ public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException { return impl.lookupAllHostAddr(host, netId)[0]; } /** * Operates identically to {@code getAllByName} except host resolution is * performed on the network designated by {@code netId}. * * @param host the hostname or literal IP string to be resolved. * @param netId the network to use for host resolution. * @return the array of addresses associated with the specified host. * @throws UnknownHostException if the address lookup fails. * @hide internal use only */ public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException { return impl.lookupAllHostAddr(host, netId).clone(); } // Only called by java.net.SocketPermission. static InetAddress[] getAllByName0(String authHost, boolean check) throws UnknownHostException { throw new UnsupportedOperationException(); } // Only called by java.net.SocketPermission. String getHostName(boolean check) { throw new UnsupportedOperationException(); } }