1 /* 2 * Copyright (C) 2010 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 android.net; 18 19 import static android.net.RouteInfo.RTN_THROW; 20 import static android.net.RouteInfo.RTN_UNICAST; 21 import static android.net.RouteInfo.RTN_UNREACHABLE; 22 23 import static com.android.testutils.MiscAsserts.assertEqualBothWays; 24 import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay; 25 import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; 26 27 import static org.junit.Assert.assertEquals; 28 import static org.junit.Assert.assertFalse; 29 import static org.junit.Assert.assertNotEquals; 30 import static org.junit.Assert.assertNull; 31 import static org.junit.Assert.assertTrue; 32 import static org.junit.Assert.fail; 33 34 import androidx.test.filters.SmallTest; 35 import androidx.test.runner.AndroidJUnit4; 36 37 import com.android.testutils.ConnectivityModuleTest; 38 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.net.Inet4Address; 43 import java.net.Inet6Address; 44 import java.net.InetAddress; 45 46 @RunWith(AndroidJUnit4.class) 47 @SmallTest 48 @ConnectivityModuleTest 49 public class RouteInfoTest { 50 private static final int INVALID_ROUTE_TYPE = -1; 51 Address(String addr)52 private InetAddress Address(String addr) { 53 return InetAddresses.parseNumericAddress(addr); 54 } 55 Prefix(String prefix)56 private IpPrefix Prefix(String prefix) { 57 return new IpPrefix(prefix); 58 } 59 60 @Test testConstructor()61 public void testConstructor() { 62 RouteInfo r; 63 // Invalid input. 64 try { 65 r = new RouteInfo((IpPrefix) null, null, "rmnet0"); 66 fail("Expected RuntimeException: destination and gateway null"); 67 } catch (RuntimeException e) { } 68 69 try { 70 r = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "rmnet0", 71 INVALID_ROUTE_TYPE); 72 fail("Invalid route type should cause exception"); 73 } catch (IllegalArgumentException e) { } 74 75 try { 76 r = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("192.0.2.1"), "rmnet0", 77 RTN_UNREACHABLE); 78 fail("Address family mismatch should cause exception"); 79 } catch (IllegalArgumentException e) { } 80 81 try { 82 r = new RouteInfo(Prefix("0.0.0.0/0"), Address("2001:db8::1"), "rmnet0", 83 RTN_UNREACHABLE); 84 fail("Address family mismatch should cause exception"); 85 } catch (IllegalArgumentException e) { } 86 87 // Null destination is default route. 88 r = new RouteInfo((IpPrefix) null, Address("2001:db8::1"), null); 89 assertEquals(Prefix("::/0"), r.getDestination()); 90 assertEquals(Address("2001:db8::1"), r.getGateway()); 91 assertNull(r.getInterface()); 92 93 r = new RouteInfo((IpPrefix) null, Address("192.0.2.1"), "wlan0"); 94 assertEquals(Prefix("0.0.0.0/0"), r.getDestination()); 95 assertEquals(Address("192.0.2.1"), r.getGateway()); 96 assertEquals("wlan0", r.getInterface()); 97 98 // Null gateway sets gateway to unspecified address (why?). 99 r = new RouteInfo(Prefix("2001:db8:beef:cafe::/48"), null, "lo"); 100 assertEquals(Prefix("2001:db8:beef::/48"), r.getDestination()); 101 assertEquals(Address("::"), r.getGateway()); 102 assertEquals("lo", r.getInterface()); 103 104 r = new RouteInfo(Prefix("192.0.2.5/24"), null); 105 assertEquals(Prefix("192.0.2.0/24"), r.getDestination()); 106 assertEquals(Address("0.0.0.0"), r.getGateway()); 107 assertNull(r.getInterface()); 108 } 109 110 @Test testMatches()111 public void testMatches() { 112 class PatchedRouteInfo { 113 private final RouteInfo mRouteInfo; 114 115 public PatchedRouteInfo(IpPrefix destination, InetAddress gateway, String iface) { 116 mRouteInfo = new RouteInfo(destination, gateway, iface); 117 } 118 119 public boolean matches(InetAddress destination) { 120 return mRouteInfo.matches(destination); 121 } 122 } 123 124 PatchedRouteInfo r; 125 126 r = new PatchedRouteInfo(Prefix("2001:db8:f00::ace:d00d/127"), null, "rmnet0"); 127 assertTrue(r.matches(Address("2001:db8:f00::ace:d00c"))); 128 assertTrue(r.matches(Address("2001:db8:f00::ace:d00d"))); 129 assertFalse(r.matches(Address("2001:db8:f00::ace:d00e"))); 130 assertFalse(r.matches(Address("2001:db8:f00::bad:d00d"))); 131 assertFalse(r.matches(Address("2001:4868:4860::8888"))); 132 assertFalse(r.matches(Address("8.8.8.8"))); 133 134 r = new PatchedRouteInfo(Prefix("192.0.2.0/23"), null, "wlan0"); 135 assertTrue(r.matches(Address("192.0.2.43"))); 136 assertTrue(r.matches(Address("192.0.3.21"))); 137 assertFalse(r.matches(Address("192.0.0.21"))); 138 assertFalse(r.matches(Address("8.8.8.8"))); 139 140 PatchedRouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0"); 141 assertTrue(ipv6Default.matches(Address("2001:db8::f00"))); 142 assertFalse(ipv6Default.matches(Address("192.0.2.1"))); 143 144 PatchedRouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0"); 145 assertTrue(ipv4Default.matches(Address("255.255.255.255"))); 146 assertTrue(ipv4Default.matches(Address("192.0.2.1"))); 147 assertFalse(ipv4Default.matches(Address("2001:db8::f00"))); 148 } 149 150 @Test testEquals()151 public void testEquals() { 152 // IPv4 153 RouteInfo r1 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0"); 154 RouteInfo r2 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0"); 155 assertEqualBothWays(r1, r2); 156 157 RouteInfo r3 = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "wlan0"); 158 RouteInfo r4 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::2"), "wlan0"); 159 RouteInfo r5 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "rmnet0"); 160 assertNotEqualEitherWay(r1, r3); 161 assertNotEqualEitherWay(r1, r4); 162 assertNotEqualEitherWay(r1, r5); 163 164 // IPv6 165 r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0"); 166 r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0"); 167 assertEqualBothWays(r1, r2); 168 169 r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0"); 170 r4 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.2"), "wlan0"); 171 r5 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "rmnet0"); 172 assertNotEqualEitherWay(r1, r3); 173 assertNotEqualEitherWay(r1, r4); 174 assertNotEqualEitherWay(r1, r5); 175 176 // Interfaces (but not destinations or gateways) can be null. 177 r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null); 178 r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null); 179 r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0"); 180 assertEqualBothWays(r1, r2); 181 assertNotEqualEitherWay(r1, r3); 182 } 183 184 @Test testHostAndDefaultRoutes()185 public void testHostAndDefaultRoutes() { 186 RouteInfo r; 187 188 r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0"); 189 assertFalse(r.isHostRoute()); 190 assertTrue(r.isDefaultRoute()); 191 assertTrue(r.isIPv4Default()); 192 assertFalse(r.isIPv6Default()); 193 194 assertFalse(r.isIPv4UnreachableDefault()); 195 assertFalse(r.isIPv6UnreachableDefault()); 196 197 198 r = new RouteInfo(Prefix("::/0"), Address("::"), "wlan0"); 199 assertFalse(r.isHostRoute()); 200 assertTrue(r.isDefaultRoute()); 201 assertFalse(r.isIPv4Default()); 202 assertTrue(r.isIPv6Default()); 203 assertFalse(r.isIPv4UnreachableDefault()); 204 assertFalse(r.isIPv6UnreachableDefault()); 205 206 r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0"); 207 assertFalse(r.isHostRoute()); 208 assertFalse(r.isDefaultRoute()); 209 assertFalse(r.isIPv4Default()); 210 assertFalse(r.isIPv6Default()); 211 assertFalse(r.isIPv4UnreachableDefault()); 212 assertFalse(r.isIPv6UnreachableDefault()); 213 214 r = new RouteInfo(Prefix("2001:db8::/48"), null, "wlan0"); 215 assertFalse(r.isHostRoute()); 216 assertFalse(r.isDefaultRoute()); 217 assertFalse(r.isIPv4Default()); 218 assertFalse(r.isIPv6Default()); 219 220 assertFalse(r.isIPv4UnreachableDefault()); 221 assertFalse(r.isIPv6UnreachableDefault()); 222 223 r = new RouteInfo(Prefix("192.0.2.0/32"), Address("0.0.0.0"), "wlan0"); 224 assertTrue(r.isHostRoute()); 225 assertFalse(r.isDefaultRoute()); 226 assertFalse(r.isIPv4Default()); 227 assertFalse(r.isIPv6Default()); 228 229 assertFalse(r.isIPv4UnreachableDefault()); 230 assertFalse(r.isIPv6UnreachableDefault()); 231 232 r = new RouteInfo(Prefix("2001:db8::/128"), Address("::"), "wlan0"); 233 assertTrue(r.isHostRoute()); 234 assertFalse(r.isDefaultRoute()); 235 assertFalse(r.isIPv4Default()); 236 assertFalse(r.isIPv6Default()); 237 assertFalse(r.isIPv4UnreachableDefault()); 238 assertFalse(r.isIPv6UnreachableDefault()); 239 240 r = new RouteInfo(Prefix("192.0.2.0/32"), null, "wlan0"); 241 assertTrue(r.isHostRoute()); 242 assertFalse(r.isDefaultRoute()); 243 assertFalse(r.isIPv4Default()); 244 assertFalse(r.isIPv6Default()); 245 assertFalse(r.isIPv4UnreachableDefault()); 246 assertFalse(r.isIPv6UnreachableDefault()); 247 248 r = new RouteInfo(Prefix("2001:db8::/128"), null, "wlan0"); 249 assertTrue(r.isHostRoute()); 250 assertFalse(r.isDefaultRoute()); 251 assertFalse(r.isIPv4Default()); 252 assertFalse(r.isIPv6Default()); 253 assertFalse(r.isIPv4UnreachableDefault()); 254 assertFalse(r.isIPv6UnreachableDefault()); 255 256 r = new RouteInfo(Prefix("::/128"), Address("fe80::"), "wlan0"); 257 assertTrue(r.isHostRoute()); 258 assertFalse(r.isDefaultRoute()); 259 assertFalse(r.isIPv4Default()); 260 assertFalse(r.isIPv6Default()); 261 assertFalse(r.isIPv4UnreachableDefault()); 262 assertFalse(r.isIPv6UnreachableDefault()); 263 264 r = new RouteInfo(Prefix("0.0.0.0/32"), Address("192.0.2.1"), "wlan0"); 265 assertTrue(r.isHostRoute()); 266 assertFalse(r.isDefaultRoute()); 267 assertFalse(r.isIPv4Default()); 268 assertFalse(r.isIPv6Default()); 269 assertFalse(r.isIPv4UnreachableDefault()); 270 assertFalse(r.isIPv6UnreachableDefault()); 271 272 r = new RouteInfo(Prefix("0.0.0.0/32"), Address("192.0.2.1"), "wlan0"); 273 assertTrue(r.isHostRoute()); 274 assertFalse(r.isDefaultRoute()); 275 assertFalse(r.isIPv4Default()); 276 assertFalse(r.isIPv6Default()); 277 assertFalse(r.isIPv4UnreachableDefault()); 278 assertFalse(r.isIPv6UnreachableDefault()); 279 280 r = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE); 281 assertFalse(r.isHostRoute()); 282 assertFalse(r.isDefaultRoute()); 283 assertFalse(r.isIPv4Default()); 284 assertFalse(r.isIPv6Default()); 285 assertTrue(r.isIPv4UnreachableDefault()); 286 assertFalse(r.isIPv6UnreachableDefault()); 287 288 r = new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE); 289 assertFalse(r.isHostRoute()); 290 assertFalse(r.isDefaultRoute()); 291 assertFalse(r.isIPv4Default()); 292 assertFalse(r.isIPv6Default()); 293 assertFalse(r.isIPv4UnreachableDefault()); 294 assertTrue(r.isIPv6UnreachableDefault()); 295 } 296 297 @Test testRouteTypes()298 public void testRouteTypes() { 299 RouteInfo r = new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE); 300 assertEquals(RTN_UNREACHABLE, r.getType()); 301 r = new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNICAST); 302 assertEquals(RTN_UNICAST, r.getType()); 303 r = new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_THROW); 304 assertEquals(RTN_THROW, r.getType()); 305 } 306 307 @Test testTruncation()308 public void testTruncation() { 309 LinkAddress l; 310 RouteInfo r; 311 312 l = new LinkAddress("192.0.2.5/30"); 313 r = new RouteInfo(l, Address("192.0.2.1"), "wlan0"); 314 assertEquals("192.0.2.4", r.getDestination().getAddress().getHostAddress()); 315 316 l = new LinkAddress("2001:db8:1:f::5/63"); 317 r = new RouteInfo(l, Address("2001:db8:5::1"), "wlan0"); 318 assertEquals("2001:db8:1:e::", r.getDestination().getAddress().getHostAddress()); 319 } 320 321 // Make sure that creating routes to multicast addresses doesn't throw an exception. Even though 322 // there's nothing we can do with them, we don't want to crash if, e.g., someone calls 323 // requestRouteToHostAddress("230.0.0.0", MOBILE_HIPRI); 324 @Test testMulticastRoute()325 public void testMulticastRoute() { 326 RouteInfo r; 327 r = new RouteInfo(Prefix("230.0.0.0/32"), Address("192.0.2.1"), "wlan0"); 328 r = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::1"), "wlan0"); 329 // No exceptions? Good. 330 } 331 332 @Test testParceling()333 public void testParceling() { 334 RouteInfo r; 335 r = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), null); 336 assertParcelingIsLossless(r); 337 r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0"); 338 assertParcelingIsLossless(r); 339 r = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0", RTN_UNREACHABLE); 340 assertParcelingIsLossless(r); 341 } 342 343 @Test testMtuParceling()344 public void testMtuParceling() { 345 final RouteInfo r = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::"), "testiface", 346 RTN_UNREACHABLE, 1450 /* mtu */); 347 assertParcelingIsLossless(r); 348 } 349 350 @Test testMtu()351 public void testMtu() { 352 RouteInfo r; 353 r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0", 354 RouteInfo.RTN_UNICAST, 1500); 355 assertEquals(1500, r.getMtu()); 356 357 r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0"); 358 assertEquals(0, r.getMtu()); 359 } 360 361 @Test testRouteKey()362 public void testRouteKey() { 363 RouteInfo.RouteKey k1, k2; 364 // Only prefix, null gateway and null interface 365 k1 = new RouteInfo(Prefix("2001:db8::/128"), null).getRouteKey(); 366 k2 = new RouteInfo(Prefix("2001:db8::/128"), null).getRouteKey(); 367 assertEquals(k1, k2); 368 assertEquals(k1.hashCode(), k2.hashCode()); 369 370 // With prefix, gateway and interface. Type and MTU does not affect RouteKey equality 371 k1 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0", 372 RTN_UNREACHABLE, 1450).getRouteKey(); 373 k2 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0", 374 RouteInfo.RTN_UNICAST, 1400).getRouteKey(); 375 assertEquals(k1, k2); 376 assertEquals(k1.hashCode(), k2.hashCode()); 377 378 // Different scope IDs are ignored by the kernel, so we consider them equal here too. 379 k1 = new RouteInfo(Prefix("2001:db8::/64"), Address("fe80::1%1"), "wlan0").getRouteKey(); 380 k2 = new RouteInfo(Prefix("2001:db8::/64"), Address("fe80::1%2"), "wlan0").getRouteKey(); 381 assertEquals(k1, k2); 382 assertEquals(k1.hashCode(), k2.hashCode()); 383 384 // Different prefix 385 k1 = new RouteInfo(Prefix("192.0.2.0/24"), null).getRouteKey(); 386 k2 = new RouteInfo(Prefix("192.0.3.0/24"), null).getRouteKey(); 387 assertNotEquals(k1, k2); 388 389 // Different gateway 390 k1 = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::1"), null).getRouteKey(); 391 k2 = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::2"), null).getRouteKey(); 392 assertNotEquals(k1, k2); 393 394 // Different interface 395 k1 = new RouteInfo(Prefix("ff02::1/128"), null, "tun0").getRouteKey(); 396 k2 = new RouteInfo(Prefix("ff02::1/128"), null, "tun1").getRouteKey(); 397 assertNotEquals(k1, k2); 398 } 399 } 400