001/* InetAddress.java -- Class to model an Internet address 002 Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006 003 Free Software Foundation, Inc. 004 005This file is part of GNU Classpath. 006 007GNU Classpath is free software; you can redistribute it and/or modify 008it under the terms of the GNU General Public License as published by 009the Free Software Foundation; either version 2, or (at your option) 010any later version. 011 012GNU Classpath is distributed in the hope that it will be useful, but 013WITHOUT ANY WARRANTY; without even the implied warranty of 014MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015General Public License for more details. 016 017You should have received a copy of the GNU General Public License 018along with GNU Classpath; see the file COPYING. If not, write to the 019Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02002110-1301 USA. 021 022Linking this library statically or dynamically with other modules is 023making a combined work based on this library. Thus, the terms and 024conditions of the GNU General Public License cover the whole 025combination. 026 027As a special exception, the copyright holders of this library give you 028permission to link this library with independent modules to produce an 029executable, regardless of the license terms of these independent 030modules, and to copy and distribute the resulting executable under 031terms of your choice, provided that you also meet, for each linked 032independent module, the terms and conditions of the license of that 033module. An independent module is a module which is not derived from 034or based on this library. If you modify this library, you may extend 035this exception to your version of the library, but you are not 036obligated to do so. If you do not wish to do so, delete this 037exception statement from your version. */ 038 039 040package java.net; 041 042import java.io.IOException; 043import java.io.ObjectInputStream; 044import java.io.ObjectOutputStream; 045import java.io.ObjectStreamException; 046import java.io.Serializable; 047 048/** 049 * This class models an Internet address. It does not have a public 050 * constructor. Instead, new instances of this objects are created 051 * using the static methods getLocalHost(), getByName(), and 052 * getAllByName(). 053 * 054 * <p>This class fulfills the function of the C style functions gethostname(), 055 * gethostbyname(), and gethostbyaddr(). It resolves Internet DNS names 056 * into their corresponding numeric addresses and vice versa.</p> 057 * 058 * @author Aaron M. Renn (arenn@urbanophile.com) 059 * @author Per Bothner 060 * @author Gary Benson (gbenson@redhat.com) 061 * 062 * @specnote This class is not final since JDK 1.4 063 */ 064public class InetAddress implements Serializable 065{ 066 private static final long serialVersionUID = 3286316764910316507L; 067 068 /** 069 * Dummy InetAddress, used to bind socket to any (all) network interfaces. 070 */ 071 static InetAddress ANY_IF; 072 static 073 { 074 byte[] addr; 075 try 076 { 077 addr = VMInetAddress.lookupInaddrAny(); 078 } 079 catch (UnknownHostException e) 080 { 081 // Make one up and hope it works. 082 addr = new byte[] {0, 0, 0, 0}; 083 } 084 try 085 { 086 ANY_IF = getByAddress(addr); 087 } 088 catch (UnknownHostException e) 089 { 090 throw (InternalError) new InternalError().initCause(e); 091 } 092 ANY_IF.hostName = ANY_IF.getHostName(); 093 } 094 095 /** 096 * Stores static localhost address object. 097 */ 098 static InetAddress LOCALHOST; 099 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}