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