NetworkUtils.java revision bcc76d345cdad2eff0f64d1dca9f92f94c8b9f07
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
26585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport android.util.Log;
278c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colittiimport android.util.Pair;
288c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
29585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Native methods for managing network interfaces.
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class NetworkUtils {
36585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
37585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    private static final String TAG = "NetworkUtils";
38585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
390900f3657664d9046e6723825fd32b244eef2b6cMike Lockwood    /** Bring the named network interface up. */
400900f3657664d9046e6723825fd32b244eef2b6cMike Lockwood    public native static int enableInterface(String interfaceName);
410900f3657664d9046e6723825fd32b244eef2b6cMike Lockwood
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Bring the named network interface down. */
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static int disableInterface(String interfaceName);
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
458171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /** Setting bit 0 indicates reseting of IPv4 addresses required */
468171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public static final int RESET_IPV4_ADDRESSES = 0x01;
478171e6f690cca1bad354e7e352823d79d420daf3Wink Saville
488171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /** Setting bit 1 indicates reseting of IPv4 addresses required */
498171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public static final int RESET_IPV6_ADDRESSES = 0x02;
508171e6f690cca1bad354e7e352823d79d420daf3Wink Saville
518171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /** Reset all addresses */
528171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public static final int RESET_ALL_ADDRESSES = RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES;
538171e6f690cca1bad354e7e352823d79d420daf3Wink Saville
548171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    /**
558171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     * Reset IPv6 or IPv4 sockets that are connected via the named interface.
568171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     *
578171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     * @param interfaceName is the interface to reset
588171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     * @param mask {@see #RESET_IPV4_ADDRESSES} and {@see #RESET_IPV6_ADDRESSES}
598171e6f690cca1bad354e7e352823d79d420daf3Wink Saville     */
608171e6f690cca1bad354e7e352823d79d420daf3Wink Saville    public native static int resetConnections(String interfaceName, int mask);
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Start the DHCP client daemon, in order to have it request addresses
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for the named interface, and then configure the interface with those
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * addresses. This call blocks until it obtains a result (either success
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or failure) from the daemon.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface to configure
684717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt     * @param dhcpResults if the request succeeds, this object is filled in with
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the IP address information.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
724717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    public native static boolean runDhcp(String interfaceName, DhcpResults dhcpResults);
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
75914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * Initiate renewal on the Dhcp client daemon. This call blocks until it obtains
76914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * a result (either success or failure) from the daemon.
77914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * @param interfaceName the name of the interface to configure
784717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt     * @param dhcpResults if the request succeeds, this object is filled in with
79914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * the IP address information.
80914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     * @return {@code true} for success, {@code false} for failure
81914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff     */
824717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    public native static boolean runDhcpRenew(String interfaceName, DhcpResults dhcpResults);
83914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff
84914ed90f2c02092474d2db36626734ca1b2cf315Irfan Sheriff    /**
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shut down the DHCP client daemon.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface for which the daemon
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should be stopped
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean stopDhcp(String interfaceName);
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Release the current DHCP lease.
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interfaceName the name of the interface for which the lease should
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be released
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} for success, {@code false} for failure
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static boolean releaseDhcpLease(String interfaceName);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the last DHCP-related error message that was recorded.
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p/>NOTE: This string is not localized, but currently it is only
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * used in logging.
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the most recent error message, if any
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native static String getDhcpError();
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10912324b46049f9bcba9aa3d5fe7ae540d49a03076Chad Brubaker     * Set the SO_MARK of {@code socketfd} to {@code mark}
11012324b46049f9bcba9aa3d5fe7ae540d49a03076Chad Brubaker     */
11112324b46049f9bcba9aa3d5fe7ae540d49a03076Chad Brubaker    public native static void markSocket(int socketfd, int mark);
11212324b46049f9bcba9aa3d5fe7ae540d49a03076Chad Brubaker
11312324b46049f9bcba9aa3d5fe7ae540d49a03076Chad Brubaker    /**
1143876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Binds the current process to the network designated by {@code netId}.  All sockets created
1153876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * in the future (and not explicitly bound via a bound {@link SocketFactory} (see
1166d3ff9ea3a542a18ca5da055418a7b9eff130d93Paul Jensen     * {@link Network#getSocketFactory}) will be bound to this network.  Note that if this
1173876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * {@code Network} ever disconnects all sockets created in this way will cease to work.  This
1183876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * is by design so an application doesn't accidentally use sockets it thinks are still bound to
119bcc76d345cdad2eff0f64d1dca9f92f94c8b9f07Paul Jensen     * a particular {@code Network}.  Passing NETID_UNSET clears the binding.
1203876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
12132a58f00d388584f5f47c0d5d4c74ce7c8457d78Paul Jensen    public native static boolean bindProcessToNetwork(int netId);
1223876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1233876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1243876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
1253876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
1263876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
1273876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    public native static int getNetworkBoundToProcess();
1283876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1293876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1303876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Binds host resolutions performed by this process to the network designated by {@code netId}.
131bcc76d345cdad2eff0f64d1dca9f92f94c8b9f07Paul Jensen     * {@link #bindProcessToNetwork} takes precedence over this setting.  Passing NETID_UNSET clears
132bcc76d345cdad2eff0f64d1dca9f92f94c8b9f07Paul Jensen     * the binding.
1333876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     *
1343876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
1353876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
13632a58f00d388584f5f47c0d5d4c74ce7c8457d78Paul Jensen    public native static boolean bindProcessToNetworkForHostResolution(int netId);
1373876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1383876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1393876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * Explicitly binds {@code socketfd} to the network designated by {@code netId}.  This
1403876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     * overrides any binding via {@link #bindProcessToNetwork}.
1413876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen     */
14232a58f00d388584f5f47c0d5d4c74ce7c8457d78Paul Jensen    public native static boolean bindSocketToNetwork(int socketfd, int netId);
1433876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen
1443876495129cce3ed8ac6f247189b075dc9baec8fPaul Jensen    /**
1456bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     * Protect {@code socketfd} from VPN connections.  After protecting, data sent through
1466bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     * this socket will go directly to the underlying network, so its traffic will not be
1476bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     * forwarded through the VPN.
1486bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen     */
1496bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public native static boolean protectFromVpn(int socketfd);
1506bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
1516bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    /**
152585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Convert a IPv4 address from an integer to an InetAddress.
15307481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     * @param hostAddress an int corresponding to the IPv4 address in network byte order
154585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
155585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public static InetAddress intToInetAddress(int hostAddress) {
156585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        byte[] addressBytes = { (byte)(0xff & hostAddress),
157585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 8)),
158585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 16)),
159585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                                (byte)(0xff & (hostAddress >> 24)) };
16047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
16207481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson           return InetAddress.getByAddress(addressBytes);
16307481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson        } catch (UnknownHostException e) {
16407481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson           throw new AssertionError();
165585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
166585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    }
167585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
16896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /**
16996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * Convert a IPv4 address from an InetAddress to an integer
17096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @param inetAddr is an InetAddress corresponding to the IPv4 address
17196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @return the IP address as an integer in network byte order
17296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     */
1734717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    public static int inetAddressToInt(Inet4Address inetAddr)
17496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throws IllegalArgumentException {
17596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        byte [] addr = inetAddr.getAddress();
17696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
17796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff                ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
17896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
17996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
18096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    /**
18196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * Convert a network prefix length to an IPv4 netmask integer
18296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @param prefixLength
18396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     * @return the IPv4 netmask as an integer in network byte order
18496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff     */
18596ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    public static int prefixLengthToNetmaskInt(int prefixLength)
18696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throws IllegalArgumentException {
18796ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        if (prefixLength < 0 || prefixLength > 32) {
18896ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff            throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
18996ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        }
19096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        int value = 0xffffffff << (32 - prefixLength);
19196ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff        return Integer.reverseBytes(value);
19296ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff    }
19396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff
1940216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    /**
19559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * Convert a IPv4 netmask integer to a prefix length
19659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @param netmask as an integer in network byte order
19759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @return the network prefix length
19859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     */
19959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    public static int netmaskIntToPrefixLength(int netmask) {
20059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        return Integer.bitCount(netmask);
20159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
20259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
20359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    /**
2040216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * Create an InetAddress from a string where the string must be a standard
2050216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * representation of a V4 or V6 address.  Avoids doing a DNS lookup on failure
2060216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * but it will throw an IllegalArgumentException in that case.
2070216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @param addrString
2080216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @return the InetAddress
2090216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     * @hide
2100216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt     */
2110216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    public static InetAddress numericToInetAddress(String addrString)
2120216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt            throws IllegalArgumentException {
213f5bbb5720454742e0e2f6ae489fa164845261cbfElliott Hughes        return InetAddress.parseNumericAddress(addrString);
2140216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt    }
2150216e618198393bfd7ac0625fa6ad251d5ea682fRobert Greenwalt
216585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
2178c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     *  Masks a raw IP address byte array with the specified prefix length.
218f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     */
2198c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public static void maskRawAddress(byte[] array, int prefixLength) {
220f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if (prefixLength < 0 || prefixLength > array.length * 8) {
2218c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            throw new RuntimeException("IP address with " + array.length +
2228c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti                    " bytes has invalid prefix length " + prefixLength);
223f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
224f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
225f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        int offset = prefixLength / 8;
2268c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        int remainder = prefixLength % 8;
2278c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        byte mask = (byte)(0xFF << (8 - remainder));
228f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
229f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        if (offset < array.length) array[offset] = (byte)(array[offset] & mask);
230f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
231f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        offset++;
232f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
233f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        for (; offset < array.length; offset++) {
234f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            array[offset] = 0;
235f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
2368c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    }
2378c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2388c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    /**
2398c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Get InetAddress masked with prefixLength.  Will never return null.
2408c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @param address the IP address to mask with
2418c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @param prefixLength the prefixLength used to mask the IP
2428c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     */
2438c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public static InetAddress getNetworkPart(InetAddress address, int prefixLength) {
2448c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        byte[] array = address.getAddress();
2458c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        maskRawAddress(array, prefixLength);
246f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
247f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        InetAddress netPart = null;
248f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        try {
249f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            netPart = InetAddress.getByAddress(array);
250f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        } catch (UnknownHostException e) {
251f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            throw new RuntimeException("getNetworkPart error - " + e.toString());
252f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
253f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return netPart;
254f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
255f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
256f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    /**
2578c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * Utility method to parse strings such as "192.0.2.5/24" or "2001:db8::cafe:d00d/64".
2588c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     * @hide
2598c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti     */
2608c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    public static Pair<InetAddress, Integer> parseIpAndMask(String ipAndMaskString) {
2618c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        InetAddress address = null;
2628c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        int prefixLength = -1;
2638c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        try {
2648c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            String[] pieces = ipAndMaskString.split("/", 2);
2658c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            prefixLength = Integer.parseInt(pieces[1]);
2668c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            address = InetAddress.parseNumericAddress(pieces[0]);
2678c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (NullPointerException e) {            // Null string.
2688c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (ArrayIndexOutOfBoundsException e) {  // No prefix length.
2698c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (NumberFormatException e) {           // Non-numeric prefix.
2708c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        } catch (IllegalArgumentException e) {        // Invalid IP address.
2718c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        }
2728c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2738c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        if (address == null || prefixLength == -1) {
2748c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti            throw new IllegalArgumentException("Invalid IP address and mask " + ipAndMaskString);
2758c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        }
2768c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2778c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti        return new Pair<InetAddress, Integer>(address, prefixLength);
2788c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    }
2798c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti
2808c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti    /**
281f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * Check if IP address type is consistent between two InetAddress.
282f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     * @return true if both are the same type.  False otherwise.
283f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt     */
284f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    public static boolean addressTypeMatches(InetAddress left, InetAddress right) {
285f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) ||
286f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                ((left instanceof Inet6Address) && (right instanceof Inet6Address)));
287f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    }
28859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
28959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    /**
29059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * Convert a 32 char hex string into a Inet6Address.
29159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be
29259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * made into an Inet6Address
29359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @param addrHexString a 32 character hex string representing an IPv6 addr
29459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     * @return addr an InetAddress representation for the string
29559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt     */
29659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    public static InetAddress hexToInet6Address(String addrHexString)
29759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            throws IllegalArgumentException {
29859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        try {
299fea17de7aaa5729d3111102b2734b158403d2780Jeff Sharkey            return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s",
30059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(0,4),   addrHexString.substring(4,8),
30159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(8,12),  addrHexString.substring(12,16),
30259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(16,20), addrHexString.substring(20,24),
30359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    addrHexString.substring(24,28), addrHexString.substring(28,32)));
30459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        } catch (Exception e) {
30559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            Log.e("NetworkUtils", "error in hexToInet6Address(" + addrHexString + "): " + e);
30659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            throw new IllegalArgumentException(e);
30759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
30859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
309a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt
310a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    /**
311a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     * Create a string array of host addresses from a collection of InetAddresses
312a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     * @param addrs a Collection of InetAddresses
313a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     * @return an array of Strings containing their host addresses
314a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt     */
315a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    public static String[] makeStrings(Collection<InetAddress> addrs) {
316a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        String[] result = new String[addrs.size()];
317a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        int i = 0;
318a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        for (InetAddress addr : addrs) {
319a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            result[i++] = addr.getHostAddress();
320a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        }
321a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        return result;
322a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    }
323d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt
324d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt    /**
325d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * Trim leading zeros from IPv4 address strings
326d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * Our base libraries will interpret that as octel..
327d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * Must leave non v4 addresses and host names alone.
328d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * For example, 192.168.000.010 -> 192.168.0.10
329d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * TODO - fix base libraries and remove this function
330d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * @param addr a string representing an ip addr
331d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     * @return a string propertly trimmed
332d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt     */
333d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt    public static String trimV4AddrZeros(String addr) {
3340faacf0658af00929481fa158f0c88289ba5145fRobert Greenwalt        if (addr == null) return null;
335d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        String[] octets = addr.split("\\.");
336d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        if (octets.length != 4) return addr;
337d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        StringBuilder builder = new StringBuilder(16);
338d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        String result = null;
339d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        for (int i = 0; i < 4; i++) {
340d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            try {
3413957b5fc49335f13b15080b8e7146580026c0479Robert Greenwalt                if (octets[i].length() > 3) return addr;
342d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt                builder.append(Integer.parseInt(octets[i]));
343d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            } catch (NumberFormatException e) {
344d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt                return addr;
345d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            }
346d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt            if (i < 3) builder.append('.');
347d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        }
348d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        result = builder.toString();
349d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt        return result;
350d4420ab2fbb85280d2f507072fe0bd820ac26a3fRobert Greenwalt    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
352