• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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