1 /* 2 * Copyright (C) 2018 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 package android.net; 17 18 import android.Manifest; 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.RequiresPermission; 22 import android.annotation.SystemApi; 23 import android.os.IBinder; 24 import android.os.RemoteException; 25 26 import java.util.ArrayList; 27 import java.util.Arrays; 28 import java.util.Collection; 29 import java.util.List; 30 import java.util.Objects; 31 32 /** 33 * Class that allows creation and management of per-app, test-only networks 34 * 35 * @hide 36 */ 37 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 38 public class TestNetworkManager { 39 /** 40 * Prefix for tun interfaces created by this class. 41 * @hide 42 */ 43 public static final String TEST_TUN_PREFIX = "testtun"; 44 45 /** 46 * Prefix for tap interfaces created by this class. 47 */ 48 public static final String TEST_TAP_PREFIX = "testtap"; 49 50 /** 51 * Prefix for clat interfaces. 52 * @hide 53 */ 54 public static final String CLAT_INTERFACE_PREFIX = "v4-"; 55 56 @NonNull private static final String TAG = TestNetworkManager.class.getSimpleName(); 57 58 @NonNull private final ITestNetworkManager mService; 59 60 private static final boolean TAP = false; 61 private static final boolean TUN = true; 62 private static final boolean BRING_UP = true; 63 private static final boolean CARRIER_UP = true; 64 // sets disableIpv6ProvisioningDelay to false. 65 private static final boolean USE_IPV6_PROV_DELAY = false; 66 private static final LinkAddress[] NO_ADDRS = new LinkAddress[0]; 67 68 /** @hide */ TestNetworkManager(@onNull ITestNetworkManager service)69 public TestNetworkManager(@NonNull ITestNetworkManager service) { 70 mService = Objects.requireNonNull(service, "missing ITestNetworkManager"); 71 } 72 73 /** 74 * Teardown the capability-limited, testing-only network for a given interface 75 * 76 * @param network The test network that should be torn down 77 * @hide 78 */ 79 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) 80 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) teardownTestNetwork(@onNull Network network)81 public void teardownTestNetwork(@NonNull Network network) { 82 try { 83 mService.teardownTestNetwork(network.netId); 84 } catch (RemoteException e) { 85 throw e.rethrowFromSystemServer(); 86 } 87 } 88 setupTestNetwork( @onNull String iface, @Nullable LinkProperties lp, boolean isMetered, @NonNull int[] administratorUids, @NonNull IBinder binder)89 private void setupTestNetwork( 90 @NonNull String iface, 91 @Nullable LinkProperties lp, 92 boolean isMetered, 93 @NonNull int[] administratorUids, 94 @NonNull IBinder binder) { 95 try { 96 mService.setupTestNetwork(iface, lp, isMetered, administratorUids, binder); 97 } catch (RemoteException e) { 98 throw e.rethrowFromSystemServer(); 99 } 100 } 101 102 /** 103 * Sets up a capability-limited, testing-only network for a given interface 104 * 105 * @param lp The LinkProperties for the TestNetworkService to use for this test network. Note 106 * that the interface name and link addresses will be overwritten, and the passed-in values 107 * discarded. 108 * @param isMetered Whether or not the network should be considered metered. 109 * @param binder A binder object guarding the lifecycle of this test network. 110 * @hide 111 */ setupTestNetwork( @onNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder)112 public void setupTestNetwork( 113 @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) { 114 Objects.requireNonNull(lp, "Invalid LinkProperties"); 115 setupTestNetwork(lp.getInterfaceName(), lp, isMetered, new int[0], binder); 116 } 117 118 /** 119 * Sets up a capability-limited, testing-only network for a given interface 120 * 121 * @param iface the name of the interface to be used for the Network LinkProperties. 122 * @param binder A binder object guarding the lifecycle of this test network. 123 * @hide 124 */ 125 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) 126 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) setupTestNetwork(@onNull String iface, @NonNull IBinder binder)127 public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) { 128 setupTestNetwork(iface, null, true, new int[0], binder); 129 } 130 131 /** 132 * Sets up a capability-limited, testing-only network for a given interface with the given 133 * administrator UIDs. 134 * 135 * @param iface the name of the interface to be used for the Network LinkProperties. 136 * @param administratorUids The administrator UIDs to be used for the test-only network 137 * @param binder A binder object guarding the lifecycle of this test network. 138 * @hide 139 */ setupTestNetwork( @onNull String iface, @NonNull int[] administratorUids, @NonNull IBinder binder)140 public void setupTestNetwork( 141 @NonNull String iface, @NonNull int[] administratorUids, @NonNull IBinder binder) { 142 setupTestNetwork(iface, null, true, administratorUids, binder); 143 } 144 145 /** 146 * Create a tun interface for testing purposes 147 * 148 * @param linkAddrs an array of LinkAddresses to assign to the TUN interface 149 * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the 150 * TUN interface. 151 * @deprecated Use {@link #createTunInterface(Collection)} instead. 152 * @hide 153 */ 154 @Deprecated 155 @NonNull createTunInterface(@onNull LinkAddress[] linkAddrs)156 public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) { 157 return createTunInterface(Arrays.asList(linkAddrs)); 158 } 159 160 /** 161 * Create a tun interface for testing purposes 162 * 163 * @param linkAddrs an array of LinkAddresses to assign to the TUN interface 164 * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the 165 * TUN interface. 166 * @hide 167 */ 168 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) 169 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 170 @NonNull createTunInterface(@onNull Collection<LinkAddress> linkAddrs)171 public TestNetworkInterface createTunInterface(@NonNull Collection<LinkAddress> linkAddrs) { 172 try { 173 final LinkAddress[] arr = new LinkAddress[linkAddrs.size()]; 174 return mService.createInterface(TUN, CARRIER_UP, BRING_UP, USE_IPV6_PROV_DELAY, 175 linkAddrs.toArray(arr), null /* iface */); 176 } catch (RemoteException e) { 177 throw e.rethrowFromSystemServer(); 178 } 179 } 180 181 /** 182 * Create a tap interface for testing purposes 183 * 184 * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the 185 * TAP interface. 186 * @hide 187 */ 188 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) 189 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 190 @NonNull createTapInterface()191 public TestNetworkInterface createTapInterface() { 192 try { 193 return mService.createInterface(TAP, CARRIER_UP, BRING_UP, USE_IPV6_PROV_DELAY, 194 NO_ADDRS, null /* iface */); 195 } catch (RemoteException e) { 196 throw e.rethrowFromSystemServer(); 197 } 198 } 199 200 /** 201 * Create a tap interface with a given interface name for testing purposes 202 * 203 * @param bringUp whether to bring up the interface before returning it. 204 * @param iface interface name to be assigned, so far only interface name which starts with 205 * "v4-testtap" or "v4-testtun" is allowed to be created. If it's null, then use 206 * the default name(e.g. testtap or testtun). 207 * 208 * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the 209 * TAP interface. 210 * @hide 211 */ 212 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) 213 @NonNull createTapInterface(boolean bringUp, @NonNull String iface)214 public TestNetworkInterface createTapInterface(boolean bringUp, @NonNull String iface) { 215 try { 216 return mService.createInterface(TAP, CARRIER_UP, bringUp, USE_IPV6_PROV_DELAY, 217 NO_ADDRS, iface); 218 } catch (RemoteException e) { 219 throw e.rethrowFromSystemServer(); 220 } 221 } 222 223 /** 224 * Create a tap interface for testing purposes. 225 * 226 * Note: setting carrierUp = false is not supported until kernel version 6.0. 227 * 228 * @param carrierUp whether the created interface has a carrier or not. 229 * @param bringUp whether to bring up the interface before returning it. 230 * @param disableIpv6ProvisioningDelay whether to disable DAD and RS delay. 231 * @hide 232 */ 233 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) 234 @NonNull createTapInterface(boolean carrierUp, boolean bringUp, boolean disableIpv6ProvisioningDelay)235 public TestNetworkInterface createTapInterface(boolean carrierUp, boolean bringUp, 236 boolean disableIpv6ProvisioningDelay) { 237 try { 238 return mService.createInterface(TAP, carrierUp, bringUp, disableIpv6ProvisioningDelay, 239 NO_ADDRS, null /* iface */); 240 } catch (RemoteException e) { 241 throw e.rethrowFromSystemServer(); 242 } 243 } 244 245 /** 246 * Enable / disable carrier on TestNetworkInterface 247 * 248 * Note: TUNSETCARRIER is not supported until kernel version 5.0. 249 * 250 * @param iface the interface to configure. 251 * @param enabled true to turn carrier on, false to turn carrier off. 252 * @hide 253 */ 254 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) setCarrierEnabled(@onNull TestNetworkInterface iface, boolean enabled)255 public void setCarrierEnabled(@NonNull TestNetworkInterface iface, boolean enabled) { 256 try { 257 mService.setCarrierEnabled(iface, enabled); 258 } catch (RemoteException e) { 259 throw e.rethrowFromSystemServer(); 260 } 261 } 262 263 /** 264 * Represents a request to create a tun/tap interface for testing. 265 * 266 * @hide 267 */ 268 public static class TestInterfaceRequest { 269 public final boolean isTun; 270 public final boolean hasCarrier; 271 public final boolean bringUp; 272 public final boolean disableIpv6ProvDelay; 273 @Nullable public final String ifname; 274 public final LinkAddress[] linkAddresses; 275 TestInterfaceRequest(boolean isTun, boolean hasCarrier, boolean bringUp, boolean disableProvDelay, @Nullable String ifname, LinkAddress[] linkAddresses)276 private TestInterfaceRequest(boolean isTun, boolean hasCarrier, boolean bringUp, 277 boolean disableProvDelay, @Nullable String ifname, LinkAddress[] linkAddresses) { 278 this.isTun = isTun; 279 this.hasCarrier = hasCarrier; 280 this.bringUp = bringUp; 281 this.disableIpv6ProvDelay = disableProvDelay; 282 this.ifname = ifname; 283 this.linkAddresses = linkAddresses; 284 } 285 286 /** 287 * Builder class for TestInterfaceRequest 288 * 289 * Defaults to a tap interface with carrier that has been brought up. 290 */ 291 public static class Builder { 292 private boolean mIsTun = false; 293 private boolean mHasCarrier = true; 294 private boolean mBringUp = true; 295 private boolean mDisableIpv6ProvDelay = false; 296 @Nullable private String mIfname; 297 private List<LinkAddress> mLinkAddresses = new ArrayList<>(); 298 299 /** Create tun interface. */ setTun()300 public Builder setTun() { 301 mIsTun = true; 302 return this; 303 } 304 305 /** Create tap interface. */ setTap()306 public Builder setTap() { 307 mIsTun = false; 308 return this; 309 } 310 311 /** Configure whether the interface has carrier. */ setHasCarrier(boolean hasCarrier)312 public Builder setHasCarrier(boolean hasCarrier) { 313 mHasCarrier = hasCarrier; 314 return this; 315 } 316 317 /** Configure whether the interface should be brought up. */ setBringUp(boolean bringUp)318 public Builder setBringUp(boolean bringUp) { 319 mBringUp = bringUp; 320 return this; 321 } 322 323 /** Disable DAD and RS delay. */ setDisableIpv6ProvisioningDelay(boolean disableProvDelay)324 public Builder setDisableIpv6ProvisioningDelay(boolean disableProvDelay) { 325 mDisableIpv6ProvDelay = disableProvDelay; 326 return this; 327 } 328 329 /** Set the interface name. */ setInterfaceName(@ullable String ifname)330 public Builder setInterfaceName(@Nullable String ifname) { 331 mIfname = ifname; 332 return this; 333 } 334 335 /** The addresses to configure on the interface. */ addLinkAddress(LinkAddress la)336 public Builder addLinkAddress(LinkAddress la) { 337 mLinkAddresses.add(la); 338 return this; 339 } 340 341 /** Build TestInterfaceRequest */ build()342 public TestInterfaceRequest build() { 343 return new TestInterfaceRequest(mIsTun, mHasCarrier, mBringUp, 344 mDisableIpv6ProvDelay, mIfname, mLinkAddresses.toArray(new LinkAddress[0])); 345 } 346 } 347 } 348 349 /** 350 * Create a TestNetworkInterface (tun or tap) for testing purposes. 351 * 352 * @param request The request describing the interface to create. 353 * @return A TestNetworkInterface representing the underlying tun/tap interface. Close the 354 * contained ParcelFileDescriptor to tear down the tun/tap interface. 355 * @hide 356 */ 357 @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) 358 @NonNull createTestInterface(@onNull TestInterfaceRequest request)359 public TestNetworkInterface createTestInterface(@NonNull TestInterfaceRequest request) { 360 try { 361 // TODO: Make TestInterfaceRequest parcelable and pass it instead. 362 return mService.createInterface(request.isTun, request.hasCarrier, request.bringUp, 363 request.disableIpv6ProvDelay, request.linkAddresses, request.ifname); 364 } catch (RemoteException e) { 365 throw e.rethrowFromSystemServer(); 366 } 367 } 368 } 369