001/* NetworkInterface.java -- 002 Copyright (C) 2002, 2003, 2004, 2005 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 java.util.Collection; 042import java.util.Collections; 043import java.util.Enumeration; 044import java.util.HashMap; 045import java.util.Iterator; 046import java.util.Map; 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 String name; 062 private Vector<InetAddress> inetAddresses; 063 064 NetworkInterface(String name, InetAddress address) 065 { 066 this.name = name; 067 this.inetAddresses = new Vector(1, 1); 068 this.inetAddresses.add(address); 069 } 070 071 NetworkInterface(String name, InetAddress[] addresses) 072 { 073 this.name = name; 074 this.inetAddresses = new Vector(addresses.length, 1); 075 076 for (int i = 0; i < addresses.length; i++) 077 this.inetAddresses.add(addresses[i]); 078 } 079 080 /** 081 * Returns the name of the network interface 082 * 083 * @return The name of the interface. 084 */ 085 public String getName() 086 { 087 return name; 088 } 089 090 /** 091 * Returns all available addresses of the network interface 092 * 093 * If a @see SecurityManager is available all addresses are checked 094 * with @see SecurityManager::checkConnect() if they are available. 095 * Only <code>InetAddresses</code> are returned where the security manager 096 * doesn't throw an exception. 097 * 098 * @return An enumeration of all addresses. 099 */ 100 public Enumeration<InetAddress> getInetAddresses() 101 { 102 SecurityManager s = System.getSecurityManager(); 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(), 58000); 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 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 for (Enumeration e = getNetworkInterfaces(); e.hasMoreElements();) 152 { 153 NetworkInterface tmp = (NetworkInterface) e.nextElement(); 154 155 if (name.equals(tmp.getName())) 156 return tmp; 157 } 158 159 // No interface with the given name found. 160 return null; 161 } 162 163 /** 164 * Return a network interface by its address 165 * 166 * @param addr The address of the interface to return 167 * 168 * @return the interface, or <code>null</code> if none found 169 * 170 * @exception SocketException If an error occurs 171 * @exception NullPointerException If the specified addess is null 172 */ 173 public static NetworkInterface getByInetAddress(InetAddress addr) 174 throws SocketException 175 { 176 for (Enumeration interfaces = getNetworkInterfaces(); 177 interfaces.hasMoreElements();) 178 { 179 NetworkInterface tmp = (NetworkInterface) interfaces.nextElement(); 180 181 for (Enumeration addresses = tmp.inetAddresses.elements(); 182 addresses.hasMoreElements();) 183 { 184 if (addr.equals((InetAddress) addresses.nextElement())) 185 return tmp; 186 } 187 } 188 189 throw new SocketException("no network interface is bound to such an IP address"); 190 } 191 192 static private Collection condense(Collection interfaces) 193 { 194 final Map condensed = new HashMap(); 195 196 final Iterator interfs = interfaces.iterator(); 197 while (interfs.hasNext()) { 198 199 final NetworkInterface face = (NetworkInterface) interfs.next(); 200 final String name = face.getName(); 201 202 if (condensed.containsKey(name)) 203 { 204 final NetworkInterface conface = (NetworkInterface) condensed.get(name); 205 if (!conface.inetAddresses.containsAll(face.inetAddresses)) 206 { 207 final Iterator faceAddresses = face.inetAddresses.iterator(); 208 while (faceAddresses.hasNext()) 209 { 210 final InetAddress faceAddress = (InetAddress) faceAddresses.next(); 211 if (!conface.inetAddresses.contains(faceAddress)) 212 { 213 conface.inetAddresses.add(faceAddress); 214 } 215 } 216 } 217 } 218 else 219 { 220 condensed.put(name, face); 221 } 222 } 223 224 return condensed.values(); 225 } 226 227 /** 228 * Return an <code>Enumeration</code> of all available network interfaces 229 * 230 * @return all interfaces 231 * 232 * @exception SocketException If an error occurs 233 */ 234 public static Enumeration<NetworkInterface> getNetworkInterfaces() 235 throws SocketException 236 { 237 Vector<NetworkInterface> networkInterfaces = 238 VMNetworkInterface.getInterfaces(); 239 240 if (networkInterfaces.isEmpty()) 241 return null; 242 243 Collection condensed = condense(networkInterfaces); 244 245 return Collections.enumeration(condensed); 246 } 247 248 /** 249 * Checks if the current instance is equal to obj 250 * 251 * @param obj The object to compare with 252 * 253 * @return <code>true</code> if equal, <code>false</code> otherwise 254 */ 255 public boolean equals(Object obj) 256 { 257 if (! (obj instanceof NetworkInterface)) 258 return false; 259 260 NetworkInterface tmp = (NetworkInterface) obj; 261 262 return (name.equals(tmp.name) && inetAddresses.equals(tmp.inetAddresses)); 263 } 264 265 /** 266 * Returns the hashcode of the current instance 267 * 268 * @return the hashcode 269 */ 270 public int hashCode() 271 { 272 // FIXME: hash correctly 273 return name.hashCode() + inetAddresses.hashCode(); 274 } 275 276 /** 277 * Returns a string representation of the interface 278 * 279 * @return the string 280 */ 281 public String toString() 282 { 283 // FIXME: check if this is correct 284 String result; 285 String separator = System.getProperty("line.separator"); 286 287 result = 288 "name: " + getDisplayName() + " (" + getName() + ") addresses:" 289 + separator; 290 291 for (Enumeration e = inetAddresses.elements(); e.hasMoreElements();) 292 { 293 InetAddress address = (InetAddress) e.nextElement(); 294 result += address.toString() + ";" + separator; 295 } 296 297 return result; 298 } 299}