/* InetAddress.java -- Class to model an Internet address
   Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * This class models an Internet address.  It does not have a public
 * constructor.  Instead, new instances of this objects are created
 * using the static methods getLocalHost(), getByName(), and
 * getAllByName().
 *
 * <p>This class fulfills the function of the C style functions gethostname(),
 * gethostbyname(), and gethostbyaddr().  It resolves Internet DNS names
 * into their corresponding numeric addresses and vice versa.</p>
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Per Bothner
 * @author Gary Benson (gbenson@redhat.com)
 *
 * @specnote This class is not final since JK 1.4
 */
public class InetAddress implements Serializable
{
  private static final long serialVersionUID = 3286316764910316507L;

  /**
   * Stores static localhost address object.
   */
  static InetAddress LOCALHOST;
  static
  {
    try
      {
	LOCALHOST = getByAddress("localhost", new byte[] {127, 0, 0, 1});
	// Some soon-to-be-removed native code synchronizes on this.
	loopbackAddress = LOCALHOST;
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }    

  /**
   * Dummy InetAddress, used to bind socket to any (all) network interfaces.
   */
  static InetAddress ANY_IF;
  static
  {
    byte[] addr;
    try
      {
	addr = VMInetAddress.lookupInaddrAny();
      }
    catch (UnknownHostException e)
      {
	// Make one up and hope it works.
	addr = new byte[] {0, 0, 0, 0};
      }
    try
      {
	ANY_IF = getByAddress(addr);
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
    ANY_IF.hostName = ANY_IF.getHostName();
  }
  
  /**
   * The Serialized Form specifies that an int 'address' is saved/restored.
   * This class uses a byte array internally so we'll just do the conversion
   * at serialization time and leave the rest of the algorithm as is.
   */
  private int address;

  /**
   * An array of octets representing an IP address.
   */
  transient byte[] addr;

  /**
   * The name of the host for this address.
   */
  String hostName;

  /**
   * Needed for serialization.
   */
  private int family;

  /**
   * Constructor.  Prior to the introduction of IPv6 support in 1.4,
   * methods such as InetAddress.getByName() would return InetAddress
   * objects.  From 1.4 such methods returned either Inet4Address or
   * Inet6Address objects, but for compatibility Inet4Address objects
   * are serialized as InetAddresses.  As such, there are only two
   * places where it is appropriate to invoke this constructor: within
   * subclasses constructors and within Inet4Address.writeReplace().
   *
   * @param ipaddr The IP number of this address as an array of bytes
   * @param hostname The hostname of this IP address.
   * @param family The address family of this IP address.
   */
  InetAddress(byte[] ipaddr, String hostname, int family)
  {
    addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
    hostName = hostname;
    this.family = family;
  }

  /**
   * Returns true if this address is a multicast address, false otherwise.
   * An address is multicast if the high four bits are "1110".  These are
   * also known as "Class D" addresses.
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @return true if mulitcast, false if not
   *
   * @since 1.1
   */
  public boolean isMulticastAddress()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isMulticastAddress();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if the InetAddress in a wildcard address
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isAnyLocalAddress()
  {
    // This is inefficient, but certain methods on Win32 create
    // InetAddress objects using "new InetAddress" rather than
    // "InetAddress.getByAddress" so we provide a method body.
    // This code is never executed on Posix systems.
    try
      {
	return getByAddress(hostName, addr).isAnyLocalAddress();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if the InetAddress is a loopback address
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isLoopbackAddress()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isLoopbackAddress();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if InetAddress is a link local address
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isLinkLocalAddress()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isLinkLocalAddress();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if InetAddress is a site local address
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isSiteLocalAddress()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isSiteLocalAddress();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if InetAddress is a global multicast address
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isMCGlobal()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isMCGlobal();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if InetAddress is a node local multicast address.
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isMCNodeLocal()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isMCNodeLocal();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if InetAddress is a link local multicast address.
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isMCLinkLocal()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isMCLinkLocal();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if InetAddress is a site local multicast address.
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isMCSiteLocal()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isMCSiteLocal();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Utility routine to check if InetAddress is a organization local
   * multicast address.
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @since 1.4
   */
  public boolean isMCOrgLocal()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).isMCOrgLocal();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Returns the hostname for this address.  This will return the IP address
   * as a String if there is no hostname available for this address
   *
   * @return The hostname for this address
   */
  public String getHostName()
  {
    if (hostName == null)
      hostName = getCanonicalHostName();

    return hostName;
  }

  /**
   * Returns the canonical hostname represented by this InetAddress
   */
  String internalGetCanonicalHostName()
  {
    try
      {
	return ResolverCache.getHostByAddr(addr);
      }
    catch (UnknownHostException e)
      {
	return getHostAddress();
      }
  }

  /**
   * Returns the canonical hostname represented by this InetAddress
   * 
   * @since 1.4
   */
  public String getCanonicalHostName()
  {
    String hostname = internalGetCanonicalHostName();

    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      {
        try
	  {
            sm.checkConnect(hostname, -1);
	  }
	catch (SecurityException e)
	  {
	    return getHostAddress();
	  }
      }

    return hostname;
  }

  /**
   * Returns the IP address of this object as a byte array.
   *
   * @return IP address
   */
  public byte[] getAddress()
  {
    // An experiment shows that JDK1.2 returns a different byte array each
    // time.  This makes sense, in terms of security.
    return (byte[]) addr.clone();
  }

  /**
   * Returns the IP address of this object as a String.
   *
   * <p>This method cannot be abstract for backward compatibility reasons. By
   * default it always throws {@link UnsupportedOperationException} unless
   * overridden.</p>
   * 
   * @return The IP address of this object in String form
   *
   * @since 1.0.2
   */
  public String getHostAddress()
  {
    // This method is masked on Posix systems, where all InetAddress
    // objects are created using InetAddress.getByAddress() which 
    // returns either Inet4Address or Inet6Address objects.  Certain
    // native methods on Win32 use "new InetAddress" in which case
    // this method will be visible.
    try
      {
	return getByAddress(hostName, addr).getHostAddress();
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Returns a hash value for this address.  Useful for creating hash
   * tables.  Overrides Object.hashCode()
   *
   * @return A hash value for this address.
   */
  public int hashCode()
  {
    // There hashing algorithm is not specified, but a simple experiment
    // shows that it is equal to the address, as a 32-bit big-endian integer.
    int hash = 0;
    int len = addr.length;
    int i = len > 4 ? len - 4 : 0;

    for (; i < len; i++)
      hash = (hash << 8) | (addr[i] & 0xff);

    return hash;
  }

  /**
   * Tests this address for equality against another InetAddress.  The two
   * addresses are considered equal if they contain the exact same octets.
   * This implementation overrides Object.equals()
   *
   * @param obj The address to test for equality
   *
   * @return true if the passed in object's address is equal to this one's,
   * false otherwise
   */
  public boolean equals(Object obj)
  {
    if (! (obj instanceof InetAddress))
      return false;

    // "The Java Class Libraries" 2nd edition says "If a machine has
    // multiple names instances of InetAddress for different name of
    // that same machine are not equal.  This is because they have
    // different host names."  This violates the description in the
    // JDK 1.2 API documentation.  A little experimentation
    // shows that the latter is correct.
    byte[] addr2 = ((InetAddress) obj).addr;

    if (addr.length != addr2.length)
      return false;

    for (int i = 0; i < addr.length; i++)
      if (addr[i] != addr2[i])
	return false;

    return true;
  }

  /**
   * Converts this address to a String.  This string contains the IP in
   * dotted decimal form. For example: "127.0.0.1"  This method is equivalent
   * to getHostAddress() and overrides Object.toString()
   *
   * @return This address in String form
   */
  public String toString()
  {
    String addr = getHostAddress();
    String host = (hostName != null) ? hostName : "";
    return host + "/" + addr;
  }

  /**
   * Returns an InetAddress object given the raw IP address.
   *
   * The argument is in network byte order: the highest order byte of the
   * address is in getAddress()[0].
   *
   * @param addr The IP address to create the InetAddress object from
   *
   * @exception UnknownHostException If IP address has illegal length
   *
   * @since 1.4
   */
  public static InetAddress getByAddress(byte[] addr)
    throws UnknownHostException
  {
    return getByAddress(null, addr);
  }

  /**
   * Creates an InetAddress based on the provided host name and IP address.
   * No name service is checked for the validity of the address.
   *
   * @param host The hostname of the InetAddress object to create
   * @param addr The IP address to create the InetAddress object from
   *
   * @exception UnknownHostException If IP address is of illegal length
   *
   * @since 1.4
   */
  public static InetAddress getByAddress(String host, byte[] addr)
    throws UnknownHostException
  {
    if (addr.length == 4)
      return new Inet4Address(addr, host);

    if (addr.length == 16)
      {
	for (int i = 0; i < 12; i++)
	  {
	    if (addr[i] != (i < 10 ? 0 : (byte) 0xFF))
	      return new Inet6Address(addr, host);
	  }
	  
	byte[] ip4addr = new byte[4];
	ip4addr[0] = addr[12];
	ip4addr[1] = addr[13];
	ip4addr[2] = addr[14];
	ip4addr[3] = addr[15];
	return new Inet4Address(ip4addr, host);
      }

    throw new UnknownHostException("IP address has illegal length");
  }

  /**
   * Returns an InetAddress object representing the IP address of
   * the given literal IP address in dotted decimal format such as
   * "127.0.0.1".  This is used by SocketPermission.setHostPort()
   * to parse literal IP addresses without performing a DNS lookup.
   *
   * @param literal The literal IP address to create the InetAddress
   * object from
   *
   * @return The address of the host as an InetAddress object, or
   * null if the IP address is invalid.
   */
  static InetAddress getByLiteral(String literal)
  {
    byte[] address = VMInetAddress.aton(literal);
    if (address == null)
      return null;
    
    try
      {
	return getByAddress(address);
      }
    catch (UnknownHostException e)
      {
	throw new RuntimeException("should never happen", e);
      }
  }

  /**
   * Returns an InetAddress object representing the IP address of the given
   * hostname.  This name can be either a hostname such as "www.urbanophile.com"
   * or an IP address in dotted decimal format such as "127.0.0.1".  If the
   * hostname is null or "", the hostname of the local machine is supplied by
   * default.  This method is equivalent to returning the first element in
   * the InetAddress array returned from GetAllByName.
   *
   * @param hostname The name of the desired host, or null for the local 
   * loopback address.
   *
   * @return The address of the host as an InetAddress object.
   *
   * @exception UnknownHostException If no IP address for the host could
   * be found
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   */
  public static InetAddress getByName(String hostname)
    throws UnknownHostException
  {
    InetAddress[] addresses = getAllByName(hostname);
    return addresses[0];
  }

  /**
   * Returns an array of InetAddress objects representing all the host/ip
   * addresses of a given host, given the host's name.  This name can be
   * either a hostname such as "www.urbanophile.com" or an IP address in
   * dotted decimal format such as "127.0.0.1".  If the value is null, the
   * hostname of the local machine is supplied by default.
   *
   * @param hostname The name of the desired host, or null for the
   * local loopback address.
   *
   * @return All addresses of the host as an array of InetAddress objects.
   *
   * @exception UnknownHostException If no IP address for the host could
   * be found
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   */
  public static InetAddress[] getAllByName(String hostname)
    throws UnknownHostException
  {
    // If null or the empty string is supplied, the loopback address
    // is returned.
    if (hostname == null || hostname.length() == 0)
      return new InetAddress[] {LOCALHOST};

    // Check if hostname is an IP address
    InetAddress address = getByLiteral(hostname);
    if (address != null)
      return new InetAddress[] {address};

    // Perform security check before resolving
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkConnect(hostname, -1);

    // Resolve the hostname
    byte[][] iplist = ResolverCache.getHostByName(hostname);
    if (iplist.length == 0)
      throw new UnknownHostException(hostname);

    InetAddress[] addresses = new InetAddress[iplist.length];
    for (int i = 0; i < iplist.length; i++)
      addresses[i] = getByAddress(hostname, iplist[i]);

    return addresses;
  }

  /**
   * Returns an InetAddress object representing the address of the current
   * host.
   *
   * @return The local host's address
   *
   * @exception UnknownHostException If no IP address for the host could
   * be found
   */
  public static InetAddress getLocalHost() throws UnknownHostException
  {
    String hostname = VMInetAddress.getLocalHostname();
    try
      {
	return getByName(hostname);
      }
    catch (SecurityException e)
      {
	return LOCALHOST;
      }
  }

  /**
   * Inet4Address objects are serialized as InetAddress objects.
   * This deserializes them back into Inet4Address objects.
   */
  private Object readResolve() throws ObjectStreamException
  {
    return new Inet4Address(addr, hostName);
  }

  private void readObject(ObjectInputStream ois)
    throws IOException, ClassNotFoundException
  {
    ois.defaultReadObject();
    addr = new byte[4];
    addr[3] = (byte) address;

    for (int i = 2; i >= 0; --i)
      addr[i] = (byte) (address >>= 8);
  }

  private void writeObject(ObjectOutputStream oos) throws IOException
  {
    // Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address
    // or a 16 byte IPv6 address.
    int len = addr.length;
    int i = len - 4;

    for (; i < len; i++)
      address = address << 8 | (addr[i] & 0xff);

    oos.defaultWriteObject();
  }

  // The native methods remain here for now;
  // methods in VMInetAddress map onto them.
  static native byte[] aton(String hostname);
  static native InetAddress[] lookup (String hostname,
				      InetAddress ipaddr, boolean all);
  static native int getFamily (byte[] ipaddr);
  static native String getLocalHostname();

  // Some soon-to-be-removed native code synchronizes on this.
  static InetAddress loopbackAddress;
  
  // Some soon-to-be-removed code uses this old and broken method.
  InetAddress(byte[] ipaddr, String hostname)
  {
    addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
    hostName = hostname;

    if (ipaddr != null)
      family = getFamily(ipaddr);
  }

  // Some soon-to-be-removed native code uses these old methods.
  private static InetAddress[] allocArray (int count)
  {
    return new InetAddress [count];
  }  
  private static SecurityException checkConnect (String hostname)
  {
    return null;
  }
}
