NetworkUtils.java revision 59b1a4ede7032c1b4d897e13dd4ede09b5e14743
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.net; 18 19import java.net.InetAddress; 20import java.net.Inet4Address; 21import java.net.Inet6Address; 22import java.net.UnknownHostException; 23 24import android.util.Log; 25 26/** 27 * Native methods for managing network interfaces. 28 * 29 * {@hide} 30 */ 31public class NetworkUtils { 32 33 private static final String TAG = "NetworkUtils"; 34 35 /** Bring the named network interface up. */ 36 public native static int enableInterface(String interfaceName); 37 38 /** Bring the named network interface down. */ 39 public native static int disableInterface(String interfaceName); 40 41 /** Reset any sockets that are connected via the named interface. */ 42 public native static int resetConnections(String interfaceName); 43 44 /** 45 * Start the DHCP client daemon, in order to have it request addresses 46 * for the named interface, and then configure the interface with those 47 * addresses. This call blocks until it obtains a result (either success 48 * or failure) from the daemon. 49 * @param interfaceName the name of the interface to configure 50 * @param ipInfo if the request succeeds, this object is filled in with 51 * the IP address information. 52 * @return {@code true} for success, {@code false} for failure 53 */ 54 public native static boolean runDhcp(String interfaceName, DhcpInfoInternal ipInfo); 55 56 /** 57 * Initiate renewal on the Dhcp client daemon. This call blocks until it obtains 58 * a result (either success or failure) from the daemon. 59 * @param interfaceName the name of the interface to configure 60 * @param ipInfo if the request succeeds, this object is filled in with 61 * the IP address information. 62 * @return {@code true} for success, {@code false} for failure 63 */ 64 public native static boolean runDhcpRenew(String interfaceName, DhcpInfoInternal ipInfo); 65 66 /** 67 * Shut down the DHCP client daemon. 68 * @param interfaceName the name of the interface for which the daemon 69 * should be stopped 70 * @return {@code true} for success, {@code false} for failure 71 */ 72 public native static boolean stopDhcp(String interfaceName); 73 74 /** 75 * Release the current DHCP lease. 76 * @param interfaceName the name of the interface for which the lease should 77 * be released 78 * @return {@code true} for success, {@code false} for failure 79 */ 80 public native static boolean releaseDhcpLease(String interfaceName); 81 82 /** 83 * Return the last DHCP-related error message that was recorded. 84 * <p/>NOTE: This string is not localized, but currently it is only 85 * used in logging. 86 * @return the most recent error message, if any 87 */ 88 public native static String getDhcpError(); 89 90 /** 91 * Convert a IPv4 address from an integer to an InetAddress. 92 * @param hostAddress an int corresponding to the IPv4 address in network byte order 93 */ 94 public static InetAddress intToInetAddress(int hostAddress) { 95 byte[] addressBytes = { (byte)(0xff & hostAddress), 96 (byte)(0xff & (hostAddress >> 8)), 97 (byte)(0xff & (hostAddress >> 16)), 98 (byte)(0xff & (hostAddress >> 24)) }; 99 100 try { 101 return InetAddress.getByAddress(addressBytes); 102 } catch (UnknownHostException e) { 103 throw new AssertionError(); 104 } 105 } 106 107 /** 108 * Convert a IPv4 address from an InetAddress to an integer 109 * @param inetAddr is an InetAddress corresponding to the IPv4 address 110 * @return the IP address as an integer in network byte order 111 */ 112 public static int inetAddressToInt(InetAddress inetAddr) 113 throws IllegalArgumentException { 114 byte [] addr = inetAddr.getAddress(); 115 if (addr.length != 4) { 116 throw new IllegalArgumentException("Not an IPv4 address"); 117 } 118 return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) | 119 ((addr[1] & 0xff) << 8) | (addr[0] & 0xff); 120 } 121 122 /** 123 * Convert a network prefix length to an IPv4 netmask integer 124 * @param prefixLength 125 * @return the IPv4 netmask as an integer in network byte order 126 */ 127 public static int prefixLengthToNetmaskInt(int prefixLength) 128 throws IllegalArgumentException { 129 if (prefixLength < 0 || prefixLength > 32) { 130 throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)"); 131 } 132 int value = 0xffffffff << (32 - prefixLength); 133 return Integer.reverseBytes(value); 134 } 135 136 /** 137 * Convert a IPv4 netmask integer to a prefix length 138 * @param netmask as an integer in network byte order 139 * @return the network prefix length 140 */ 141 public static int netmaskIntToPrefixLength(int netmask) { 142 return Integer.bitCount(netmask); 143 } 144 145 /** 146 * Create an InetAddress from a string where the string must be a standard 147 * representation of a V4 or V6 address. Avoids doing a DNS lookup on failure 148 * but it will throw an IllegalArgumentException in that case. 149 * @param addrString 150 * @return the InetAddress 151 * @hide 152 */ 153 public static InetAddress numericToInetAddress(String addrString) 154 throws IllegalArgumentException { 155 return InetAddress.parseNumericAddress(addrString); 156 } 157 158 /** 159 * Get InetAddress masked with prefixLength. Will never return null. 160 * @param IP address which will be masked with specified prefixLength 161 * @param prefixLength the prefixLength used to mask the IP 162 */ 163 public static InetAddress getNetworkPart(InetAddress address, int prefixLength) { 164 if (address == null) { 165 throw new RuntimeException("getNetworkPart doesn't accept null address"); 166 } 167 168 byte[] array = address.getAddress(); 169 170 if (prefixLength < 0 || prefixLength > array.length * 8) { 171 throw new RuntimeException("getNetworkPart - bad prefixLength"); 172 } 173 174 int offset = prefixLength / 8; 175 int reminder = prefixLength % 8; 176 byte mask = (byte)(0xFF << (8 - reminder)); 177 178 if (offset < array.length) array[offset] = (byte)(array[offset] & mask); 179 180 offset++; 181 182 for (; offset < array.length; offset++) { 183 array[offset] = 0; 184 } 185 186 InetAddress netPart = null; 187 try { 188 netPart = InetAddress.getByAddress(array); 189 } catch (UnknownHostException e) { 190 throw new RuntimeException("getNetworkPart error - " + e.toString()); 191 } 192 return netPart; 193 } 194 195 /** 196 * Check if IP address type is consistent between two InetAddress. 197 * @return true if both are the same type. False otherwise. 198 */ 199 public static boolean addressTypeMatches(InetAddress left, InetAddress right) { 200 return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) || 201 ((left instanceof Inet6Address) && (right instanceof Inet6Address))); 202 } 203 204 /** 205 * Convert a 32 char hex string into a Inet6Address. 206 * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be 207 * made into an Inet6Address 208 * @param addrHexString a 32 character hex string representing an IPv6 addr 209 * @return addr an InetAddress representation for the string 210 */ 211 public static InetAddress hexToInet6Address(String addrHexString) 212 throws IllegalArgumentException { 213 try { 214 return numericToInetAddress(String.format("%s:%s:%s:%s:%s:%s:%s:%s", 215 addrHexString.substring(0,4), addrHexString.substring(4,8), 216 addrHexString.substring(8,12), addrHexString.substring(12,16), 217 addrHexString.substring(16,20), addrHexString.substring(20,24), 218 addrHexString.substring(24,28), addrHexString.substring(28,32))); 219 } catch (Exception e) { 220 Log.e("NetworkUtils", "error in hexToInet6Address(" + addrHexString + "): " + e); 221 throw new IllegalArgumentException(e); 222 } 223 } 224} 225