Frames | No Frames |
1: /* InetAddress.java -- Class to model an Internet address 2: Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.net; 41: 42: import java.io.IOException; 43: import java.io.ObjectInputStream; 44: import java.io.ObjectOutputStream; 45: import java.io.ObjectStreamException; 46: import java.io.Serializable; 47: 48: /** 49: * This class models an Internet address. It does not have a public 50: * constructor. Instead, new instances of this objects are created 51: * using the static methods getLocalHost(), getByName(), and 52: * getAllByName(). 53: * 54: * <p>This class fulfills the function of the C style functions gethostname(), 55: * gethostbyname(), and gethostbyaddr(). It resolves Internet DNS names 56: * into their corresponding numeric addresses and vice versa.</p> 57: * 58: * @author Aaron M. Renn (arenn@urbanophile.com) 59: * @author Per Bothner 60: * @author Gary Benson (gbenson@redhat.com) 61: * 62: * @specnote This class is not final since JDK 1.4 63: */ 64: public class InetAddress implements Serializable 65: { 66: private static final long serialVersionUID = 3286316764910316507L; 67: 68: /** 69: * Dummy InetAddress, used to bind socket to any (all) network interfaces. 70: */ 71: static InetAddress ANY_IF; 72: static 73: { 74: byte[] addr; 75: try 76: { 77: addr = VMInetAddress.lookupInaddrAny(); 78: } 79: catch (UnknownHostException e) 80: { 81: // Make one up and hope it works. 82: addr = new byte[] {0, 0, 0, 0}; 83: } 84: try 85: { 86: ANY_IF = getByAddress(addr); 87: } 88: catch (UnknownHostException e) 89: { 90: throw (InternalError) new InternalError().initCause(e); 91: } 92: ANY_IF.hostName = ANY_IF.getHostName(); 93: } 94: 95: /** 96: * Stores static localhost address object. 97: */ 98: static InetAddress LOCALHOST; 99: static 100: { 101: try 102: { 103: LOCALHOST = getByAddress("localhost", new byte[] {127, 0, 0, 1}); 104: } 105: catch (UnknownHostException e) 106: { 107: throw (InternalError) new InternalError().initCause(e); 108: } 109: } 110: 111: /** 112: * The Serialized Form specifies that an int 'address' is saved/restored. 113: * This class uses a byte array internally so we'll just do the conversion 114: * at serialization time and leave the rest of the algorithm as is. 115: */ 116: private int address; 117: 118: /** 119: * An array of octets representing an IP address. 120: */ 121: transient byte[] addr; 122: 123: /** 124: * The name of the host for this address. 125: */ 126: String hostName; 127: 128: /** 129: * Needed for serialization. 130: */ 131: private int family; 132: 133: /** 134: * Constructor. Prior to the introduction of IPv6 support in 1.4, 135: * methods such as InetAddress.getByName() would return InetAddress 136: * objects. From 1.4 such methods returned either Inet4Address or 137: * Inet6Address objects, but for compatibility Inet4Address objects 138: * are serialized as InetAddresses. As such, there are only two 139: * places where it is appropriate to invoke this constructor: within 140: * subclasses constructors and within Inet4Address.writeReplace(). 141: * 142: * @param ipaddr The IP number of this address as an array of bytes 143: * @param hostname The hostname of this IP address. 144: * @param family The address family of this IP address. 145: */ 146: InetAddress(byte[] ipaddr, String hostname, int family) 147: { 148: addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone(); 149: hostName = hostname; 150: this.family = family; 151: } 152: 153: /** 154: * Returns true if this address is a multicast address, false otherwise. 155: * An address is multicast if the high four bits are "1110". These are 156: * also known as "Class D" addresses. 157: * 158: * <p>This method cannot be abstract for backward compatibility reasons. By 159: * default it always throws {@link UnsupportedOperationException} unless 160: * overridden.</p> 161: * 162: * @return true if mulitcast, false if not 163: * 164: * @since 1.1 165: */ 166: public boolean isMulticastAddress() 167: { 168: throw new UnsupportedOperationException(); 169: } 170: 171: /** 172: * Utility routine to check if the InetAddress in a wildcard address 173: * 174: * <p>This method cannot be abstract for backward compatibility reasons. By 175: * default it always throws {@link UnsupportedOperationException} unless 176: * overridden.</p> 177: * 178: * @since 1.4 179: */ 180: public boolean isAnyLocalAddress() 181: { 182: throw new UnsupportedOperationException(); 183: } 184: 185: /** 186: * Utility routine to check if the InetAddress is a loopback address 187: * 188: * <p>This method cannot be abstract for backward compatibility reasons. By 189: * default it always throws {@link UnsupportedOperationException} unless 190: * overridden.</p> 191: * 192: * @since 1.4 193: */ 194: public boolean isLoopbackAddress() 195: { 196: throw new UnsupportedOperationException(); 197: } 198: 199: /** 200: * Utility routine to check if InetAddress is a link local address 201: * 202: * <p>This method cannot be abstract for backward compatibility reasons. By 203: * default it always throws {@link UnsupportedOperationException} unless 204: * overridden.</p> 205: * 206: * @since 1.4 207: */ 208: public boolean isLinkLocalAddress() 209: { 210: throw new UnsupportedOperationException(); 211: } 212: 213: /** 214: * Utility routine to check if InetAddress is a site local address 215: * 216: * <p>This method cannot be abstract for backward compatibility reasons. By 217: * default it always throws {@link UnsupportedOperationException} unless 218: * overridden.</p> 219: * 220: * @since 1.4 221: */ 222: public boolean isSiteLocalAddress() 223: { 224: throw new UnsupportedOperationException(); 225: } 226: 227: /** 228: * Utility routine to check if InetAddress is a global multicast address 229: * 230: * <p>This method cannot be abstract for backward compatibility reasons. By 231: * default it always throws {@link UnsupportedOperationException} unless 232: * overridden.</p> 233: * 234: * @since 1.4 235: */ 236: public boolean isMCGlobal() 237: { 238: throw new UnsupportedOperationException(); 239: } 240: 241: /** 242: * Utility routine to check if InetAddress is a node local multicast address. 243: * 244: * <p>This method cannot be abstract for backward compatibility reasons. By 245: * default it always throws {@link UnsupportedOperationException} unless 246: * overridden.</p> 247: * 248: * @since 1.4 249: */ 250: public boolean isMCNodeLocal() 251: { 252: throw new UnsupportedOperationException(); 253: } 254: 255: /** 256: * Utility routine to check if InetAddress is a link local multicast address. 257: * 258: * <p>This method cannot be abstract for backward compatibility reasons. By 259: * default it always throws {@link UnsupportedOperationException} unless 260: * overridden.</p> 261: * 262: * @since 1.4 263: */ 264: public boolean isMCLinkLocal() 265: { 266: throw new UnsupportedOperationException(); 267: } 268: 269: /** 270: * Utility routine to check if InetAddress is a site local multicast address. 271: * 272: * <p>This method cannot be abstract for backward compatibility reasons. By 273: * default it always throws {@link UnsupportedOperationException} unless 274: * overridden.</p> 275: * 276: * @since 1.4 277: */ 278: public boolean isMCSiteLocal() 279: { 280: throw new UnsupportedOperationException(); 281: } 282: 283: /** 284: * Utility routine to check if InetAddress is a organization local 285: * multicast address. 286: * 287: * <p>This method cannot be abstract for backward compatibility reasons. By 288: * default it always throws {@link UnsupportedOperationException} unless 289: * overridden.</p> 290: * 291: * @since 1.4 292: */ 293: public boolean isMCOrgLocal() 294: { 295: throw new UnsupportedOperationException(); 296: } 297: 298: /** 299: * Returns the hostname for this address. This will return the IP address 300: * as a String if there is no hostname available for this address 301: * 302: * @return The hostname for this address 303: */ 304: public String getHostName() 305: { 306: if (hostName == null) 307: hostName = getCanonicalHostName(); 308: 309: return hostName; 310: } 311: 312: /** 313: * Returns the canonical hostname represented by this InetAddress 314: */ 315: String internalGetCanonicalHostName() 316: { 317: try 318: { 319: return ResolverCache.getHostByAddr(addr); 320: } 321: catch (UnknownHostException e) 322: { 323: return getHostAddress(); 324: } 325: } 326: 327: /** 328: * Returns the canonical hostname represented by this InetAddress 329: * 330: * @since 1.4 331: */ 332: public String getCanonicalHostName() 333: { 334: String hostname = internalGetCanonicalHostName(); 335: 336: SecurityManager sm = System.getSecurityManager(); 337: if (sm != null) 338: { 339: try 340: { 341: sm.checkConnect(hostname, -1); 342: } 343: catch (SecurityException e) 344: { 345: return getHostAddress(); 346: } 347: } 348: 349: return hostname; 350: } 351: 352: /** 353: * Returns the IP address of this object as a byte array. 354: * 355: * @return IP address 356: */ 357: public byte[] getAddress() 358: { 359: // An experiment shows that JDK1.2 returns a different byte array each 360: // time. This makes sense, in terms of security. 361: return (byte[]) addr.clone(); 362: } 363: 364: /** 365: * Returns the IP address of this object as a String. 366: * 367: * <p>This method cannot be abstract for backward compatibility reasons. By 368: * default it always throws {@link UnsupportedOperationException} unless 369: * overridden.</p> 370: * 371: * @return The IP address of this object in String form 372: * 373: * @since 1.0.2 374: */ 375: public String getHostAddress() 376: { 377: throw new UnsupportedOperationException(); 378: } 379: 380: /** 381: * Returns a hash value for this address. Useful for creating hash 382: * tables. Overrides Object.hashCode() 383: * 384: * @return A hash value for this address. 385: */ 386: public int hashCode() 387: { 388: // There hashing algorithm is not specified, but a simple experiment 389: // shows that it is equal to the address, as a 32-bit big-endian integer. 390: int hash = 0; 391: int len = addr.length; 392: int i = len > 4 ? len - 4 : 0; 393: 394: for (; i < len; i++) 395: hash = (hash << 8) | (addr[i] & 0xff); 396: 397: return hash; 398: } 399: 400: /** 401: * Tests this address for equality against another InetAddress. The two 402: * addresses are considered equal if they contain the exact same octets. 403: * This implementation overrides Object.equals() 404: * 405: * @param obj The address to test for equality 406: * 407: * @return true if the passed in object's address is equal to this one's, 408: * false otherwise 409: */ 410: public boolean equals(Object obj) 411: { 412: if (! (obj instanceof InetAddress)) 413: return false; 414: 415: // "The Java Class Libraries" 2nd edition says "If a machine has 416: // multiple names instances of InetAddress for different name of 417: // that same machine are not equal. This is because they have 418: // different host names." This violates the description in the 419: // JDK 1.2 API documentation. A little experimentation 420: // shows that the latter is correct. 421: byte[] addr2 = ((InetAddress) obj).addr; 422: 423: if (addr.length != addr2.length) 424: return false; 425: 426: for (int i = 0; i < addr.length; i++) 427: if (addr[i] != addr2[i]) 428: return false; 429: 430: return true; 431: } 432: 433: /** 434: * Converts this address to a String. This string contains the IP in 435: * dotted decimal form. For example: "127.0.0.1" This method is equivalent 436: * to getHostAddress() and overrides Object.toString() 437: * 438: * @return This address in String form 439: */ 440: public String toString() 441: { 442: String addr = getHostAddress(); 443: String host = (hostName != null) ? hostName : ""; 444: return host + "/" + addr; 445: } 446: 447: /** 448: * Returns an InetAddress object given the raw IP address. 449: * 450: * The argument is in network byte order: the highest order byte of the 451: * address is in getAddress()[0]. 452: * 453: * @param addr The IP address to create the InetAddress object from 454: * 455: * @exception UnknownHostException If IP address has illegal length 456: * 457: * @since 1.4 458: */ 459: public static InetAddress getByAddress(byte[] addr) 460: throws UnknownHostException 461: { 462: return getByAddress(null, addr); 463: } 464: 465: /** 466: * Creates an InetAddress based on the provided host name and IP address. 467: * No name service is checked for the validity of the address. 468: * 469: * @param host The hostname of the InetAddress object to create 470: * @param addr The IP address to create the InetAddress object from 471: * 472: * @exception UnknownHostException If IP address is of illegal length 473: * 474: * @since 1.4 475: */ 476: public static InetAddress getByAddress(String host, byte[] addr) 477: throws UnknownHostException 478: { 479: if (addr.length == 4) 480: return new Inet4Address(addr, host); 481: 482: if (addr.length == 16) 483: { 484: for (int i = 0; i < 12; i++) 485: { 486: if (addr[i] != (i < 10 ? 0 : (byte) 0xFF)) 487: return new Inet6Address(addr, host); 488: } 489: 490: byte[] ip4addr = new byte[4]; 491: ip4addr[0] = addr[12]; 492: ip4addr[1] = addr[13]; 493: ip4addr[2] = addr[14]; 494: ip4addr[3] = addr[15]; 495: return new Inet4Address(ip4addr, host); 496: } 497: 498: throw new UnknownHostException("IP address has illegal length"); 499: } 500: 501: /** 502: * Returns an InetAddress object representing the IP address of 503: * the given literal IP address in dotted decimal format such as 504: * "127.0.0.1". This is used by SocketPermission.setHostPort() 505: * to parse literal IP addresses without performing a DNS lookup. 506: * 507: * @param literal The literal IP address to create the InetAddress 508: * object from 509: * 510: * @return The address of the host as an InetAddress object, or 511: * null if the IP address is invalid. 512: */ 513: static InetAddress getByLiteral(String literal) 514: { 515: byte[] address = VMInetAddress.aton(literal); 516: if (address == null) 517: return null; 518: 519: try 520: { 521: return getByAddress(address); 522: } 523: catch (UnknownHostException e) 524: { 525: throw (InternalError) new InternalError().initCause(e); 526: } 527: } 528: 529: /** 530: * Returns an InetAddress object representing the IP address of the given 531: * hostname. This name can be either a hostname such as "www.urbanophile.com" 532: * or an IP address in dotted decimal format such as "127.0.0.1". If the 533: * hostname is null or "", the hostname of the local machine is supplied by 534: * default. This method is equivalent to returning the first element in 535: * the InetAddress array returned from GetAllByName. 536: * 537: * @param hostname The name of the desired host, or null for the local 538: * loopback address. 539: * 540: * @return The address of the host as an InetAddress object. 541: * 542: * @exception UnknownHostException If no IP address for the host could 543: * be found 544: * @exception SecurityException If a security manager exists and its 545: * checkConnect method doesn't allow the operation 546: */ 547: public static InetAddress getByName(String hostname) 548: throws UnknownHostException 549: { 550: InetAddress[] addresses = getAllByName(hostname); 551: return addresses[0]; 552: } 553: 554: /** 555: * Returns an array of InetAddress objects representing all the host/ip 556: * addresses of a given host, given the host's name. This name can be 557: * either a hostname such as "www.urbanophile.com" or an IP address in 558: * dotted decimal format such as "127.0.0.1". If the value is null, the 559: * hostname of the local machine is supplied by default. 560: * 561: * @param hostname The name of the desired host, or null for the 562: * local loopback address. 563: * 564: * @return All addresses of the host as an array of InetAddress objects. 565: * 566: * @exception UnknownHostException If no IP address for the host could 567: * be found 568: * @exception SecurityException If a security manager exists and its 569: * checkConnect method doesn't allow the operation 570: */ 571: public static InetAddress[] getAllByName(String hostname) 572: throws UnknownHostException 573: { 574: // If null or the empty string is supplied, the loopback address 575: // is returned. 576: if (hostname == null || hostname.length() == 0) 577: return new InetAddress[] {LOCALHOST}; 578: 579: // Check if hostname is an IP address 580: InetAddress address = getByLiteral(hostname); 581: if (address != null) 582: return new InetAddress[] {address}; 583: 584: // Perform security check before resolving 585: SecurityManager sm = System.getSecurityManager(); 586: if (sm != null) 587: sm.checkConnect(hostname, -1); 588: 589: // Resolve the hostname 590: byte[][] iplist = ResolverCache.getHostByName(hostname); 591: if (iplist.length == 0) 592: throw new UnknownHostException(hostname); 593: 594: InetAddress[] addresses = new InetAddress[iplist.length]; 595: for (int i = 0; i < iplist.length; i++) 596: addresses[i] = getByAddress(hostname, iplist[i]); 597: 598: return addresses; 599: } 600: 601: /** 602: * Returns an InetAddress object representing the address of the current 603: * host. 604: * 605: * @return The local host's address 606: * 607: * @exception UnknownHostException If no IP address for the host could 608: * be found 609: */ 610: public static InetAddress getLocalHost() throws UnknownHostException 611: { 612: String hostname = VMInetAddress.getLocalHostname(); 613: try 614: { 615: return getByName(hostname); 616: } 617: catch (SecurityException e) 618: { 619: return LOCALHOST; 620: } 621: } 622: 623: /** 624: * Inet4Address objects are serialized as InetAddress objects. 625: * This deserializes them back into Inet4Address objects. 626: */ 627: private Object readResolve() throws ObjectStreamException 628: { 629: return new Inet4Address(addr, hostName); 630: } 631: 632: private void readObject(ObjectInputStream ois) 633: throws IOException, ClassNotFoundException 634: { 635: ois.defaultReadObject(); 636: addr = new byte[4]; 637: addr[3] = (byte) address; 638: 639: for (int i = 2; i >= 0; --i) 640: addr[i] = (byte) (address >>= 8); 641: } 642: 643: private void writeObject(ObjectOutputStream oos) throws IOException 644: { 645: // Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address 646: // or a 16 byte IPv6 address. 647: int len = addr.length; 648: int i = len - 4; 649: 650: for (; i < len; i++) 651: address = address << 8 | (addr[i] & 0xff); 652: 653: oos.defaultWriteObject(); 654: } 655: }