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 
17 package com.android.server.ethernet;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.fail;
21 
22 import android.net.IpConfiguration;
23 import android.net.IpConfiguration.IpAssignment;
24 import android.net.IpConfiguration.ProxySettings;
25 import android.net.LinkAddress;
26 import android.net.NetworkCapabilities;
27 import android.net.StaticIpConfiguration;
28 
29 import androidx.test.filters.SmallTest;
30 import androidx.test.runner.AndroidJUnit4;
31 
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 
35 import java.net.InetAddress;
36 
37 @SmallTest
38 @RunWith(AndroidJUnit4.class)
39 public class EthernetTrackerTest {
40     /**
41      * Test: Creation of various valid static IP configurations
42      */
43     @Test
createStaticIpConfiguration()44     public void createStaticIpConfiguration() {
45         // Empty gives default StaticIPConfiguration object
46         assertStaticConfiguration(new StaticIpConfiguration(), "");
47 
48         // Setting only the IP address properly cascades and assumes defaults
49         assertStaticConfiguration(
50                 new StaticIpConfigBuilder().setIp("192.0.2.10/24").build(),
51                 "ip=192.0.2.10/24");
52 
53         // Setting other fields properly cascades them
54         assertStaticConfiguration(
55                 new StaticIpConfigBuilder()
56                         .setIp("192.0.2.10/24")
57                         .setDns(new String[] {"4.4.4.4", "8.8.8.8"})
58                         .setGateway("192.0.2.1")
59                         .setDomains("android")
60                         .build(),
61                 "ip=192.0.2.10/24 dns=4.4.4.4,8.8.8.8 gateway=192.0.2.1 domains=android");
62 
63         // Verify order doesn't matter
64         assertStaticConfiguration(
65                 new StaticIpConfigBuilder()
66                         .setIp("192.0.2.10/24")
67                         .setDns(new String[] {"4.4.4.4", "8.8.8.8"})
68                         .setGateway("192.0.2.1")
69                         .setDomains("android")
70                         .build(),
71                 "domains=android ip=192.0.2.10/24 gateway=192.0.2.1 dns=4.4.4.4,8.8.8.8 ");
72     }
73 
74     /**
75      * Test: Attempt creation of various bad static IP configurations
76      */
77     @Test
createStaticIpConfiguration_Bad()78     public void createStaticIpConfiguration_Bad() {
79         assertStaticConfigurationFails("ip=192.0.2.1/24 gateway= blah=20.20.20.20");  // Unknown key
80         assertStaticConfigurationFails("ip=192.0.2.1");  // mask is missing
81         assertStaticConfigurationFails("ip=a.b.c");  // not a valid ip address
82         assertStaticConfigurationFails("dns=4.4.4.4,1.2.3.A");  // not valid ip address in dns
83         assertStaticConfigurationFails("=");  // Key and value is empty
84         assertStaticConfigurationFails("ip=");  // Value is empty
85         assertStaticConfigurationFails("ip=192.0.2.1/24 gateway=");  // Gateway is empty
86     }
87 
assertStaticConfigurationFails(String config)88     private void assertStaticConfigurationFails(String config) {
89         try {
90             EthernetTracker.parseStaticIpConfiguration(config);
91             fail("Expected to fail: " + config);
92         } catch (IllegalArgumentException e) {
93             // expected
94         }
95     }
96 
assertStaticConfiguration(StaticIpConfiguration expectedStaticIpConfig, String configAsString)97     private void assertStaticConfiguration(StaticIpConfiguration expectedStaticIpConfig,
98                 String configAsString) {
99         IpConfiguration expectedIpConfiguration = new IpConfiguration(IpAssignment.STATIC,
100                 ProxySettings.NONE, expectedStaticIpConfig, null);
101 
102         assertEquals(expectedIpConfiguration,
103                 EthernetTracker.parseStaticIpConfiguration(configAsString));
104     }
105 
106     private static class StaticIpConfigBuilder {
107         private final StaticIpConfiguration config = new StaticIpConfiguration();
108 
setIp(String address)109         StaticIpConfigBuilder setIp(String address) {
110             config.ipAddress = new LinkAddress(address);
111             return this;
112         }
113 
setDns(String[] dnsArray)114         StaticIpConfigBuilder setDns(String[] dnsArray) {
115             for (String dns : dnsArray) {
116                 config.dnsServers.add(InetAddress.parseNumericAddress(dns));
117             }
118             return this;
119         }
120 
setGateway(String gateway)121         StaticIpConfigBuilder setGateway(String gateway) {
122             config.gateway = InetAddress.parseNumericAddress(gateway);
123             return this;
124         }
125 
setDomains(String domains)126         StaticIpConfigBuilder setDomains(String domains) {
127             config.domains = domains;
128             return this;
129         }
130 
build()131         StaticIpConfiguration build() {
132             return new StaticIpConfiguration(config);
133         }
134     }
135 
136     /**
137      * Test: Attempt to create a capabilties with various valid sets of capabilities/transports
138      */
139     @Test
createNetworkCapabilities()140     public void createNetworkCapabilities() {
141 
142         // Particularly common expected results
143         NetworkCapabilities defaultEthernetCleared = new NetworkCapabilitiesBuilder()
144                 .clearAll()
145                 .setLinkUpstreamBandwidthKbps(100000)
146                 .setLinkDownstreamBandwidthKbps(100000)
147                 .addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
148                 .build();
149 
150         NetworkCapabilities ethernetClearedWithCommonCaps = new NetworkCapabilitiesBuilder()
151                 .clearAll()
152                 .setLinkUpstreamBandwidthKbps(100000)
153                 .setLinkDownstreamBandwidthKbps(100000)
154                 .addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
155                 .addCapability(12)
156                 .addCapability(13)
157                 .addCapability(14)
158                 .addCapability(15)
159                 .build();
160 
161         // Empty capabilities and transports lists with a "please clear defaults" should
162         // yield an empty capabilities set with TRANPORT_ETHERNET
163         assertParsedNetworkCapabilities(defaultEthernetCleared, true, "", "");
164 
165         // Empty capabilities and transports without the clear defaults flag should return the
166         // default capabilities set with TRANSPORT_ETHERNET
167         assertParsedNetworkCapabilities(
168                 new NetworkCapabilitiesBuilder()
169                         .setLinkUpstreamBandwidthKbps(100000)
170                         .setLinkDownstreamBandwidthKbps(100000)
171                         .addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
172                         .build(),
173                 false, "", "");
174 
175         // A list of capabilities without the clear defaults flag should return the default
176         // capabilities, mixed with the desired capabilities, and TRANSPORT_ETHERNET
177         assertParsedNetworkCapabilities(
178                 new NetworkCapabilitiesBuilder()
179                         .setLinkUpstreamBandwidthKbps(100000)
180                         .setLinkDownstreamBandwidthKbps(100000)
181                         .addTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
182                         .addCapability(11)
183                         .addCapability(12)
184                         .build(),
185                 false, "11,12", "");
186 
187         // Adding a list of capabilities with a clear defaults will leave exactly those capabilities
188         // with a default TRANSPORT_ETHERNET since no overrides are specified
189         assertParsedNetworkCapabilities(ethernetClearedWithCommonCaps, true, "12,13,14,15", "");
190 
191         // Adding any invalid capabilities to the list will cause them to be ignored
192         assertParsedNetworkCapabilities(ethernetClearedWithCommonCaps, true, "12,13,14,15,65,73", "");
193         assertParsedNetworkCapabilities(ethernetClearedWithCommonCaps, true, "12,13,14,15,abcdefg", "");
194 
195         // Adding a valid override transport will remove the default TRANSPORT_ETHERNET transport
196         // and apply only the override to the capabiltities object
197         assertParsedNetworkCapabilities(
198                 new NetworkCapabilitiesBuilder()
199                         .clearAll()
200                         .setLinkUpstreamBandwidthKbps(100000)
201                         .setLinkDownstreamBandwidthKbps(100000)
202                         .addTransport(0)
203                         .build(),
204                 true, "", "0");
205         assertParsedNetworkCapabilities(
206                 new NetworkCapabilitiesBuilder()
207                         .clearAll()
208                         .setLinkUpstreamBandwidthKbps(100000)
209                         .setLinkDownstreamBandwidthKbps(100000)
210                         .addTransport(1)
211                         .build(),
212                 true, "", "1");
213         assertParsedNetworkCapabilities(
214                 new NetworkCapabilitiesBuilder()
215                         .clearAll()
216                         .setLinkUpstreamBandwidthKbps(100000)
217                         .setLinkDownstreamBandwidthKbps(100000)
218                         .addTransport(2)
219                         .build(),
220                 true, "", "2");
221         assertParsedNetworkCapabilities(
222                 new NetworkCapabilitiesBuilder()
223                         .clearAll()
224                         .setLinkUpstreamBandwidthKbps(100000)
225                         .setLinkDownstreamBandwidthKbps(100000)
226                         .addTransport(3)
227                         .build(),
228                 true, "", "3");
229 
230         // "4" is TRANSPORT_VPN, which is unsupported. Should default back to TRANPORT_ETHERNET
231         assertParsedNetworkCapabilities(defaultEthernetCleared, true, "", "4");
232 
233         // "5" is TRANSPORT_WIFI_AWARE, which is currently supported due to no legacy TYPE_NONE
234         // conversion. When that becomes available, this test must be updated
235         assertParsedNetworkCapabilities(defaultEthernetCleared, true, "", "5");
236 
237         // "6" is TRANSPORT_LOWPAN, which is currently supported due to no legacy TYPE_NONE
238         // conversion. When that becomes available, this test must be updated
239         assertParsedNetworkCapabilities(defaultEthernetCleared, true, "", "6");
240 
241         // Adding an invalid override transport will leave the transport as TRANSPORT_ETHERNET
242         assertParsedNetworkCapabilities(defaultEthernetCleared,true, "", "100");
243         assertParsedNetworkCapabilities(defaultEthernetCleared, true, "", "abcdefg");
244 
245         // Ensure the adding of both capabilities and transports work
246         assertParsedNetworkCapabilities(
247                 new NetworkCapabilitiesBuilder()
248                         .clearAll()
249                         .setLinkUpstreamBandwidthKbps(100000)
250                         .setLinkDownstreamBandwidthKbps(100000)
251                         .addCapability(12)
252                         .addCapability(13)
253                         .addCapability(14)
254                         .addCapability(15)
255                         .addTransport(3)
256                         .build(),
257                 true, "12,13,14,15", "3");
258 
259         // Ensure order does not matter for capability list
260         assertParsedNetworkCapabilities(ethernetClearedWithCommonCaps, true, "13,12,15,14", "");
261     }
262 
assertParsedNetworkCapabilities(NetworkCapabilities expectedNetworkCapabilities, boolean clearCapabilties, String configCapabiltiies,String configTransports)263     private void assertParsedNetworkCapabilities(NetworkCapabilities expectedNetworkCapabilities,
264             boolean clearCapabilties, String configCapabiltiies,String configTransports) {
265         assertEquals(expectedNetworkCapabilities,
266                 EthernetTracker.createNetworkCapabilities(clearCapabilties, configCapabiltiies,
267                         configTransports));
268     }
269 
270     private static class NetworkCapabilitiesBuilder {
271         private final NetworkCapabilities nc = new NetworkCapabilities();
272 
clearAll()273         NetworkCapabilitiesBuilder clearAll(){
274             // This is THE ONLY one that doesn't return a reference to the object so I wrapped
275             // everything in a builder to keep things consistent and clean above. Fix if this
276             // ever changes
277             nc.clearAll();
278             return this;
279         }
280 
addCapability(int capability)281         NetworkCapabilitiesBuilder addCapability(int capability) {
282             nc.addCapability(capability);
283             return this;
284         }
285 
addTransport(int transport)286         NetworkCapabilitiesBuilder addTransport(int transport) {
287             nc.addTransportType(transport);
288             return this;
289         }
290 
setLinkUpstreamBandwidthKbps(int upKbps)291         NetworkCapabilitiesBuilder setLinkUpstreamBandwidthKbps(int upKbps) {
292             nc.setLinkUpstreamBandwidthKbps(upKbps);
293             return this;
294         }
295 
setLinkDownstreamBandwidthKbps(int downKbps)296         NetworkCapabilitiesBuilder setLinkDownstreamBandwidthKbps(int downKbps) {
297             nc.setLinkDownstreamBandwidthKbps(downKbps);
298             return this;
299         }
300 
build()301         NetworkCapabilities build() {
302             return new NetworkCapabilities(nc);
303         }
304     }
305 }
306