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