001/* NetworkInterface.java -- 002 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package java.net; 040 041import gnu.classpath.SystemProperties; 042 043import gnu.java.lang.CPStringBuilder; 044 045import java.util.Enumeration; 046import java.util.Iterator; 047import java.util.Vector; 048 049/** 050 * This class models a network interface on the host computer. A network 051 * interface contains a name (typically associated with a specific 052 * hardware adapter) and a list of addresses that are bound to it. 053 * For example, an ethernet interface may be named "eth0" and have the 054 * address 192.168.1.101 assigned to it. 055 * 056 * @author Michael Koch (konqueror@gmx.de) 057 * @since 1.4 058 */ 059public final class NetworkInterface 060{ 061 private final VMNetworkInterface netif; 062 063 private NetworkInterface(VMNetworkInterface netif) 064 { 065 this.netif = netif; 066 } 067 068 /** Creates an NetworkInterface instance which 069 * represents any interface in the system. Its only 070 * address is <code>0.0.0.0/0.0.0.0</code>. This 071 * method is needed by {@link MulticastSocket#getNetworkInterface} 072 */ 073 static NetworkInterface createAnyInterface() 074 { 075 return new NetworkInterface(new VMNetworkInterface()); 076 } 077 078 /** 079 * Returns the name of the network interface 080 * 081 * @return The name of the interface. 082 */ 083 public String getName() 084 { 085 return netif.name; 086 } 087 088 /** 089 * Returns all available addresses of the network interface 090 * 091 * If a @see SecurityManager is available all addresses are checked 092 * with @see SecurityManager::checkConnect() if they are available. 093 * Only <code>InetAddresses</code> are returned where the security manager 094 * doesn't throw an exception. 095 * 096 * @return An enumeration of all addresses. 097 */ 098 public Enumeration<InetAddress> getInetAddresses() 099 { 100 SecurityManager s = System.getSecurityManager(); 101 Vector<InetAddress> inetAddresses 102 = new Vector<InetAddress>(netif.addresses); 103 104 if (s == null) 105 return inetAddresses.elements(); 106 107 Vector<InetAddress> tmpInetAddresses = new Vector<InetAddress>(1, 1); 108 109 for (Enumeration<InetAddress> addresses = inetAddresses.elements(); 110 addresses.hasMoreElements();) 111 { 112 InetAddress addr = addresses.nextElement(); 113 try 114 { 115 s.checkConnect(addr.getHostAddress(), -1); 116 tmpInetAddresses.add(addr); 117 } 118 catch (SecurityException e) 119 { 120 // Ignore. 121 } 122 } 123 124 return tmpInetAddresses.elements(); 125 } 126 127 /** 128 * Returns the display name of the interface 129 * 130 * @return The display name of the interface 131 */ 132 public String getDisplayName() 133 { 134 return netif.name; 135 } 136 137 /** 138 * Returns an network interface by name 139 * 140 * @param name The name of the interface to return 141 * 142 * @return a <code>NetworkInterface</code> object representing the interface, 143 * or null if there is no interface with that name. 144 * 145 * @exception SocketException If an error occurs 146 * @exception NullPointerException If the specified name is null 147 */ 148 public static NetworkInterface getByName(String name) 149 throws SocketException 150 { 151 if (name == null) 152 throw new NullPointerException(); 153 VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces(); 154 for (int i = 0; i < netifs.length; i++) 155 { 156 if (netifs[i].name.equals(name)) 157 return new NetworkInterface(netifs[i]); 158 } 159 return null; 160 } 161 162 /** 163 * Return a network interface by its address 164 * 165 * @param addr The address of the interface to return 166 * 167 * @return the interface, or <code>null</code> if none found 168 * 169 * @exception SocketException If an error occurs 170 * @exception NullPointerException If the specified addess is null 171 */ 172 public static NetworkInterface getByInetAddress(InetAddress addr) 173 throws SocketException 174 { 175 if (addr == null) 176 throw new NullPointerException(); 177 VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces(); 178 for (int i = 0; i < netifs.length; i++) 179 { 180 if (netifs[i].addresses.contains(addr)) 181 return new NetworkInterface(netifs[i]); 182 } 183 return null; 184 } 185 186 /** 187 * Return an <code>Enumeration</code> of all available network interfaces 188 * 189 * @return all interfaces 190 * 191 * @exception SocketException If an error occurs 192 */ 193 public static Enumeration<NetworkInterface> getNetworkInterfaces() 194 throws SocketException 195 { 196 VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces(); 197 Vector<NetworkInterface> networkInterfaces = 198 new Vector<NetworkInterface>(netifs.length); 199 for (int i = 0; i < netifs.length; i++) 200 { 201 if (!netifs[i].addresses.isEmpty()) 202 networkInterfaces.add(new NetworkInterface(netifs[i])); 203 } 204 return networkInterfaces.elements(); 205 } 206 207 /** 208 * Checks if the current instance is equal to obj 209 * 210 * @param obj The object to compare with 211 * 212 * @return <code>true</code> if equal, <code>false</code> otherwise 213 */ 214 public boolean equals(Object obj) 215 { 216 if (! (obj instanceof NetworkInterface)) 217 return false; 218 219 NetworkInterface tmp = (NetworkInterface) obj; 220 221 if (netif.name == null) 222 return tmp.netif.name == null; 223 224 return (netif.name.equals(tmp.netif.name) 225 && (netif.addresses.equals(tmp.netif.addresses))); 226 } 227 228 /** 229 * Returns the hashcode of the current instance 230 * 231 * @return the hashcode 232 */ 233 public int hashCode() 234 { 235 // FIXME: hash correctly 236 int hc = netif.addresses.hashCode(); 237 238 if (netif.name != null) 239 hc += netif.name.hashCode(); 240 241 return hc; 242 } 243 244 /** 245 * Returns a string representation of the interface 246 * 247 * @return the string 248 */ 249 public String toString() 250 { 251 // FIXME: check if this is correct 252 CPStringBuilder result; 253 String separator = SystemProperties.getProperty("line.separator"); 254 255 result = new CPStringBuilder(); 256 257 result.append("name: "); 258 result.append(getDisplayName()); 259 result.append(" (").append(getName()).append(") addresses:"); 260 result.append(separator); 261 262 for (Iterator it = netif.addresses.iterator(); it.hasNext(); ) 263 { 264 InetAddress address = (InetAddress) it.next(); 265 result.append(address.toString()).append(";").append(separator); 266 } 267 268 return result.toString(); 269 } 270 271 /** 272 * Determines whether this interface is ready to transfer data. 273 * 274 * @return whether the interface is up 275 */ 276 public boolean isUp() 277 throws SocketException 278 { 279 return VMNetworkInterface.isUp(netif.name); 280 } 281 282 /** 283 * Determines whether this interface does point to point 284 * transmission. 285 * 286 * @return whether the interface does point to point transmission 287 */ 288 public boolean isPointToPoint() 289 throws SocketException 290 { 291 return VMNetworkInterface.isPointToPoint(netif.name); 292 } 293 294 /** 295 * Determines whether this interface is the loopback interface. 296 * 297 * @return whether the interface is the loopback interface 298 */ 299 public boolean isLoopback() 300 throws SocketException 301 { 302 return VMNetworkInterface.isLoopback(netif.name); 303 } 304 305 /** 306 * Determines whether this interface supports multicast transmission. 307 * 308 * @return whether the interface supports multicast transmission. 309 */ 310 public boolean supportsMulticast() 311 throws SocketException 312 { 313 return VMNetworkInterface.supportsMulticast(netif.name); 314 } 315 316}