home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / sybase / starbuck / java.z / InetAddress.java < prev    next >
Text File  |  1996-05-03  |  10KB  |  318 lines

  1. /*
  2.  * @(#)InetAddress.java    1.28 96/04/29 Jonathan Payne
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.net;
  21.  
  22. import java.util.Hashtable;
  23.  
  24. /**
  25.  * A class that represents Internet addresses.
  26.  *
  27.  * @version     1.28, 29 Apr 1996
  28.  * @author     Jonathan Payne
  29.  * @author     Arthur van Hoff
  30.  * @author     Chris Warth
  31.  */
  32. public final 
  33. class InetAddress {
  34.     private static boolean inCheck = false;
  35.     String hostName;
  36.     int address;    // Currently we only deal effectively with 32-bit addresses. 
  37.             // However this field can be expanded to be a byte array 
  38.             // or a 64-bit quantity without too much effort.
  39.     int family;
  40.  
  41.     /*
  42.      * Load net library into runtime.
  43.      */
  44.     static {
  45.     System.loadLibrary("net");
  46.     }
  47.  
  48.     /** 
  49.      * Constructor for the Socket.accept() method.
  50.      * This creates an empty InetAddress, which is filled in by
  51.      * the accept() method.  This InetAddress, however, is not
  52.      * put in the address cache, since it is not created by name.
  53.      */
  54.     InetAddress() {}
  55.  
  56.     /**
  57.      * Creates an InetAddress with the specified host name and IP address.
  58.      * @param hostName the specified host name
  59.      * @param addr the specified IP address.  The address is expected in 
  60.      *          network byte order.
  61.      * @exception UnknownHostException If the address is unknown.
  62.      */
  63.     InetAddress(String hostName, byte addr[]) {
  64.     this.hostName = new String(hostName);
  65.     this.family = getInetFamily();
  66.     /*
  67.      * We must be careful here to maintain the network byte
  68.      * order of the address.  As it comes in, the most
  69.      * significant byte of the address is in addr[0].  It
  70.      * actually doesn't matter what order they end up in the
  71.      * array, as long as it is documented and consistent.
  72.      */
  73.     address  = addr[3] & 0xFF;
  74.     address |= ((addr[2] << 8) & 0xFF00);
  75.     address |= ((addr[1] << 16) & 0xFF0000);
  76.     address |= ((addr[0] << 24) & 0xFF000000);
  77.     }
  78.  
  79.     /**
  80.      * Gets the hostname for this address; also the key in the 
  81.      * hashtable.
  82.      * If the host is equal to null, then this address refers to any
  83.      * of the local machine's available network addresses.
  84.      */
  85.     public String getHostName() {
  86.     if (hostName == null) {
  87.         try {
  88.         hostName = getHostByAddr(address);
  89.         } catch (UnknownHostException e) {
  90.         hostName = getHostAddress();
  91.         }
  92.     }
  93.  
  94.     return hostName;
  95.     }
  96.  
  97.     /**
  98.      * Returns the raw IP address in network byte order.  The highest
  99.      * order byte position is in addr[0]. To be prepared for 64-bit
  100.      * IP addresses n array of bytes is returned.
  101.  
  102.      * @return raw IP address in network byte order.
  103.      */
  104.     public byte[] getAddress() {    
  105.     byte[] addr = new byte[4];
  106.  
  107.     addr[0] = (byte) ((address >>> 24) & 0xFF);
  108.     addr[1] = (byte) ((address >>> 16) & 0xFF);
  109.     addr[2] = (byte) ((address >>> 8) & 0xFF);
  110.     addr[3] = (byte) (address & 0xFF);
  111.     return addr;
  112.     }
  113.  
  114.       /**
  115.       * Returns the IP address string "%d.%d.%d.%d"
  116.       * @return raw IP address in a string format
  117.       */
  118.      public String getHostAddress() {    
  119.          return ((address >>> 24) & 0xFF) + "." +
  120.                 ((address >>> 16) & 0xFF) + "." +
  121.                 ((address >>>  8) & 0xFF) + "." +
  122.                 ((address >>>  0) & 0xFF);
  123.      }
  124.  
  125.  
  126.     /**
  127.      * Returns a hashcode for this InetAddress.
  128.      */
  129.     public int hashCode() {
  130.     return address;
  131.     }
  132.  
  133.     /**
  134.      * Compares this object against the specified object.
  135.      * @param obj the object to compare against.
  136.      * @return true if the objects are the same; false otherwise.
  137.      */
  138.     public boolean equals(Object obj) {
  139.     return (obj != null) && (obj instanceof InetAddress) &&
  140.         (((InetAddress)obj).address == address);
  141.     }
  142.  
  143.     /**
  144.      * Converts the InetAddress to a String.
  145.      */
  146.     public String toString() {
  147.     return ((hostName != null) ? hostName + "/" : "") +
  148.     getHostAddress();
  149.     }
  150.  
  151.     /* 
  152.      * Cached addresses - our own litle nis, not! 
  153.      *
  154.      * Do not purge cache of numerical IP addresses, since 
  155.      * duplicate dynamic DNS name lookups can leave the system
  156.      * vulnerable to hostname spoofing attacks.  Once a hostname
  157.      * has been looked up in DNS and entered into the Java cache, 
  158.      * from then on, the hostname is translated to IP address only
  159.      * via the cache.
  160.      */
  161.     static Hashtable        addressCache = new Hashtable();
  162.     static InetAddress        unknownAddress;
  163.     static InetAddress        anyLocalAddress;
  164.     static InetAddress      localHost;
  165.     /* 
  166.      * generic localHost to give back to applets 
  167.      * - private so not API delta
  168.      */
  169.     private static InetAddress      loopbackHost;
  170.  
  171.     static {
  172.     unknownAddress = new InetAddress();
  173.     anyLocalAddress = new InetAddress();
  174.     makeAnyLocalAddress(anyLocalAddress);
  175.     byte[] IP = new byte[4];
  176.     IP[0] = 0x7F;
  177.     IP[1] = 0x00;
  178.     IP[2] = 0x00;
  179.     IP[3] = 0x01;
  180.     loopbackHost = new InetAddress("localhost", IP);
  181.     
  182.     try {
  183.         localHost = getByName(getLocalHostName());
  184.     } catch (Exception ex) {
  185.         localHost = unknownAddress;
  186.     }
  187.  
  188.     /* cache the name/address pair "0.0.0.0"/0.0.0.0 */
  189.     String unknownByAddr = new String("0.0.0.0");
  190.     InetAddress[] unknown_array = new InetAddress[1];
  191.     unknown_array[0] = new InetAddress(unknownByAddr, unknownAddress.getAddress());
  192.     addressCache.put(unknownByAddr, unknown_array);
  193.     }
  194.  
  195.     /**
  196.      * Returns a network address for the indicated host.  A host name
  197.      * of null refers to default address for the local machine.  A local
  198.      * cache is used to speed access to addresses.  If all
  199.      * addresses for a host are needed, use the getAllByName() method.
  200.      * @param host the specified host
  201.      * @exception UnknownHostException If the address is unknown.
  202.      */
  203.     public static synchronized InetAddress getByName(String host)
  204.     throws UnknownHostException
  205.     {
  206.     if (host == null || host.length() == 0) {
  207.         return loopbackHost;
  208.     }
  209.     return getAllByName(host)[0];
  210.    }
  211.  
  212.     /** 
  213.      * Given a hostname, returns an array of all the corresponding InetAddresses.  
  214.      * @exception UnknownHostException If the host name could not be resolved
  215.      */
  216.     public static synchronized InetAddress getAllByName(String host)[]
  217.     throws UnknownHostException
  218.     {
  219.  
  220.     Object objcopy = null;
  221.  
  222.     if (host == null) {
  223.         throw new UnknownHostException(host);
  224.     }
  225.  
  226.     /* make sure the connection to the host is allowed, before we
  227.        create the InetAddress */
  228.     SecurityManager security = System.getSecurityManager();
  229.     if (security != null && !security.getInCheck()) {
  230.         security.checkConnect(host, -1);
  231.     }
  232.  
  233.        /* Cache.get can return: null, unknownAddress, or InetAddress[] */
  234.     Object obj = addressCache.get(host);
  235.  
  236. //      if ((obj != null) && (obj != unknownAddress))
  237. //        for (int i = 0; i < ((InetAddress [])obj).length; i++) {
  238. //        System.out.println("GetAllByName(" + host + ")  = " + ((InetAddress [])obj)[i]);
  239. //    }
  240.  
  241.     /* If no entry in cache, then do the host lookup */
  242.     if (obj == null) {
  243.         try {
  244.         /*
  245.          * Do not put the call to lookup() inside the
  246.          * constructor.  if you do you will still be
  247.          * allocating space when the lookup fails.
  248.          */
  249.         byte[][] byte_array = lookupAllHostAddr(host);
  250.         InetAddress[] addr_array = new InetAddress[byte_array.length];
  251.  
  252.         for (int i = 0; i < byte_array.length; i++) {
  253.             byte addr[] = byte_array[i];
  254.             addr_array[i] = new InetAddress(host, addr);
  255.             /*
  256.              * For each address pair like foo.com/1.1.1.1,
  257.              * add "1.1.1.1"/1.1.1.1 to the cache, as well
  258.              */
  259.                 InetAddress[] hostByAddr_array = new InetAddress[1];
  260.             String hostByAddr = new String(addr_array[i].getHostAddress());
  261.             hostByAddr_array[0] = new InetAddress(hostByAddr, addr);
  262.             addressCache.put(hostByAddr, hostByAddr_array);
  263.         }
  264.         obj = addr_array;
  265.         } catch (UnknownHostException e) {
  266.         obj  = unknownAddress;
  267.         }
  268.         addressCache.put(host, obj);
  269.     }
  270.  
  271.     if (obj == unknownAddress) {
  272.         /*
  273.          * We currently cache the fact that a host is unknown.
  274.          */
  275.         throw new UnknownHostException(host);
  276.     }
  277.  
  278.     /* Make a copy of the InetAddress array */
  279.     try {
  280.           objcopy = ((InetAddress [])obj).clone();
  281.     } catch (CloneNotSupportedException cnse) {
  282.           cnse.printStackTrace();
  283.     }
  284.  
  285.     return (InetAddress [])objcopy;
  286.     }
  287.  
  288.     /**
  289.      * Returns the local host.
  290.      * @exception UnknownHostException If the host name could not be resolved
  291.      */
  292.     public static InetAddress getLocalHost() throws UnknownHostException {
  293.         if (localHost.equals(unknownAddress)) {
  294.         throw new UnknownHostException();
  295.     }
  296.         /* make sure the connection to the host is allowed: if yes,
  297.      * return the "real" localHost; if not, return loopback "127.0.0.1"   
  298.      */
  299.     SecurityManager security = System.getSecurityManager();
  300.     try {
  301.         if (security != null && !security.getInCheck()) 
  302.         security.checkConnect(localHost.getHostName(), -1);
  303.     } catch (java.lang.SecurityException e) { 
  304.         return loopbackHost;
  305.     }
  306.     return localHost;
  307.     }
  308.  
  309.     private static native String getLocalHostName() throws UnknownHostException;
  310.     private static native void makeAnyLocalAddress(InetAddress addr);
  311.     private static native byte[] lookupHostAddr(String hostname) throws UnknownHostException;
  312.     private static native byte[][]
  313.         lookupAllHostAddr(String hostname) throws UnknownHostException;
  314.     private static native String getHostByAddr(int addr) throws UnknownHostException;
  315.     private static native int getInetFamily();
  316. }
  317.  
  318.