Source for java.net.InetAddress

   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: }