1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 205d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport android.system.ErrnoException; 21a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughesimport java.io.File; 22a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughesimport java.io.FileDescriptor; 23a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughesimport java.io.IOException; 24d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.ArrayList; 25a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughesimport java.util.Arrays; 26d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.Collections; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration; 28d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughesimport java.util.LinkedList; 29b5fc5ecd3fe5315fc2756c0c25adc458cc8c8d91Elliott Hughesimport java.util.List; 30a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughesimport libcore.io.IoUtils; 31a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughesimport libcore.io.Libcore; 325d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport static android.system.OsConstants.*; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is used to represent a network interface of the local device. An 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interface is defined by its address and a platform dependent name. The class 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provides methods to get all information about the available interfaces of the 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * system or to identify the local interface of a joined multicast group. 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class NetworkInterface extends Object { 41ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath private static final File SYS_CLASS_NET = new File("/sys/class/net"); 42ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath 43d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes private final String name; 44a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes private final int interfaceIndex; 45a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private final List<InterfaceAddress> interfaceAddresses; 46a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private final List<InetAddress> addresses; 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 48a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes private final List<NetworkInterface> children = new LinkedList<NetworkInterface>(); 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 50d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes private NetworkInterface parent = null; 51d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 52a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private NetworkInterface(String name, int interfaceIndex, 53a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes List<InetAddress> addresses, List<InterfaceAddress> interfaceAddresses) { 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.interfaceIndex = interfaceIndex; 56a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes this.addresses = addresses; 57a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes this.interfaceAddresses = interfaceAddresses; 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 60a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes static NetworkInterface forUnboundMulticastSocket() { 61a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // This is what the RI returns for a MulticastSocket that hasn't been constrained 62a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // to a specific interface. 63a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return new NetworkInterface(null, -1, 64a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes Arrays.asList(Inet6Address.ANY), Collections.<InterfaceAddress>emptyList()); 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 68a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns the index for the network interface, or -1 if unknown. 698ffa0b68c9fd3f722bee2bcd94b1d38151a0791dElliott Hughes * @since 1.7 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 71a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes public int getIndex() { 72a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return interfaceIndex; 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 76a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns the name of this network interface (such as "eth0" or "lo"). 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getName() { 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return name; 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 83a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns an enumeration of the addresses bound to this network interface. 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Enumeration<InetAddress> getInetAddresses() { 86ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes return Collections.enumeration(addresses); 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 90a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns a human-readable name for this network interface. On Android, this is the same 91a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * string as returned by {@link #getName}. 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getDisplayName() { 94a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return name; 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 98a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns the {@code NetworkInterface} corresponding to the named network interface, or null 99a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * if no interface has this name. 100f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 101a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * @throws SocketException if an error occurs. 102a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * @throws NullPointerException if {@code interfaceName == null}. 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 104d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public static NetworkInterface getByName(String interfaceName) throws SocketException { 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (interfaceName == null) { 106a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes throw new NullPointerException("interfaceName == null"); 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 108a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (!isValidInterfaceName(interfaceName)) { 109a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return null; 110a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 111a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 112ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath return getByNameInternal(interfaceName, readIfInet6Lines()); 113ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath } 114ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath 115ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath /** 116ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath * Similar to {@link #getByName(String)} except that {@code interfaceName} 117ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath * is assumed to be valid. 118ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath */ 119ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath private static NetworkInterface getByNameInternal(String interfaceName, 120ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath String[] ifInet6Lines) throws SocketException { 121a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes int interfaceIndex = readIntFile("/sys/class/net/" + interfaceName + "/ifindex"); 122a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes List<InetAddress> addresses = new ArrayList<InetAddress>(); 123a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes List<InterfaceAddress> interfaceAddresses = new ArrayList<InterfaceAddress>(); 124ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath 125ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath collectIpv6Addresses(interfaceName, interfaceIndex, addresses, interfaceAddresses, 126ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath ifInet6Lines); 127a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes collectIpv4Address(interfaceName, addresses, interfaceAddresses); 128a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 129a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return new NetworkInterface(interfaceName, interfaceIndex, addresses, interfaceAddresses); 130a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 131a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 132ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath private static String[] readIfInet6Lines() throws SocketException { 133ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath try { 134ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath return IoUtils.readFileAsString("/proc/net/if_inet6").split("\n"); 135ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath } catch (IOException ioe) { 136ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath throw rethrowAsSocketException(ioe); 137ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath } 138ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath } 139ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath 140ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath /** 141ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath * Visible for testing only. 142ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath * 143ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath * @hide 144ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath */ 145ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath public static void collectIpv6Addresses(String interfaceName, int interfaceIndex, 146ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath List<InetAddress> addresses, List<InterfaceAddress> interfaceAddresses, 147ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath String[] ifInet6Lines) throws SocketException { 148b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // Format of /proc/net/if_inet6. 149b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // All numeric fields are implicit hex, 150b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // but not necessarily two-digit (http://code.google.com/p/android/issues/detail?id=34022). 151a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // 1. IPv6 address 152a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // 2. interface index 153a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // 3. prefix length 154a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // 4. scope 155a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // 5. flags 156a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // 6. interface name 157a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // "00000000000000000000000000000001 01 80 10 80 lo" 158b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // "fe800000000000000000000000000000 407 40 20 80 wlan0" 159ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath final String suffix = " " + interfaceName; 160a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes try { 161ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath for (String line : ifInet6Lines) { 162a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (!line.endsWith(suffix)) { 163a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes continue; 164a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 165b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes 166b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // Extract the IPv6 address. 167a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes byte[] addressBytes = new byte[16]; 168a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes for (int i = 0; i < addressBytes.length; ++i) { 169a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes addressBytes[i] = (byte) Integer.parseInt(line.substring(2*i, 2*i + 2), 16); 170a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 171a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 172b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // Extract the prefix length. 173b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // Skip the IPv6 address and its trailing space. 174b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes int prefixLengthStart = 32 + 1; 175b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes // Skip the interface index and its trailing space. 176b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes prefixLengthStart = line.indexOf(' ', prefixLengthStart) + 1; 177b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes int prefixLengthEnd = line.indexOf(' ', prefixLengthStart); 178b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes short prefixLength = Short.parseShort(line.substring(prefixLengthStart, prefixLengthEnd), 16); 179b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes 180b0e6dc5464f959b3d42f37b32f4b01767f6fe506Elliott Hughes Inet6Address inet6Address = new Inet6Address(addressBytes, null, interfaceIndex); 181a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes addresses.add(inet6Address); 182a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes interfaceAddresses.add(new InterfaceAddress(inet6Address, prefixLength)); 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 184ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath } catch (NumberFormatException ex) { 185a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes throw rethrowAsSocketException(ex); 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 187a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 188a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 189a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private static void collectIpv4Address(String interfaceName, List<InetAddress> addresses, 190a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes List<InterfaceAddress> interfaceAddresses) throws SocketException { 191a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes FileDescriptor fd = null; 192a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes try { 193a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes fd = Libcore.os.socket(AF_INET, SOCK_DGRAM, 0); 194a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes InetAddress address = Libcore.os.ioctlInetAddress(fd, SIOCGIFADDR, interfaceName); 195a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes InetAddress broadcast = Libcore.os.ioctlInetAddress(fd, SIOCGIFBRDADDR, interfaceName); 196a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes InetAddress netmask = Libcore.os.ioctlInetAddress(fd, SIOCGIFNETMASK, interfaceName); 197a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (broadcast.equals(Inet4Address.ANY)) { 198a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes broadcast = null; 199a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 200a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 201a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes addresses.add(address); 202a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes interfaceAddresses.add(new InterfaceAddress((Inet4Address) address, 203a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes (Inet4Address) broadcast, (Inet4Address) netmask)); 204a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } catch (ErrnoException errnoException) { 205a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (errnoException.errno != EADDRNOTAVAIL) { 206a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // EADDRNOTAVAIL just means no IPv4 address for this interface. 207a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // Anything else is a real error. 208a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes throw rethrowAsSocketException(errnoException); 209a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 210a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } catch (Exception ex) { 211a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes throw rethrowAsSocketException(ex); 212a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } finally { 213a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes IoUtils.closeQuietly(fd); 214a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 215a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 216a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 2170d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes @FindBugsSuppressWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME") 218a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private static boolean isValidInterfaceName(String interfaceName) { 219ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath final String[] interfaceList = SYS_CLASS_NET.list(); 220ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath // We have no interfaces listed under /sys/class/net 221ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath if (interfaceList == null) { 222ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath return false; 223ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath } 224ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath 225a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // Don't just stat because a crafty user might have / or .. in the supposed interface name. 226ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath for (String validName : interfaceList) { 227a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (interfaceName.equals(validName)) { 228a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return true; 229a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 230a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 231a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return false; 232a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 233a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 234a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private static int readIntFile(String path) throws SocketException { 235a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes try { 236a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes String s = IoUtils.readFileAsString(path).trim(); 237a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (s.startsWith("0x")) { 238a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return Integer.parseInt(s.substring(2), 16); 239a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } else { 240a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return Integer.parseInt(s); 241a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 242a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } catch (Exception ex) { 243a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes throw rethrowAsSocketException(ex); 244a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 245a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 246a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 247a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private static SocketException rethrowAsSocketException(Exception ex) throws SocketException { 248a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes SocketException result = new SocketException(); 249a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes result.initCause(ex); 250a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes throw result; 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 254c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * Returns the {@code NetworkInterface} corresponding to the given address, or null if no 255c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * interface has this address. 256f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 257c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * @throws SocketException if an error occurs. 258c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * @throws NullPointerException if {@code address == null}. 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 260d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public static NetworkInterface getByInetAddress(InetAddress address) throws SocketException { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (address == null) { 262b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new NullPointerException("address == null"); 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 264d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes for (NetworkInterface networkInterface : getNetworkInterfacesList()) { 265d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes if (networkInterface.addresses.contains(address)) { 266d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return networkInterface; 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 273c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * Returns the NetworkInterface corresponding to the given interface index, or null if no 274c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * interface has this index. 275c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * 276c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes * @throws SocketException if an error occurs. 2778ffa0b68c9fd3f722bee2bcd94b1d38151a0791dElliott Hughes * @since 1.7 278c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes */ 279c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes public static NetworkInterface getByIndex(int index) throws SocketException { 280a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes String name = Libcore.os.if_indextoname(index); 281a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (name == null) { 282a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return null; 283c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes } 284a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return NetworkInterface.getByName(name); 285c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes } 286c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes 287c3d19477189eafcdfec5735f9e5e13ffdeaf963dElliott Hughes /** 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a list of all network interfaces available on the local system or 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} if no interface is available. 290f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the list of {@code NetworkInterface} instances representing the 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available interfaces. 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while getting the network interface 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * information. 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 297d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public static Enumeration<NetworkInterface> getNetworkInterfaces() throws SocketException { 298d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return Collections.enumeration(getNetworkInterfacesList()); 299d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 300d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 3010d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes @FindBugsSuppressWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME") 302d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes private static List<NetworkInterface> getNetworkInterfacesList() throws SocketException { 303ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath String[] interfaceNames = SYS_CLASS_NET.list(); 304a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes NetworkInterface[] interfaces = new NetworkInterface[interfaceNames.length]; 3054bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes boolean[] done = new boolean[interfaces.length]; 306ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath 307ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath String[] ifInet6Lines = readIfInet6Lines(); 308a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes for (int i = 0; i < interfaceNames.length; ++i) { 309ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath interfaces[i] = NetworkInterface.getByNameInternal(interfaceNames[i], ifInet6Lines); 3104bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes // http://b/5833739: getByName can return null if the interface went away between our 3114bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes // readdir(2) and our stat(2), so mark interfaces that disappeared as 'done'. 3124bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes if (interfaces[i] == null) { 3134bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes done[i] = true; 3144bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes } 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 317d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes List<NetworkInterface> result = new ArrayList<NetworkInterface>(); 318d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes for (int counter = 0; counter < interfaces.length; counter++) { 3194bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes // If this interface has been dealt with already, continue. 3204bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes if (done[counter]) { 321d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes continue; 322d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 323ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath 324d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes // Checks whether the following interfaces are children. 325ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath for (int counter2 = counter; counter2 < interfaces.length; counter2++) { 3264bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes if (done[counter2]) { 327d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes continue; 328d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 329d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes if (interfaces[counter2].name.startsWith(interfaces[counter].name + ":")) { 330d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes interfaces[counter].children.add(interfaces[counter2]); 331d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes interfaces[counter2].parent = interfaces[counter]; 332d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes interfaces[counter].addresses.addAll(interfaces[counter2].addresses); 3334bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes done[counter2] = true; 334ab6d858336e6db8b5117b78837fee2a9f35fdf2cNarayan Kamath } 335d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 336d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes result.add(interfaces[counter]); 3374bbc5de89764a9bcdb62c65be31e0f110578d427Elliott Hughes done[counter] = true; 338d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 339d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return result; 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares the specified object to this {@code NetworkInterface} and 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returns whether they are equal or not. The object must be an instance of 345a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * {@code NetworkInterface} with the same name, display name, and list 346a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * of interface addresses. 347f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object to compare with this instance. 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the specified object is equal to this {@code 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * NetworkInterface}, {@code false} otherwise. 3525839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson * @see #hashCode() 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object obj) { 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (obj == this) { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3595839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson if (!(obj instanceof NetworkInterface)) { 3605839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson return false; 3615839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson } 362d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes NetworkInterface rhs = (NetworkInterface) obj; 363d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes // TODO: should the order of the addresses matter (we use List.equals)? 364d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return interfaceIndex == rhs.interfaceIndex && 365a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes name.equals(rhs.name) && 366d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes addresses.equals(rhs.addresses); 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 370d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns the hash code for this {@code NetworkInterface}. Since the 371d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * name should be unique for each network interface the hash code is 372a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * generated using the name. 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 374a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes @Override public int hashCode() { 375d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return name.hashCode(); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 37810914811ea02b4acc7ab1dc5a0ada1b54cdf2203Elliott Hughes /** 37910914811ea02b4acc7ab1dc5a0ada1b54cdf2203Elliott Hughes * Returns a string containing details of this network interface. 38010914811ea02b4acc7ab1dc5a0ada1b54cdf2203Elliott Hughes * The exact format is deliberately unspecified. Callers that require a specific 38110914811ea02b4acc7ab1dc5a0ada1b54cdf2203Elliott Hughes * format should build a string themselves, using this class' accessor methods. 38210914811ea02b4acc7ab1dc5a0ada1b54cdf2203Elliott Hughes */ 383a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes @Override public String toString() { 384a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes StringBuilder sb = new StringBuilder(25); 385a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append("["); 386a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append(name); 387a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append("]["); 388a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append(interfaceIndex); 389a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append("]"); 390a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes for (InetAddress address : addresses) { 391a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append("["); 392a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append(address.toString()); 393a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes sb.append("]"); 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 395a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return sb.toString(); 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 397d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 398d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 399ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes * Returns a List of the InterfaceAddresses for this network interface. 400d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 401d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 402d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public List<InterfaceAddress> getInterfaceAddresses() { 403ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes return Collections.unmodifiableList(interfaceAddresses); 404d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 405d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 406d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 407a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns an enumeration of all the sub-interfaces of this network interface. 408d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Sub-interfaces are also known as virtual interfaces. 409a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * 410a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * <p>For example, {@code eth0:1} would be a sub-interface of {@code eth0}. 411f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 412d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @return an Enumeration of all the sub-interfaces of this network interface 413d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 414d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 415d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public Enumeration<NetworkInterface> getSubInterfaces() { 416d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return Collections.enumeration(children); 417d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 418d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 419d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 420d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns the parent NetworkInterface of this interface if this is a 421d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * sub-interface, or null if it's a physical (non virtual) interface. 422f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 423d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @return the NetworkInterface this interface is attached to. 424d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 425d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 426d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public NetworkInterface getParent() { 427d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return parent; 428d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 429d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 430d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 431d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns true if this network interface is up. 432f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 433d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @return true if the interface is up. 434d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @throws SocketException if an I/O error occurs. 435d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 436d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 437d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public boolean isUp() throws SocketException { 438a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return hasFlag(IFF_UP); 439d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 440d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 441d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 442d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns true if this network interface is a loopback interface. 443f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 444d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @return true if the interface is a loopback interface. 445d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @throws SocketException if an I/O error occurs. 446d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 447d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 448d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public boolean isLoopback() throws SocketException { 449a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return hasFlag(IFF_LOOPBACK); 450d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 451d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 452d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 453d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns true if this network interface is a point-to-point interface. 454d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * (For example, a PPP connection using a modem.) 455f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 456d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @return true if the interface is point-to-point. 457d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @throws SocketException if an I/O error occurs. 458d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 459d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 460d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public boolean isPointToPoint() throws SocketException { 461a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return hasFlag(IFF_POINTOPOINT); 462d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 463d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 464d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 465d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns true if this network interface supports multicast. 466f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 467d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @throws SocketException if an I/O error occurs. 468d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 469d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 470d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public boolean supportsMulticast() throws SocketException { 471a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return hasFlag(IFF_MULTICAST); 472a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 473a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 474a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes private boolean hasFlag(int mask) throws SocketException { 475a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes int flags = readIntFile("/sys/class/net/" + name + "/flags"); 476a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return (flags & mask) != 0; 477d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 478d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 479d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 480a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns the hardware address of the interface, if it has one, or null otherwise. 481f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 482d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @throws SocketException if an I/O error occurs. 483d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 484d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 485d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public byte[] getHardwareAddress() throws SocketException { 486a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes try { 487a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // Parse colon-separated bytes with a trailing newline: "aa:bb:cc:dd:ee:ff\n". 488a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes String s = IoUtils.readFileAsString("/sys/class/net/" + name + "/address"); 489a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes byte[] result = new byte[s.length()/3]; 490a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes for (int i = 0; i < result.length; ++i) { 491a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes result[i] = (byte) Integer.parseInt(s.substring(3*i, 3*i + 2), 16); 492a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 493a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes // We only want to return non-zero hardware addresses. 494a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes for (int i = 0; i < result.length; ++i) { 495a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes if (result[i] != 0) { 496a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return result; 497a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 498a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 499a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return null; 500a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } catch (Exception ex) { 501a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes throw rethrowAsSocketException(ex); 502d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 503d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 504d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 505d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 506d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns the Maximum Transmission Unit (MTU) of this interface. 507f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 508d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @return the value of the MTU for the interface. 509d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @throws SocketException if an I/O error occurs. 510d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 511d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 512d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public int getMTU() throws SocketException { 513a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes return readIntFile("/sys/class/net/" + name + "/mtu"); 514d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 515d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes 516d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes /** 517d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * Returns true if this interface is a virtual interface (also called 518d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * a sub-interface). Virtual interfaces are, on some systems, interfaces 519d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * created as a child of a physical interface and given different settings 520d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * (like address or MTU). Usually the name of the interface will the name of 521d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * the parent followed by a colon (:) and a number identifying the child, 522d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * since there can be several virtual interfaces attached to a single 523d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * physical interface. 524f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 525d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @return true if this interface is a virtual interface. 526d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes * @since 1.6 527d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes */ 528d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes public boolean isVirtual() { 529d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes return parent != null; 530d2af45a6fd008ceb958ac74e5a50e582b8419e9cElliott Hughes } 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 532