InetAddress.java revision d2af45a6fd008ceb958ac74e5a50e582b8419e9c
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileDescriptor;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectStreamException;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectStreamField;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController;
28ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colittiimport java.util.Arrays;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList;
30d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.Collections;
31ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colittiimport java.util.Comparator;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration;
33d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.List;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.StringTokenizer;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.net.NetUtil;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.INetworkSystem;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.Platform;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Inet6Util;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Msg;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
44048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * An Internet Protocol (IP) address. This can be either an IPv4 address or an IPv6 address, and
45048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * in practice you'll have an instance of either {@code Inet4Address} or {@code Inet6Address} (this
46048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * class cannot be instantiated directly). Most code does not need to distinguish between the two
47048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * families, and should use {@code InetAddress}.
48048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * <p>
49048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * An {@code InetAddress} may have a hostname (accessible via {@code getHostName}), but may not,
50048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * depending on how the {@code InetAddress} was created.
51048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * <p>
52048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * On Android, addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are
53048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * cached for 10 seconds. The underlying C library or OS may cache for longer, but you can control
54048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * the Java-level caching with the usual {@code "networkaddress.cache.ttl"} and
55048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * {@code "networkaddress.cache.negative.ttl"} system properties. These are parsed as integer
56048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * numbers of seconds, where the special value 0 means "don't cache" and -1 means "cache forever".
57048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * <p>
58048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * Note also that on Android &ndash; unlike the RI &ndash; the cache is not unbounded. The current
59048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * implementation caches around 512 entries, removed on a least-recently-used basis.
60048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * (Obviously, you should not rely on these details.)
61048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes *
62048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * @see Inet4Address
63048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes * @see Inet6Address
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
65048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughespublic class InetAddress implements Serializable {
66048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    // BEGIN android-added: better DNS caching.
67048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    // Our Java-side DNS cache.
68048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static final AddressCache addressCache = new AddressCache();
69048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    // END android-added
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final static INetworkSystem NETIMPL = Platform.getNetworkSystem();
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused"; //$NON-NLS-1$
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
75ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    private static final long serialVersionUID = 3286316764910316507L;
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    String hostName;
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class WaitReachable {
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient Object waitReachable = new WaitReachable();
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean reached;
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int addrCount;
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
88051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    int family = 0;
89051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    static final int AF_INET = 2;
90051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    static final int AF_INET6 = 10;
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    byte[] ipaddress;
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-removed
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // // Fill in the JNI id caches
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // private static native void oneTimeInitialization(boolean supportsIPv6);
97f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    //
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // static {
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     oneTimeInitialization(true);
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // }
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-removed
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
104051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Constructs an {@code InetAddress}.
105051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     *
106051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Note: this constructor should not be used. Creating an InetAddress
107051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * without specifying whether it's an IPv4 or IPv6 address does not make
108051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * sense, because subsequent code cannot know which of of the subclasses'
109051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * methods need to be called to implement a given InetAddress method. The
110051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * proper way to create an InetAddress is to call new Inet4Address or
111051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Inet6Address or to use one of the static methods that return
112051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * InetAddresses (e.g., getByAddress). That is why the API does not have
113051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * public constructors for any of these classes.
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    InetAddress() {
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super();
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
119d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes    // BEGIN android-removed: use Inet4Address/Inet6Address instead, as appropriate.
120d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes    // InetAddress(byte[] address) { ... }
121051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    // END android-removed
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
123d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes    // BEGIN android-removed: use Inet4Address/Inet6Address instead, as appropriate.
124d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes    // InetAddress(byte[] address, String hostName) { ... }
125ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    // END android-removed
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares this {@code InetAddress} instance against the specified address
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in {@code obj}. Two addresses are equal if their address byte arrays have
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the same length and if the bytes in the arrays are equal.
131f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to be tested for equality.
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if both objects are equal, {@code false} otherwise.
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object obj) {
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-changed
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(obj instanceof InetAddress)) {
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
142051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress);
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-changed
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the IP address represented by this {@code InetAddress} instance
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as a byte array. The elements are in network order (the highest order
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address byte is in the zeroth element).
150f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the address in form of a byte array.
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getAddress() {
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ipaddress.clone();
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
157ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    // BEGIN android-added
158ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    static final Comparator<byte[]> SHORTEST_FIRST = new Comparator<byte[]>() {
159ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        public int compare(byte[] a1, byte[] a2) {
160ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            return a1.length - a2.length;
161ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
162ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    };
163ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
164ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    /**
165ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * Converts an array of byte arrays representing raw IP addresses of a host
166ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * to an array of InetAddress objects, sorting to respect the value of the
1674c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * system property {@code "java.net.preferIPv6Addresses"}.
168ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     *
169ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param rawAddresses the raw addresses to convert.
170ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param hostName the hostname corresponding to the IP address.
171ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @return the corresponding InetAddresses, appropriately sorted.
172ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     */
173ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    static InetAddress[] bytesToInetAddresses(byte[][] rawAddresses,
174ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            String hostName) {
175a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        // If we prefer IPv4, ignore the RFC3484 ordering we get from getaddrinfo
176a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        // and always put IPv4 addresses first. Arrays.sort() is stable, so the
177a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        // internal ordering will not be changed.
178a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        if (!NetUtil.preferIPv6Addresses()) {
179a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson            Arrays.sort(rawAddresses, SHORTEST_FIRST);
180a2a7fa1da77a6aaac09595f5712bc4a450ad2025Steinar H. Gunderson        }
181ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
182ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        // Convert the byte arrays to InetAddresses.
183ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        InetAddress[] returnedAddresses = new InetAddress[rawAddresses.length];
184ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        for (int i = 0; i < rawAddresses.length; i++) {
185ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            byte[] rawAddress = rawAddresses[i];
186ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            if (rawAddress.length == 16) {
187ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti                returnedAddresses[i] = new Inet6Address(rawAddress, hostName);
188ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            } else if (rawAddress.length == 4) {
189ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti                returnedAddresses[i] = new Inet4Address(rawAddress, hostName);
190ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            } else {
191ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti              // Cannot happen, because the underlying code only returns
192ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti              // addresses that are 4 or 16 bytes long.
193ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti              throw new AssertionError("Impossible address length " +
194ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti                                       rawAddress.length);
195ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            }
196ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
197ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        return returnedAddresses;
198ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    }
199ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    // END android-added
200ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets all IP addresses associated with the given {@code host} identified
203ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * by name or literal IP address. The IP address is resolved by the
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * configured name service. If the host name is empty or {@code null} an
205ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * {@code UnknownHostException} is thrown. If the host name is a literal IP
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address string an array with the corresponding single {@code InetAddress}
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is returned.
208f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
209ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param host the hostname or literal IP string to be resolved.
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the array of addresses associated with the specified host.
211ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @throws UnknownHostException if the address lookup fails.
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static InetAddress[] getAllByName(String host)
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws UnknownHostException {
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-changed
216ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        return getAllByNameImpl(host, true);
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-changed
218ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    }
219ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
220ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    // BEGIN android-added
221ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    /**
222ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * Implementation of getAllByName.
223ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     *
224ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param host the hostname or literal IP string to be resolved.
225ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param returnUnshared requests a result that is modifiable by the caller.
226ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @return the array of addresses associated with the specified host.
227ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @throws UnknownHostException if the address lookup fails.
228ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     */
229ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    static InetAddress[] getAllByNameImpl(String host, boolean returnUnshared)
230ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            throws UnknownHostException {
231ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        if (host == null || 0 == host.length()) {
2324c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes            if (NetUtil.preferIPv6Addresses()) {
233051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                return new InetAddress[] { Inet6Address.LOOPBACK,
234051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                                           Inet4Address.LOOPBACK };
235ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            } else {
236051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                return new InetAddress[] { Inet4Address.LOOPBACK,
237051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                                           Inet6Address.LOOPBACK };
238ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            }
239ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
240ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti
241ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        // Special-case "0" for legacy IPv4 applications.
242ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        if (host.equals("0")) { //$NON-NLS-1$
243051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti            return new InetAddress[] { Inet4Address.ANY };
244ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        }
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isHostName(host)) {
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            SecurityManager security = System.getSecurityManager();
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (security != null) {
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                security.checkConnect(host, -1);
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
251ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            if (returnUnshared) {
252ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti                return lookupHostByName(host).clone();
253ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            } else {
254ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti                return lookupHostByName(host);
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
258e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti        byte[] hBytes = NETIMPL.ipStringToByteArray(host);
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hBytes.length == 4) {
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (new InetAddress[] { new Inet4Address(hBytes) });
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (hBytes.length == 16) {
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (new InetAddress[] { new Inet6Address(hBytes) });
263051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        } else {
264051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti            throw new UnknownHostException(
265051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                    Msg.getString("K0339")); //$NON-NLS-1$
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
268ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    // END android-added
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the address of a host according to the given host string name
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code host}. The host string may be either a machine name or a dotted
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * string IP address. If the latter, the {@code hostName} field is
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * determined upon demand. {@code host} can be {@code null} which means that
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * an address of the loopback interface is returned.
276f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param host
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the hostName to be resolved to an address or {@code null}.
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the {@code InetAddress} instance representing the host.
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the address lookup fails.
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
283ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    public static InetAddress getByName(String host) throws UnknownHostException {
284ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        return getAllByNameImpl(host, false)[0];
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
287e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti    // BEGIN android-added
288e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti    /**
289fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes     * Returns the numeric string form of the given IP address.
290e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti     *
291fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes     * @param ipAddress
292fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes     *         the byte array to convert; length 4 for IPv4, 16 for IPv6.
293fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes     * @throws IllegalArgumentException
294fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes     *         if ipAddress is of length other than 4 or 16.
295511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti     */
296fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes    private static String ipAddressToString(byte[] ipAddress) {
297511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti        try {
298fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes            return NETIMPL.byteArrayToIpString(ipAddress);
299fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes        } catch (IOException ex) {
300fc354fea0c535ceef679e8856a73dd05be8351dfElliott Hughes            throw new IllegalArgumentException("byte[] neither 4 nor 16 bytes", ex);
301511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti        }
302511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    }
303e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti    // END android-added
304511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the textual representation of this IP address.
307f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
308511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti     * @return the textual representation of host's IP address.
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getHostAddress() {
311511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti        return ipAddressToString(ipaddress);
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the host name of this IP address. If the IP address could not be
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * resolved, the textual representation in a dotted-quad-notation is
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returned.
318f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the corresponding string name of this IP address.
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getHostName() {
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (hostName == null) {
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int address = 0;
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (ipaddress.length == 4) {
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    address = bytesToInt(ipaddress, 0);
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (address == 0) {
328511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti                        return hostName = ipAddressToString(ipaddress);
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                hostName = getHostByAddrImpl(ipaddress).hostName;
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (hostName.equals("localhost") && ipaddress.length == 4 //$NON-NLS-1$
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && address != 0x7f000001) {
334511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti                    return hostName = ipAddressToString(ipaddress);
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (UnknownHostException e) {
338511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            return hostName = ipAddressToString(ipaddress);
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Only check host names, not addresses
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (security != null && isHostName(hostName)) {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                security.checkConnect(hostName, -1);
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SecurityException e) {
347511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            return ipAddressToString(ipaddress);
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return hostName;
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the fully qualified domain name for the host associated with this IP
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address. If a security manager is set, it is checked if the method caller
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is allowed to get the hostname. Otherwise, the textual representation in
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * a dotted-quad-notation is returned.
357f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the fully qualified domain name of this IP address.
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getCanonicalHostName() {
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String canonicalName;
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int address = 0;
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ipaddress.length == 4) {
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                address = bytesToInt(ipaddress, 0);
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (address == 0) {
367511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti                    return ipAddressToString(ipaddress);
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            canonicalName = getHostByAddrImpl(ipaddress).hostName;
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (UnknownHostException e) {
372511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            return ipAddressToString(ipaddress);
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Only check host names, not addresses
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (security != null && isHostName(canonicalName)) {
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                security.checkConnect(canonicalName, -1);
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SecurityException e) {
381511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            return ipAddressToString(ipaddress);
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return canonicalName;
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the local host address if the security policy allows this.
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Otherwise, gets the loopback address which allows this machine to be
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * contacted.
390f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the {@code InetAddress} representing the local host.
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the address lookup fails.
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static InetAddress getLocalHost() throws UnknownHostException {
396048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes        String host = gethostname();
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (security != null) {
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                security.checkConnect(host, -1);
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SecurityException e) {
403051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti            return Inet4Address.LOOPBACK;
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
405ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti        return lookupHostByName(host)[0];
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
407048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static native String gethostname();
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the hashcode of the represented IP address.
411f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the appropriate hashcode value.
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
416051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        // BEGIN android-changed
417051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        return Arrays.hashCode(ipaddress);
418051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        // END android-changed
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
421051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    // BEGIN android-changed
422051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    /*
423051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * Returns whether this address is an IP multicast address or not. This
424051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti     * implementation returns always {@code false}.
425f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this address is in the multicast group, {@code
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         false} otherwise.
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMulticastAddress() {
430051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        return false;
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
432051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti    // END android-changed
433051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti
434ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    /**
435048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes     * Resolves a hostname to its IP addresses using a cache.
436ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     *
437ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @param host the hostname to resolve.
438ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     * @return the IP addresses of the host.
439ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti     */
440048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    // BEGIN android-changed
441048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static InetAddress[] lookupHostByName(String host) throws UnknownHostException {
442048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes        // Do we have a result cached?
443048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes        InetAddress[] cachedResult = addressCache.get(host);
444048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes        if (cachedResult != null) {
445048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            if (cachedResult.length > 0) {
446048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes                // A cached positive result.
447048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes                return cachedResult;
448048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            } else {
449048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes                // A cached negative result.
450048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes                throw new UnknownHostException(host);
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
454048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            InetAddress[] addresses = bytesToInetAddresses(getaddrinfo(host), host);
455048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            addressCache.put(host, addresses);
456048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            return addresses;
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (UnknownHostException e) {
458048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            addressCache.putUnknownHost(host);
459048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            throw new UnknownHostException(host);
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
462048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static native byte[][] getaddrinfo(String name) throws UnknownHostException;
463048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    // END android-changed
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-deleted
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // static native InetAddress[] getAliasesByNameImpl(String name)
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     throws UnknownHostException;
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-deleted
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Query the IP stack for the host address. The host is in address form.
472f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param addr
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the host address to lookup.
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs during lookup.
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-changed
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // static native InetAddress getHostByAddrImpl(byte[] addr)
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //    throws UnknownHostException;
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static InetAddress getHostByAddrImpl(byte[] addr)
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws UnknownHostException {
483051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        if (addr.length == 4) {
484048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            return new Inet4Address(addr, getnameinfo(addr));
485051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        } else if (addr.length == 16) {
486048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes            return new Inet6Address(addr, getnameinfo(addr));
487051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        } else {
488051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti            throw new UnknownHostException(Msg.getString(
489051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                    "K0339")); //$NON-NLS-1$
490051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        }
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Resolves an IP address to a hostname. Thread safe.
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
496048303b64df9c987ae2f57b6bf88ff5ac1b5cca0Elliott Hughes    private static native String getnameinfo(byte[] addr);
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-changed
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
499511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    // BEGIN android-removed
500511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    // static int inetAddr(String host) throws UnknownHostException
501511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    // END android-removed
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
503511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    // BEGIN android-removed
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // static native int inetAddrImpl(String host) throws UnknownHostException;
505511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    // END android-removed
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
507511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    // BEGIN android-removed
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // static native String inetNtoaImpl(int hipAddr);
509511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti    // END android-removed
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
511ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    // BEGIN android-removed
5124c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes    // static native InetAddress getHostByNameImpl(String name) throws UnknownHostException;
513ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti    // END android-removed
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
51555392539fea537abfb6581b474918f9d611fba27Jesse Wilson    static String getHostNameInternal(String host, boolean isCheck) throws UnknownHostException {
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (host == null || 0 == host.length()) {
517051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti            return Inet4Address.LOOPBACK.getHostAddress();
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isHostName(host)) {
52055392539fea537abfb6581b474918f9d611fba27Jesse Wilson            if (isCheck) {
52155392539fea537abfb6581b474918f9d611fba27Jesse Wilson                SecurityManager sm = System.getSecurityManager();
52255392539fea537abfb6581b474918f9d611fba27Jesse Wilson                if (sm != null) {
52355392539fea537abfb6581b474918f9d611fba27Jesse Wilson                    sm.checkConnect(host, -1);
52455392539fea537abfb6581b474918f9d611fba27Jesse Wilson                }
52555392539fea537abfb6581b474918f9d611fba27Jesse Wilson            }
526ca8f5b66c546d8545e41f71b6fb852424c681881Lorenzo Colitti            return lookupHostByName(host)[0].getHostAddress();
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return host;
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of this
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * IP address.
534f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the description, as host/address.
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (hostName == null ? "" : hostName) + "/" + getHostAddress(); //$NON-NLS-1$ //$NON-NLS-2$
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns true if the string is a host name, false if it is an IP Address.
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static boolean isHostName(String value) {
546e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti        try {
547e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti            NETIMPL.ipStringToByteArray(value);
548e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti            return false;
549e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti        } catch (UnknownHostException e) {
550e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti            return true;
551e8596906d75fd8ccda31600d71ad56391cd7cd3aLorenzo Colitti        }
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a loopback address or not. This
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}. Valid IPv4 loopback
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * addresses are 127.d.d.d The only valid IPv6 loopback address is ::1.
558f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a loopback address,
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isLoopbackAddress() {
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a link-local address or not. This
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}.
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 link-local addresses are FE80::0 through to
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * There are no valid IPv4 link-local addresses.
574f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a link-local address,
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isLinkLocalAddress() {
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a site-local address or not. This
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}.
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 site-local addresses are FEC0::0 through to
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * There are no valid IPv4 site-local addresses.
590f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a site-local address,
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isSiteLocalAddress() {
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a global multicast address or not. This
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation returns always {@code false}.
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 link-global multicast addresses are FFxE:/112 where x is a set
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the global multicast
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 global multicast addresses are between: 224.0.1.0 to
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 238.255.255.255.
608f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a global multicast
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCGlobal() {
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a node-local multicast address or not.
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This implementation returns always {@code false}.
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 node-local multicast addresses are FFx1:/112 where x is a set
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the node-local multicast
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * There are no valid IPv4 node-local multicast addresses.
625f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a node-local multicast
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCNodeLocal() {
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a link-local multicast address or not.
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This implementation returns always {@code false}.
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 link-local multicast addresses are FFx2:/112 where x is a set
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the link-local multicast
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 link-local addresses are between: 224.0.0.0 to 224.0.0.255
642f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a link-local multicast
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCLinkLocal() {
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a site-local multicast address or not.
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This implementation returns always {@code false}.
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 site-local multicast addresses are FFx5:/112 where x is a set
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of flags, and the additional 112 bits make up the site-local multicast
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address space.
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 site-local addresses are between: 239.252.0.0 to
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 239.255.255.255
660f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a site-local multicast
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         address, {@code false} otherwise.
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCSiteLocal() {
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this address is a organization-local multicast address or
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * not. This implementation returns always {@code false}.
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv6 organization-local multicast addresses are FFx8:/112 where x
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is a set of flags, and the additional 112 bits make up the
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * organization-local multicast address space.
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid IPv4 organization-local addresses are between: 239.192.0.0 to
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 239.251.255.255
678f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a organization-local
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         multicast address, {@code false} otherwise.
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isMCOrgLocal() {
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this is a wildcard address or not. This implementation
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returns always {@code false}.
689f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this instance represents a wildcard address,
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isAnyLocalAddress() {
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tries to reach this {@code InetAddress}. This method first tries to use
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * on port 7 (Echo) of the remote host is established.
701f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            timeout in milliseconds before the test fails if no connection
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            could be established.
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this address is reachable, {@code false}
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise.
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs during an I/O operation.
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if timeout is less than zero.
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isReachable(int timeout) throws IOException {
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isReachable(null, 0, timeout);
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tries to reach this {@code InetAddress}. This method first tries to use
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * on port 7 (Echo) of the remote host is established.
720f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
721d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes     * @param networkInterface
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the network interface on which to connection should be
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            established.
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ttl
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the maximum count of hops (time-to-live).
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            timeout in milliseconds before the test fails if no connection
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            could be established.
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this address is reachable, {@code false}
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise.
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs during an I/O operation.
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if ttl or timeout is less than zero.
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
736d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes    public boolean isReachable(NetworkInterface networkInterface, final int ttl,
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            final int timeout) throws IOException {
738d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        if (ttl < 0 || timeout < 0) {
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K0051")); //$NON-NLS-1$
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
741d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        if (networkInterface == null) {
742d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes            return isReachableByTCP(this, null, timeout);
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
744d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes            return isReachableByMultiThread(networkInterface, ttl, timeout);
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Uses multi-Thread to try if isReachable, returns true if any of threads
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returns in time
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-changed
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isReachableByMultiThread(NetworkInterface netif,
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            final int ttl, final int timeout)
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-changed
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
757d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        List<InetAddress> addresses = Collections.list(netif.getInetAddresses());
758d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        if (addresses.isEmpty()) {
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reached = false;
762d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        addrCount = addresses.size();
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean needWait = false;
764d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes        for (final InetAddress addr : addresses) {
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // loopback interface can only reach to local addresses
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (addr.isLoopbackAddress()) {
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Enumeration<NetworkInterface> NetworkInterfaces = NetworkInterface
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .getNetworkInterfaces();
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (NetworkInterfaces.hasMoreElements()) {
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    NetworkInterface networkInterface = NetworkInterfaces
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .nextElement();
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Enumeration<InetAddress> localAddresses = networkInterface
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getInetAddresses();
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    while (localAddresses.hasMoreElements()) {
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (InetAddress.this.equals(localAddresses
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                .nextElement())) {
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return true;
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                synchronized (waitReachable) {
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    addrCount--;
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (addrCount == 0) {
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // if count equals zero, all thread
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // expired,notifies main thread
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        waitReachable.notifyAll();
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            needWait = true;
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new Thread() {
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                @Override
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                public void run() {
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    boolean threadReached = false;
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // BEGIN android-changed
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // if isICMP, tries ICMP ping, else TCP echo
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // if (isICMP) {
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    //     threadReached = NETIMPL.isReachableByICMP(
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    //             InetAddress.this, addr, ttl, timeout);
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // } else {
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        try {
806f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                            threadReached = isReachableByTCP(addr,
807f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                                    InetAddress.this, timeout);
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        } catch (IOException e) {
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // do nothing
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // }
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // END android-changed
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    synchronized (waitReachable) {
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (threadReached) {
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // if thread reached this address, sets reached to
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // true and notifies main thread
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            reached = true;
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            waitReachable.notifyAll();
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        } else {
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            addrCount--;
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            if (0 == addrCount) {
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                // if count equals zero, all thread
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                // expired,notifies main thread
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                waitReachable.notifyAll();
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            }
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }.start();
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (needWait) {
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            synchronized (waitReachable) {
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    while (!reached && (addrCount != 0)) {
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // wait for notification
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        waitReachable.wait(1000);
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (InterruptedException e) {
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // do nothing
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return reached;
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-removed
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // private boolean isReachableByICMPUseMultiThread(NetworkInterface netif,
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         int ttl, int timeout) throws IOException {
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     return isReachableByMultiThread(netif, ttl, timeout, true);
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // }
855f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    //
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // private boolean isReachableByTCPUseMultiThread(NetworkInterface netif,
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         int ttl, int timeout) throws IOException {
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     return isReachableByMultiThread(netif, ttl, timeout, false);
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // }
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-removed
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isReachableByTCP(InetAddress dest, InetAddress source,
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int timeout) throws IOException {
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        FileDescriptor fd = new FileDescriptor();
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // define traffic only for parameter
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int traffic = 0;
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean reached = false;
868f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        NETIMPL.createStreamSocket(fd, NetUtil.preferIPv4Stack());
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (null != source) {
871f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                NETIMPL.bind(fd, source, 0);
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            NETIMPL.connectStreamWithTimeoutSocket(fd, 7, timeout, traffic,
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    dest);
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            reached = true;
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ERRMSG_CONNECTION_REFUSED.equals(e.getMessage())) {
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Connection refused means the IP is reachable
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                reached = true;
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        NETIMPL.socketClose(fd);
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return reached;
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the {@code InetAddress} corresponding to the array of bytes. In
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the case of an IPv4 address there must be exactly 4 bytes and for IPv6
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown.
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The IP address is not validated by a name service.
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The high order byte is {@code ipAddress[0]}.
896f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ipAddress
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            is either a 4 (IPv4) or 16 (IPv6) byte long array.
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return an {@code InetAddress} instance representing the given IP address
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code ipAddress}.
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given byte array has no valid length.
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static InetAddress getByAddress(byte[] ipAddress)
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws UnknownHostException {
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // simply call the method by the same name specifying the default scope
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // id of 0
90855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        return getByAddressInternal(null, ipAddress, 0);
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the {@code InetAddress} corresponding to the array of bytes. In
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the case of an IPv4 address there must be exactly 4 bytes and for IPv6
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * exactly 16 bytes. If not, an {@code UnknownHostException} is thrown. The
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * IP address is not validated by a name service. The high order byte is
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code ipAddress[0]}.
917f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ipAddress
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            either a 4 (IPv4) or 16 (IPv6) byte array.
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param scope_id
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the scope id for an IPV6 scoped address. If not a scoped
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            address just pass in 0.
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the InetAddress
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static InetAddress getByAddress(byte[] ipAddress, int scope_id)
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws UnknownHostException {
92855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        return getByAddressInternal(null, ipAddress, scope_id);
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static boolean isIPv4MappedAddress(byte ipAddress[]) {
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Check if the address matches ::FFFF:d.d.d.d
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The first 10 bytes are 0. The next to are -1 (FF).
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The last 4 bytes are varied.
93555b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        if (ipAddress == null || ipAddress.length != 16) {
93655b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti            return false;
93755b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        }
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < 10; i++) {
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ipAddress[i] != 0) {
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (ipAddress[10] != -1 || ipAddress[11] != -1) {
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
94955b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti    private static byte[] ipv4MappedToIPv4(byte[] mappedAddress) {
95055b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        byte[] ipv4Address = new byte[4];
95155b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        for(int i = 0; i < 4; i++) {
95255b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti            ipv4Address[i] = mappedAddress[12 + i];
95355b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        }
95455b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        return ipv4Address;
95555b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti    }
95655b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the {@code InetAddress} corresponding to the array of bytes, and
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the given hostname. In the case of an IPv4 address there must be exactly
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code
961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * UnknownHostException} will be thrown.
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The host name and IP address are not validated.
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The hostname either be a machine alias or a valid IPv6 or IPv4 address
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * format.
967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The high order byte is {@code ipAddress[0]}.
969f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param hostName
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string representation of hostname or IP address.
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ipAddress
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            either a 4 (IPv4) or 16 (IPv6) byte long array.
974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return an {@code InetAddress} instance representing the given IP address
975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         and hostname.
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given byte array has no valid length.
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static InetAddress getByAddress(String hostName, byte[] ipAddress)
980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws UnknownHostException {
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // just call the method by the same name passing in a default scope id
982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // of 0
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getByAddressInternal(hostName, ipAddress, 0);
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the {@code InetAddress} corresponding to the array of bytes, and
988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the given hostname. In the case of an IPv4 address there must be exactly
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 4 bytes and for IPv6 exactly 16 bytes. If not, an {@code
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * UnknownHostException} is thrown. The host name and IP address are not
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * validated. The hostname either be a machine alias or a valid IPv6 or IPv4
992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address format. The high order byte is {@code ipAddress[0]}.
993f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param hostName
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            string representation of hostname or IP address.
996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ipAddress
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            either a 4 (IPv4) or 16 (IPv6) byte array.
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param scope_id
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the scope id for a scoped address. If not a scoped address
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            just pass in 0.
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the InetAddress
1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static InetAddress getByAddressInternal(String hostName, byte[] ipAddress,
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int scope_id) throws UnknownHostException {
100655b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        if (ipAddress == null) {
1007511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            // We don't throw NullPointerException here for RI compatibility,
1008511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            // but we do say "address is null" (K0331), instead of "addr is of
1009511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            // illegal length".
1010511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti            throw new UnknownHostException(
1011511ab05f7731dffa3480cbd0b79836b231f77ef6Lorenzo Colitti                Msg.getString("K0331", hostName)); //$NON-NLS-1$
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
101355b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti        switch (ipAddress.length) {
101455b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti            case 4:
101555b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                return new Inet4Address(ipAddress.clone());
101655b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti            case 16:
101755b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                // First check to see if the address is an IPv6-mapped
101855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                // IPv4 address. If it is, then we can make it a IPv4
101955b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                // address, otherwise, we'll create an IPv6 address.
102055b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                if (isIPv4MappedAddress(ipAddress)) {
102155b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                    return new Inet4Address(ipv4MappedToIPv4(ipAddress));
102255b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                } else {
102355b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                    return new Inet6Address(ipAddress.clone(), scope_id);
102455b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                }
102555b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti            default:
102655b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                if (hostName != null) {
102755b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                    // "Invalid IP Address is neither 4 or 16 bytes: <hostName>"
102855b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                    throw new UnknownHostException(
102955b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                            Msg.getString("K0332", hostName)); //$NON-NLS-1$
103055b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                } else {
103155b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                    // "Invalid IP Address is neither 4 or 16 bytes"
103255b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                    throw new UnknownHostException(
103355b49708e6a5f5f5047513b67094257b32ff9e93Lorenzo Colitti                            Msg.getString("K0339")); //$NON-NLS-1$
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Takes the integer and chops it into 4 bytes, putting it into the byte
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array starting with the high order byte at the index start. This method
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * makes no checks on the validity of the parameters.
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static void intToBytes(int value, byte bytes[], int start) {
1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Shift the int so the current byte is right-most
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Use a byte mask of 255 to single out the last byte.
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bytes[start] = (byte) ((value >> 24) & 255);
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bytes[start + 1] = (byte) ((value >> 16) & 255);
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bytes[start + 2] = (byte) ((value >> 8) & 255);
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bytes[start + 3] = (byte) (value & 255);
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Takes the byte array and creates an integer out of four bytes starting at
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * start as the high-order byte. This method makes no checks on the validity
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of the parameters.
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static int bytesToInt(byte bytes[], int start) {
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // First mask the byte with 255, as when a negative
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // signed byte converts to an integer, it has bits
1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // on in the first 3 bytes, we are only concerned
1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // about the right-most 8 bits.
1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Then shift the rightmost byte to align with its
1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // position in the integer.
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int value = ((bytes[start + 3] & 255))
1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                | ((bytes[start + 2] & 255) << 8)
1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                | ((bytes[start + 1] & 255) << 16)
1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                | ((bytes[start] & 255) << 24);
1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return value;
1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final ObjectStreamField[] serialPersistentFields = {
1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new ObjectStreamField("address", Integer.TYPE), //$NON-NLS-1$
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new ObjectStreamField("family", Integer.TYPE), //$NON-NLS-1$
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            new ObjectStreamField("hostName", String.class) }; //$NON-NLS-1$
1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void writeObject(ObjectOutputStream stream) throws IOException {
1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectOutputStream.PutField fields = stream.putFields();
1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (ipaddress == null) {
1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fields.put("address", 0); //$NON-NLS-1$
1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fields.put("address", bytesToInt(ipaddress, 0)); //$NON-NLS-1$
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fields.put("family", family); //$NON-NLS-1$
1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fields.put("hostName", hostName); //$NON-NLS-1$
1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        stream.writeFields();
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readObject(ObjectInputStream stream) throws IOException,
1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException {
1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ObjectInputStream.GetField fields = stream.readFields();
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int addr = fields.get("address", 0); //$NON-NLS-1$
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ipaddress = new byte[4];
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        intToBytes(addr, ipaddress, 0);
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        hostName = (String) fields.get("hostName", null); //$NON-NLS-1$
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        family = fields.get("family", 2); //$NON-NLS-1$
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
10995839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson    /*
11005839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson     * The spec requires that if we encounter a generic InetAddress in
11015839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson     * serialized form then we should interpret it as an Inet4 address.
11025839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson     */
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object readResolve() throws ObjectStreamException {
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new Inet4Address(ipaddress, hostName);
1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1107