1 /* 2 * Copyright (C) 2015 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.system.OsConstants.AF_INET6; 20 import static android.system.OsConstants.IPPROTO_ICMPV6; 21 import static android.system.OsConstants.SOCK_DGRAM; 22 import static android.system.OsConstants.SOL_SOCKET; 23 import static android.system.OsConstants.SO_RCVTIMEO; 24 25 import static com.android.compatibility.common.util.PropertyUtil.getVsrApiLevel; 26 27 import static junit.framework.Assert.assertEquals; 28 29 import static org.junit.Assert.assertTrue; 30 import static org.junit.Assume.assumeTrue; 31 32 import android.os.Build; 33 import android.system.ErrnoException; 34 import android.system.Os; 35 import android.system.StructTimeval; 36 37 import androidx.test.filters.SmallTest; 38 39 import com.android.net.module.util.SocketUtils; 40 import com.android.testutils.DevSdkIgnoreRule; 41 import com.android.testutils.DevSdkIgnoreRunner; 42 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 46 import java.io.FileDescriptor; 47 import java.math.BigInteger; 48 import java.nio.ByteBuffer; 49 import java.nio.ByteOrder; 50 import java.util.TreeSet; 51 52 @RunWith(DevSdkIgnoreRunner.class) 53 @SmallTest 54 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 55 public class NetworkUtilsTest { 56 @Test testRoutedIPv4AddressCount()57 public void testRoutedIPv4AddressCount() { 58 final TreeSet<IpPrefix> set = new TreeSet<>(IpPrefix.lengthComparator()); 59 // No routes routes to no addresses. 60 assertEquals(0, NetworkUtils.routedIPv4AddressCount(set)); 61 62 set.add(new IpPrefix("0.0.0.0/0")); 63 assertEquals(1l << 32, NetworkUtils.routedIPv4AddressCount(set)); 64 65 set.add(new IpPrefix("20.18.0.0/16")); 66 set.add(new IpPrefix("20.18.0.0/24")); 67 set.add(new IpPrefix("20.18.0.0/8")); 68 // There is a default route, still covers everything 69 assertEquals(1l << 32, NetworkUtils.routedIPv4AddressCount(set)); 70 71 set.clear(); 72 set.add(new IpPrefix("20.18.0.0/24")); 73 set.add(new IpPrefix("20.18.0.0/8")); 74 // The 8-length includes the 24-length prefix 75 assertEquals(1l << 24, NetworkUtils.routedIPv4AddressCount(set)); 76 77 set.add(new IpPrefix("10.10.10.126/25")); 78 // The 8-length does not include this 25-length prefix 79 assertEquals((1l << 24) + (1 << 7), NetworkUtils.routedIPv4AddressCount(set)); 80 81 set.clear(); 82 set.add(new IpPrefix("1.2.3.4/32")); 83 set.add(new IpPrefix("1.2.3.4/32")); 84 set.add(new IpPrefix("1.2.3.4/32")); 85 set.add(new IpPrefix("1.2.3.4/32")); 86 assertEquals(1l, NetworkUtils.routedIPv4AddressCount(set)); 87 88 set.add(new IpPrefix("1.2.3.5/32")); 89 set.add(new IpPrefix("1.2.3.6/32")); 90 91 set.add(new IpPrefix("1.2.3.7/32")); 92 set.add(new IpPrefix("1.2.3.8/32")); 93 set.add(new IpPrefix("1.2.3.9/32")); 94 set.add(new IpPrefix("1.2.3.0/32")); 95 assertEquals(7l, NetworkUtils.routedIPv4AddressCount(set)); 96 97 // 1.2.3.4/30 eats 1.2.3.{4-7}/32 98 set.add(new IpPrefix("1.2.3.4/30")); 99 set.add(new IpPrefix("6.2.3.4/28")); 100 set.add(new IpPrefix("120.2.3.4/16")); 101 assertEquals(7l - 4 + 4 + 16 + 65536, NetworkUtils.routedIPv4AddressCount(set)); 102 } 103 104 @Test testRoutedIPv6AddressCount()105 public void testRoutedIPv6AddressCount() { 106 final TreeSet<IpPrefix> set = new TreeSet<>(IpPrefix.lengthComparator()); 107 // No routes routes to no addresses. 108 assertEquals(BigInteger.ZERO, NetworkUtils.routedIPv6AddressCount(set)); 109 110 set.add(new IpPrefix("::/0")); 111 assertEquals(BigInteger.ONE.shiftLeft(128), NetworkUtils.routedIPv6AddressCount(set)); 112 113 set.add(new IpPrefix("1234:622a::18/64")); 114 set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/96")); 115 set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/8")); 116 // There is a default route, still covers everything 117 assertEquals(BigInteger.ONE.shiftLeft(128), NetworkUtils.routedIPv6AddressCount(set)); 118 119 set.clear(); 120 set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/96")); 121 set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/8")); 122 // The 8-length includes the 96-length prefix 123 assertEquals(BigInteger.ONE.shiftLeft(120), NetworkUtils.routedIPv6AddressCount(set)); 124 125 set.add(new IpPrefix("10::26/64")); 126 // The 8-length does not include this 64-length prefix 127 assertEquals(BigInteger.ONE.shiftLeft(120).add(BigInteger.ONE.shiftLeft(64)), 128 NetworkUtils.routedIPv6AddressCount(set)); 129 130 set.clear(); 131 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); 132 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); 133 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); 134 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); 135 assertEquals(BigInteger.ONE, NetworkUtils.routedIPv6AddressCount(set)); 136 137 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad5/128")); 138 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad6/128")); 139 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad7/128")); 140 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad8/128")); 141 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad9/128")); 142 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad0/128")); 143 assertEquals(BigInteger.valueOf(7), NetworkUtils.routedIPv6AddressCount(set)); 144 145 // add4:f00:80:f7:1111::6ad4/126 eats add4:f00:8[:f7:1111::6ad{4-7}/128 146 set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/126")); 147 set.add(new IpPrefix("d00d:f00:80:f7:1111::6ade/124")); 148 set.add(new IpPrefix("f00b:a33::/112")); 149 assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536), 150 NetworkUtils.routedIPv6AddressCount(set)); 151 } 152 getTimevalBytes(StructTimeval tv)153 private byte[] getTimevalBytes(StructTimeval tv) { 154 byte[] timeval = new byte[16]; 155 ByteBuffer buf = ByteBuffer.wrap(timeval); 156 buf.order(ByteOrder.nativeOrder()); 157 buf.putLong(tv.tv_sec); 158 buf.putLong(tv.tv_usec); 159 return timeval; 160 } 161 testSetSockOptBytes(FileDescriptor sock, long timeValMillis)162 private void testSetSockOptBytes(FileDescriptor sock, long timeValMillis) 163 throws ErrnoException { 164 final StructTimeval writeTimeval = StructTimeval.fromMillis(timeValMillis); 165 byte[] timeval = getTimevalBytes(writeTimeval); 166 final StructTimeval readTimeval; 167 168 NetworkUtils.setsockoptBytes(sock, SOL_SOCKET, SO_RCVTIMEO, timeval); 169 readTimeval = Os.getsockoptTimeval(sock, SOL_SOCKET, SO_RCVTIMEO); 170 171 assertEquals(writeTimeval, readTimeval); 172 } 173 174 @Test testSetSockOptBytes()175 public void testSetSockOptBytes() throws ErrnoException { 176 final FileDescriptor sock = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6); 177 178 testSetSockOptBytes(sock, 3000); 179 180 testSetSockOptBytes(sock, 5000); 181 182 SocketUtils.closeSocketQuietly(sock); 183 } 184 185 @Test testIsKernel64Bit()186 public void testIsKernel64Bit() { 187 assumeTrue(getVsrApiLevel() > Build.VERSION_CODES.TIRAMISU); 188 assertTrue(NetworkUtils.isKernel64Bit()); 189 } 190 } 191