19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.InetAddress;
20585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport java.net.Inet4Address;
21585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport java.net.Inet6Address;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.UnknownHostException;
23a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwaltimport java.util.Collection;
24fea17de7aaa5729d3111102b2734b158403d2780Jeff Sharkeyimport java.util.Locale;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
260a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport android.os.Parcel;
27585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport android.util.Log;
288c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colittiimport android.util.Pair;
298c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
30585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Native methods for managing network interfaces.
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class NetworkUtils {
37585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
38585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    private static final String TAG = "NetworkUtils";
39585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
408171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /** Setting bit 0 indicates reseting of IPv4 addresses required */
418171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public static final int RESET_IPV4_ADDRESSES = 0x01;
428171e6f690cca1bad354e7e352823d79d420daf3Wink Saville
438171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /** Setting bit 1 indicates reseting of IPv4 addresses required */
448171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public static final int RESET_IPV6_ADDRESSES = 0x02;
458171e6f690cca1bad354e7e352823d79d420daf3Wink Saville
468171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /** Reset all addresses */
478171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public static final int RESET_ALL_ADDRESSES = RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES;
488171e6f690cca1bad354e7e352823d79d420daf3Wink Saville
498171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /**
508171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     * Reset IPv6 or IPv4 sockets that are connected via the named interface.
518171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     *
528171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     * @param interfaceName is the interface to reset
538171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     * @param mask {@see #RESET_IPV4_ADDRESSES} and {@see #RESET_IPV6_ADDRESSES}
548171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     */
558171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public native static int resetConnections(String interfaceName, int mask);
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Start the DHCP client daemon, in order to have it request addresses
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for the named interface, and then configure the interface with those
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * addresses. This call blocks until it obtains a result (either success
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or failure) from the daemon.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface to configure
634717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt     * @param dhcpResults if the request succeeds, this object is filled in with
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the IP address information.
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
674717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    public native static boolean runDhcp(String interfaceName, DhcpResults dhcpResults);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
70914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * Initiate renewal on the Dhcp client daemon. This call blocks until it obtains
71914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * a result (either success or failure) from the daemon.
72914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * @param interfaceName the name of the interface to configure
734717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt     * @param dhcpResults if the request succeeds, this object is filled in with
74914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * the IP address information.
75914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * @return {@code true} for success, {@code false} for failure
76914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     */
774717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    public native static boolean runDhcpRenew(String interfaceName, DhcpResults dhcpResults);
78914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff
79914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff    /**
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shut down the DHCP client daemon.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface for which the daemon
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should be stopped
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean stopDhcp(String interfaceName);
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Release the current DHCP lease.
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface for which the lease should
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be released
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean releaseDhcpLease(String interfaceName);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the last DHCP-related error message that was recorded.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p/>NOTE: This string is not localized, but currently it is only
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * used in logging.
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the most recent error message, if any
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static String getDhcpError();
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1043876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Binds the current process to the network designated by {@code netId}.  All sockets created
1053876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * in the future (and not explicitly bound via a bound {@link SocketFactory} (see
1066d3ff9ea3a542a18ca5da055418a7b9eff130d93Paul Jensen     * {@link Network#getSocketFactory}) will be bound to this network.  Note that if this
1073876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * {@code Network} ever disconnects all sockets created in this way will cease to work.  This
1083876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * is by design so an application doesn't accidentally use sockets it thinks are still bound to
109bcc76d345cdad2eff0f64d1dca9f92f94c8b9f07Paul Jensen     * a particular {@code Network}.  Passing NETID_UNSET clears the binding.
1103876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
11132a58f00d388584f5f47c0d5d4c74ce7c8457d78Paul Jensen    public native static boolean bindProcessToNetwork(int netId);
1123876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1133876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1143876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
1153876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
1163876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
1173876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    public native static int getNetworkBoundToProcess();
1183876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1193876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1203876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Binds host resolutions performed by this process to the network designated by {@code netId}.
121bcc76d345cdad2eff0f64d1dca9f92f94c8b9f07Paul Jensen     * {@link #bindProcessToNetwork} takes precedence over this setting.  Passing NETID_UNSET clears
122bcc76d345cdad2eff0f64d1dca9f92f94c8b9f07Paul Jensen     * the binding.
1233876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     *
1243876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
1253876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
12632a58f00d388584f5f47c0d5d4c74ce7c8457d78Paul Jensen    public native static boolean bindProcessToNetworkForHostResolution(int netId);
1273876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1283876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1293876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Explicitly binds {@code socketfd} to the network designated by {@code netId}.  This
1303876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * overrides any binding via {@link #bindProcessToNetwork}.
1319f1274b7e43d14c7e3a42148ebfda3905fec8b06Lorenzo Colitti     * @return 0 on success or negative errno on failure.
1323876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
1339f1274b7e43d14c7e3a42148ebfda3905fec8b06Lorenzo Colitti    public native static int bindSocketToNetwork(int socketfd, int netId);
1343876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1353876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1366bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     * Protect {@code socketfd} from VPN connections.  After protecting, data sent through
1376bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     * this socket will go directly to the underlying network, so its traffic will not be
1386bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     * forwarded through the VPN.
1396bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     */
1406bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public native static boolean protectFromVpn(int socketfd);
1416bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
1426bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    /**
143585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Convert a IPv4 address from an integer to an InetAddress.
14407481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     * @param hostAddress an int corresponding to the IPv4 address in network byte order
145585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
146585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public static InetAddress intToInetAddress(int hostAddress) {
147585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        byte[] addressBytes = { (byte)(0xff & hostAddress),
148585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 8)),
149585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 16)),
150585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 24)) };
15147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
15307481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson           return InetAddress.getByAddress(addressBytes);
15407481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson        } catch (UnknownHostException e) {
15507481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson           throw new AssertionError();
156585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
157585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    }
158585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
15996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /**
16096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * Convert a IPv4 address from an InetAddress to an integer
16196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @param inetAddr is an InetAddress corresponding to the IPv4 address
16296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @return the IP address as an integer in network byte order
16396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     */
1644717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    public static int inetAddressToInt(Inet4Address inetAddr)
16596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throws IllegalArgumentException {
16696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        byte [] addr = inetAddr.getAddress();
16796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
16896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
16996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
17096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
17196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /**
17296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * Convert a network prefix length to an IPv4 netmask integer
17396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @param prefixLength
17496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @return the IPv4 netmask as an integer in network byte order
17596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     */
17696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    public static int prefixLengthToNetmaskInt(int prefixLength)
17796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throws IllegalArgumentException {
17896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (prefixLength < 0 || prefixLength > 32) {
17996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
18096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
18196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        int value = 0xffffffff << (32 - prefixLength);
18296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        return Integer.reverseBytes(value);
18396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
18496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
1850216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    /**
18659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * Convert a IPv4 netmask integer to a prefix length
18759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @param netmask as an integer in network byte order
18859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @return the network prefix length
18959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     */
19059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    public static int netmaskIntToPrefixLength(int netmask) {
19159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        return Integer.bitCount(netmask);
19259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
19359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
19459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    /**
1950216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * Create an InetAddress from a string where the string must be a standard
1960216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * representation of a V4 or V6 address.  Avoids doing a DNS lookup on failure
1970216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * but it will throw an IllegalArgumentException in that case.
1980216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @param addrString
1990216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @return the InetAddress
2000216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @hide
2010216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     */
2020216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    public static InetAddress numericToInetAddress(String addrString)
2030216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            throws IllegalArgumentException {
204f5bbb5720454742e0e2f6ae489fa164845261cbfElliott Hughes        return InetAddress.parseNumericAddress(addrString);
2050216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    }
2060216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt
207585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
2080a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti     * Writes an InetAddress to a parcel. The address may be null. This is likely faster than
2090a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti     * calling writeSerializable.
2100a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti     */
2110a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti    protected static void parcelInetAddress(Parcel parcel, InetAddress address, int flags) {
2120a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        byte[] addressArray = (address != null) ? address.getAddress() : null;
2130a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        parcel.writeByteArray(addressArray);
2140a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti    }
2150a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti
2160a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti    /**
2170a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti     * Reads an InetAddress from a parcel. Returns null if the address that was written was null
2180a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti     * or if the data is invalid.
2190a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti     */
2200a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti    protected static InetAddress unparcelInetAddress(Parcel in) {
2210a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        byte[] addressArray = in.createByteArray();
2220a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        if (addressArray == null) {
2230a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti            return null;
2240a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        }
2250a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        try {
2260a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti            return InetAddress.getByAddress(addressArray);
2270a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        } catch (UnknownHostException e) {
2280a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti            return null;
2290a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti        }
2300a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti    }
2310a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti
2320a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti
2330a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti    /**
2348c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     *  Masks a raw IP address byte array with the specified prefix length.
235f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     */
2368c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public static void maskRawAddress(byte[] array, int prefixLength) {
237f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if (prefixLength < 0 || prefixLength > array.length * 8) {
2388c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            throw new RuntimeException("IP address with " + array.length +
2398c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti                    " bytes has invalid prefix length " + prefixLength);
240f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
241f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
242f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        int offset = prefixLength / 8;
2438c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        int remainder = prefixLength % 8;
2448c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        byte mask = (byte)(0xFF << (8 - remainder));
245f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
246f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if (offset < array.length) array[offset] = (byte)(array[offset] & mask);
247f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
248f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        offset++;
249f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
250f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        for (; offset < array.length; offset++) {
251f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            array[offset] = 0;
252f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
2538c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    }
2548c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2558c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    /**
2568c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Get InetAddress masked with prefixLength.  Will never return null.
2578c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @param address the IP address to mask with
2588c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @param prefixLength the prefixLength used to mask the IP
2598c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     */
2608c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public static InetAddress getNetworkPart(InetAddress address, int prefixLength) {
2618c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        byte[] array = address.getAddress();
2628c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        maskRawAddress(array, prefixLength);
263f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
264f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        InetAddress netPart = null;
265f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        try {
266f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            netPart = InetAddress.getByAddress(array);
267f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        } catch (UnknownHostException e) {
268f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            throw new RuntimeException("getNetworkPart error - " + e.toString());
269f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
270f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return netPart;
271f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
272f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
273f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    /**
2748c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Utility method to parse strings such as "192.0.2.5/24" or "2001:db8::cafe:d00d/64".
2758c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @hide
2768c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     */
2778c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public static Pair<InetAddress, Integer> parseIpAndMask(String ipAndMaskString) {
2788c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        InetAddress address = null;
2798c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        int prefixLength = -1;
2808c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        try {
2818c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            String[] pieces = ipAndMaskString.split("/", 2);
2828c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            prefixLength = Integer.parseInt(pieces[1]);
2838c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            address = InetAddress.parseNumericAddress(pieces[0]);
2848c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (NullPointerException e) {            // Null string.
2858c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (ArrayIndexOutOfBoundsException e) {  // No prefix length.
2868c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (NumberFormatException e) {           // Non-numeric prefix.
2878c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (IllegalArgumentException e) {        // Invalid IP address.
2888c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        }
2898c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2908c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        if (address == null || prefixLength == -1) {
2918c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            throw new IllegalArgumentException("Invalid IP address and mask " + ipAndMaskString);
2928c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        }
2938c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2948c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        return new Pair<InetAddress, Integer>(address, prefixLength);
2958c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    }
2968c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2978c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    /**
298f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * Check if IP address type is consistent between two InetAddress.
299f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @return true if both are the same type.  False otherwise.
300f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     */
301f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    public static boolean addressTypeMatches(InetAddress left, InetAddress right) {
302f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) ||
303f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                ((left instanceof Inet6Address) && (right instanceof Inet6Address)));
304f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
30559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
30659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    /**
30759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * Convert a 32 char hex string into a Inet6Address.
30859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be
30959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * made into an Inet6Address
31059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @param addrHexString a 32 character hex string representing an IPv6 addr
31159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @return addr an InetAddress representation for the string
31259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     */
31359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    public static InetAddress hexToInet6Address(String addrHexString)
31459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            throws IllegalArgumentException {
31559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        try {
316fea17de7aaa5729d3111102b2734b158403d2780Jeff Sharkey            return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s",
31759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(0,4),   addrHexString.substring(4,8),
31859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(8,12),  addrHexString.substring(12,16),
31959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(16,20), addrHexString.substring(20,24),
32059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(24,28), addrHexString.substring(28,32)));
32159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        } catch (Exception e) {
32259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            Log.e("NetworkUtils", "error in hexToInet6Address(" + addrHexString + "): " + e);
32359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            throw new IllegalArgumentException(e);
32459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
32559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
326a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt
327a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    /**
328a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     * Create a string array of host addresses from a collection of InetAddresses
329a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     * @param addrs a Collection of InetAddresses
330a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     * @return an array of Strings containing their host addresses
331a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     */
332a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    public static String[] makeStrings(Collection<InetAddress> addrs) {
333a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        String[] result = new String[addrs.size()];
334a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        int i = 0;
335a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        for (InetAddress addr : addrs) {
336a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            result[i++] = addr.getHostAddress();
337a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        }
338a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        return result;
339a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    }
340d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt
341d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt    /**
342d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * Trim leading zeros from IPv4 address strings
343d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * Our base libraries will interpret that as octel..
344d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * Must leave non v4 addresses and host names alone.
345d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * For example, 192.168.000.010 -> 192.168.0.10
346d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * TODO - fix base libraries and remove this function
347d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * @param addr a string representing an ip addr
348d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * @return a string propertly trimmed
349d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     */
350d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt    public static String trimV4AddrZeros(String addr) {
3510faacf0658af00929481fa158f0c88289ba5145fRobert Greenwalt        if (addr == null) return null;
352d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        String[] octets = addr.split("\\.");
353d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        if (octets.length != 4) return addr;
354d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        StringBuilder builder = new StringBuilder(16);
355d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        String result = null;
356d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        for (int i = 0; i < 4; i++) {
357d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            try {
3583957b5fc49335f13b15080b8e7146580026c0479Robert Greenwalt                if (octets[i].length() > 3) return addr;
359d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt                builder.append(Integer.parseInt(octets[i]));
360d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            } catch (NumberFormatException e) {
361d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt                return addr;
362d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            }
363d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            if (i < 3) builder.append('.');
364d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        }
365d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        result = builder.toString();
366d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        return result;
367d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt    }
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
369