Home | History | Annotate | Download | only in net
      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