1 /* 2 * Copyright (C) 2014 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.cts; 18 19 import android.system.ErrnoException; 20 import android.system.Os; 21 import android.system.OsConstants; 22 import android.system.StructStat; 23 import android.test.AndroidTestCase; 24 25 import java.io.File; 26 import java.io.FileDescriptor; 27 import java.io.IOException; 28 29 /** 30 * Tests for multinetwork functionality. 31 */ 32 public class MultinetworkTest extends AndroidTestCase { 33 34 // Global sysctls. Must be present and set to 1. 35 private static final String[] GLOBAL_SYSCTLS = { 36 "/proc/sys/net/ipv4/fwmark_reflect", 37 "/proc/sys/net/ipv6/fwmark_reflect", 38 "/proc/sys/net/ipv4/tcp_fwmark_accept", 39 }; 40 41 // Per-interface IPv6 autoconf sysctls. 42 private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf"; 43 private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table"; 44 45 // Expected mode, UID, and GID of sysctl files. 46 private static final int SYSCTL_MODE = 0100644; 47 private static final int SYSCTL_UID = 0; 48 private static final int SYSCTL_GID = 0; 49 checkSysctlPermissions(String fileName)50 private void checkSysctlPermissions(String fileName) throws ErrnoException { 51 StructStat stat = Os.stat(fileName); 52 assertEquals("mode of " + fileName + ":", SYSCTL_MODE, stat.st_mode); 53 assertEquals("UID of " + fileName + ":", SYSCTL_UID, stat.st_uid); 54 assertEquals("GID of " + fileName + ":", SYSCTL_GID, stat.st_gid); 55 } 56 assertLess(String what, int a, int b)57 private void assertLess(String what, int a, int b) { 58 assertTrue(what + " expected < " + b + " but was: " + a, a < b); 59 } 60 readFile(String fileName)61 private String readFile(String fileName) throws ErrnoException, IOException { 62 byte[] buf = new byte[1024]; 63 FileDescriptor fd = Os.open(fileName, 0, OsConstants.O_RDONLY); 64 int bytesRead = Os.read(fd, buf, 0, buf.length); 65 assertLess("length of " + fileName + ":", bytesRead, buf.length); 66 return new String(buf); 67 } 68 69 /** 70 * Checks that the sysctls for multinetwork kernel features are present and 71 * enabled. The necessary kernel commits are: 72 * 73 * Mainline Linux: 74 * e110861 net: add a sysctl to reflect the fwmark on replies 75 * 1b3c61d net: Use fwmark reflection in PMTU discovery. 76 * 84f39b0 net: support marking accepting TCP sockets 77 * 78 * Common Android tree (e.g., 3.10): 79 * a03f539 net: ipv6: autoconf routes into per-device tables 80 */ testProcFiles()81 public void testProcFiles() throws ErrnoException, IOException, NumberFormatException { 82 for (String sysctl : GLOBAL_SYSCTLS) { 83 checkSysctlPermissions(sysctl); 84 int value = Integer.parseInt(readFile(sysctl).trim()); 85 assertEquals("value of " + sysctl + ":", 1, value); 86 } 87 88 File[] interfaceDirs = new File(IPV6_SYSCTL_DIR).listFiles(); 89 for (File interfaceDir : interfaceDirs) { 90 if (interfaceDir.getName().equals("all") || interfaceDir.getName().equals("lo")) { 91 continue; 92 } 93 String sysctl = new File(interfaceDir, AUTOCONF_SYSCTL).getAbsolutePath(); 94 checkSysctlPermissions(sysctl); 95 int value = Integer.parseInt(readFile(sysctl).trim()); 96 assertLess("value of " + sysctl + ":", value, 0); 97 } 98 } 99 } 100