1 /* 2 * Copyright (C) 2011 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 libcore.java.net; 18 19 import junit.framework.TestCase; 20 21 import java.io.BufferedReader; 22 import java.io.InputStreamReader; 23 import java.lang.reflect.Field; 24 import java.net.Inet4Address; 25 import java.net.Inet6Address; 26 import java.net.InetAddress; 27 import java.net.InterfaceAddress; 28 import java.net.MulticastSocket; 29 import java.net.NetworkInterface; 30 import java.net.SocketException; 31 import java.util.Collections; 32 import java.util.Enumeration; 33 import java.util.HashSet; 34 import java.util.List; 35 import java.util.Set; 36 import java.util.regex.Pattern; 37 38 import static java.net.NetworkInterface.getNetworkInterfaces; 39 40 public class NetworkInterfaceTest extends TestCase { 41 // http://code.google.com/p/android/issues/detail?id=13784 42 private final static int ARPHRD_ETHER = 1; // from if_arp.h 43 public void testIPv6() throws Exception { 44 NetworkInterface lo = NetworkInterface.getByName("lo"); 45 Set<InetAddress> actual = new HashSet<InetAddress>(Collections.list(lo.getInetAddresses())); 46 47 Set<InetAddress> expected = new HashSet<InetAddress>(); 48 expected.add(Inet4Address.LOOPBACK); 49 expected.add(Inet6Address.getByAddress("localhost", new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, null)); 50 51 assertEquals(expected, actual); 52 } 53 54 /* 55 // http://code.google.com/p/android/issues/detail?id=34022 56 public void test_collectIpv6Addresses_3digitInterfaceIndex() throws Exception { 57 String lines[] = new String[] { 58 "fe800000000000000000000000000000 407 40 20 80 wlan0" }; 59 List<InetAddress> addresses = new ArrayList<InetAddress>(1); 60 List<InterfaceAddress> ifAddresses = new ArrayList<InterfaceAddress>(1); 61 62 NetworkInterface.collectIpv6Addresses("wlan0", 1, addresses, 63 ifAddresses, lines); 64 assertEquals(1, addresses.size()); 65 assertEquals(1, ifAddresses.size()); 66 // Make sure the prefix length (field #3) is parsed correctly 67 assertEquals(4*16 + 0, ifAddresses.get(0).getNetworkPrefixLength()); 68 } 69 70 public void test_collectIpv6Addresses_skipsUnmatchedLines() throws Exception { 71 String[] lines = new String[] { 72 "fe800000000000000000000000000000 40 40 20 80 wlan0", 73 "fe100000000000000000000000000000 41 40 20 80 wlan1", 74 "feb00000000000000000000000000000 42 40 20 80 wlan2" }; 75 List<InetAddress> addresses = new ArrayList<InetAddress>(1); 76 List<InterfaceAddress> ifAddresses = new ArrayList<InterfaceAddress>(1); 77 78 NetworkInterface.collectIpv6Addresses("wlan0", 1, addresses, 79 ifAddresses, lines); 80 assertEquals(1, addresses.size()); 81 assertEquals(1, ifAddresses.size()); 82 }*/ 83 84 public void testInterfaceProperties() throws Exception { 85 for (NetworkInterface nif : Collections.list(getNetworkInterfaces())) { 86 assertEquals(nif, NetworkInterface.getByName(nif.getName())); 87 // Skip interfaces that are inactive 88 if (nif.isUp() == false) { 89 continue; 90 } 91 // Ethernet 92 if (isEthernet(nif.getName())) { 93 assertEquals(6, nif.getHardwareAddress().length); 94 for (InterfaceAddress ia : nif.getInterfaceAddresses()) { 95 if (ia.getAddress() instanceof Inet4Address) { 96 assertNotNull(ia.getBroadcast()); 97 } 98 } 99 } 100 } 101 } 102 103 public void testLoopback() throws Exception { 104 NetworkInterface lo = NetworkInterface.getByName("lo"); 105 assertNull(lo.getHardwareAddress()); 106 for (InterfaceAddress ia : lo.getInterfaceAddresses()) { 107 assertNull(ia.getBroadcast()); 108 } 109 } 110 111 public void testDumpAll() throws Exception { 112 Set<String> allNames = new HashSet<String>(); 113 Set<Integer> allIndexes = new HashSet<Integer>(); 114 for (NetworkInterface nif : Collections.list(getNetworkInterfaces())) { 115 System.err.println(nif); 116 System.err.println(nif.getInterfaceAddresses()); 117 String flags = nif.isUp() ? "UP" : "DOWN"; 118 if (nif.isLoopback()) { 119 flags += " LOOPBACK"; 120 } 121 if (nif.isPointToPoint()) { 122 flags += " PTP"; 123 } 124 if (nif.isVirtual()) { 125 flags += " VIRTUAL"; 126 } 127 if (nif.supportsMulticast()) { 128 flags += " MULTICAST"; 129 } 130 flags += " MTU=" + nif.getMTU(); 131 byte[] mac = nif.getHardwareAddress(); 132 if (mac != null) { 133 flags += " HWADDR="; 134 for (int i = 0; i < mac.length; ++i) { 135 if (i > 0) { 136 flags += ":"; 137 } 138 flags += String.format("%02x", mac[i]); 139 } 140 } 141 System.err.println(flags); 142 System.err.println("-"); 143 144 assertFalse(allNames.contains(nif.getName())); 145 allNames.add(nif.getName()); 146 147 assertFalse(allIndexes.contains(nif.getIndex())); 148 allIndexes.add(nif.getIndex()); 149 } 150 } 151 152 // b/28903817 153 public void testInterfaceRemoval() throws Exception { 154 NetworkInterface lo = NetworkInterface.getByName("lo"); 155 156 // Simulate interface removal by changing it's name to unused value. 157 // This works only because getHardwareAddress (and others) is using name to fetch 158 // the NI data. If this changes, this test needs an update. 159 Field nameField = NetworkInterface.class.getDeclaredField("name"); 160 nameField.setAccessible(true); 161 nameField.set(lo, "noSuchInterface"); 162 163 try { 164 lo.getHardwareAddress(); 165 fail(); 166 } catch(SocketException expected) {} 167 168 try { 169 lo.getMTU(); 170 fail(); 171 } catch(SocketException expected) {} 172 173 try { 174 lo.isLoopback(); 175 fail(); 176 } catch(SocketException expected) {} 177 178 try { 179 lo.isUp(); 180 fail(); 181 } catch(SocketException expected) {} 182 183 try { 184 lo.isPointToPoint(); 185 fail(); 186 } catch(SocketException expected) {} 187 188 try { 189 lo.supportsMulticast(); 190 fail(); 191 } catch(SocketException expected) {} 192 } 193 194 // b/29243557 195 public void testGetNetworkInterfaces() throws Exception { 196 // Check that the interfaces we get from #getNetworkInterfaces agrees with IP-LINK(8). 197 198 // Parse output of ip link. 199 String[] cmd = { "ip", "link" }; 200 Process proc = Runtime.getRuntime().exec(cmd); 201 BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); 202 Set<String> expectedNiNames = new HashSet<>(); 203 for (String s; (s = stdInput.readLine()) != null; ) { 204 String[] split = s.split(": |@"); 205 try { 206 if (split.length > 2) { 207 expectedNiNames.add(split[1]); 208 } 209 } catch (NumberFormatException e) { 210 // Skip this line. 211 } 212 } 213 214 Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces(); 215 Set<String> actualNiNames = new HashSet<>(); 216 Collections.list(nifs).forEach(ni -> actualNiNames.add(ni.getName())); 217 218 assertEquals(expectedNiNames, actualNiNames); 219 } 220 221 // Calling getSubInterfaces on interfaces with no subinterface should not throw NPE. 222 // http://b/33844501 223 public void testGetSubInterfaces() throws Exception { 224 List<NetworkInterface> nifs = Collections.list(NetworkInterface.getNetworkInterfaces()); 225 226 for (NetworkInterface nif : nifs) { 227 nif.getSubInterfaces(); 228 } 229 } 230 231 // Is ifName a name of a Ethernet device? 232 private static Pattern ethernetNamePattern = Pattern.compile("^(eth|wlan)[0-9]+$"); 233 private static boolean isEthernet(String ifName) throws Exception { 234 return ethernetNamePattern.matcher(ifName).matches(); 235 } 236 237 public void testGetInterfaceAddressesDoesNotThrowNPE() throws Exception { 238 try (MulticastSocket mcastSock = new MulticastSocket()) { 239 mcastSock.getNetworkInterface().getInterfaceAddresses(); 240 } 241 } 242 } 243