/* MulticastSocket.java -- Class for using multicast sockets
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
   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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.util.Enumeration;

/**
 * Written using on-line Java Platform 1.2 API Specification, as well
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
 * Status:  Believed complete and correct.
 */

/**
 * This class models a multicast UDP socket.  A multicast address is a
 * class D internet address (one whose most significant bits are 1110).  
 * A multicast group consists of a multicast address and a well known
 * port number.  All members of the group listening on that address and
 * port will receive all the broadcasts to the group.
 * <p>
 * Please note that applets are not allowed to use multicast sockets 
 * 
 * Written using on-line Java Platform 1.2 API Specification, as well
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
 * Status:  Believed complete and correct.
 *
 * @author Warren Levy <warrenl@cygnus.com>
 * @author Aaron M. Renn (arenn@urbanophile.com) (Documentation comments)
 * @since 1.1
 * @date May 18, 1999.
 */
public class MulticastSocket extends DatagramSocket
{
  /**
   * Create a MulticastSocket that this not bound to any address
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   */
  public MulticastSocket() throws IOException
  {
    this(new InetSocketAddress(0));
  }

  /**
   * Create a multicast socket bound to the specified port
   *
   * @param port The port to bind to
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   */
  public MulticastSocket(int port) throws IOException
  {
    this(new InetSocketAddress(port));
  }

  /**
   * Create a multicast socket bound to the specified SocketAddress.
   *
   * @param address The SocketAddress the multicast socket will be bound to
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkListen method doesn't allow the operation
   *
   * @since 1.4
   */
  public MulticastSocket(SocketAddress address) throws IOException
  {
    super((SocketAddress) null);
    setReuseAddress(true);
    if (address != null)
      bind(address);
  }
  
  /**
   * Returns the interface being used for multicast packets
   * 
   * @return The multicast interface
   *
   * @exception SocketException If an error occurs
   */
  public InetAddress getInterface() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    return (InetAddress) getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
  }

  /**
   * Returns the current value of the "Time to Live" option.  This is the
   * number of hops a packet can make before it "expires".   This method id
   * deprecated.  Use <code>getTimeToLive</code> instead.
   * 
   * @return The TTL value
   *
   * @exception IOException If an error occurs
   *
   * @deprecated 1.2 Replaced by getTimeToLive()
   *
   * @see MulticastSocket#getTimeToLive()
   */
  public byte getTTL() throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    // Use getTTL here rather than getTimeToLive in case we're using an impl
    // other than the default PlainDatagramSocketImpl and it doesn't have
    // getTimeToLive yet.
    return getImpl().getTTL();
  }

  /**
   * Returns the current value of the "Time to Live" option.  This is the
   * number of hops a packet can make before it "expires". 
   * 
   * @return The TTL value
   *
   * @exception IOException If an error occurs
   *
   * @since 1.2
   */
  public int getTimeToLive() throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    return getImpl().getTimeToLive();
  }

  /**
   * Sets the interface to use for sending multicast packets.
   *
   * @param addr The new interface to use.
   *
   * @exception SocketException If an error occurs.
   *
   * @since 1.4
   */
  public void setInterface(InetAddress addr) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().setOption(SocketOptions.IP_MULTICAST_IF, addr);
  }

  /**
   * Sets the local network interface used to send multicast messages
   *
   * @param netIF The local network interface used to send multicast messages
   * 
   * @exception SocketException If an error occurs
   * 
   * @see MulticastSocket#getNetworkInterface()
   * 
   * @since 1.4
   */
  public void setNetworkInterface(NetworkInterface netIf)
    throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Enumeration e = netIf.getInetAddresses ();

    if (!e.hasMoreElements ())
      throw new SocketException("no network devices found");

    InetAddress address = (InetAddress) e.nextElement ();
    getImpl().setOption (SocketOptions.IP_MULTICAST_IF, address);
  }

  /**
   * Gets the local network interface which is used to send multicast messages
   *
   * @return The local network interface to send multicast messages
   *
   * @exception SocketException If an error occurs
   *
   * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf)
   * 
   * @since 1.4
   */
  public NetworkInterface getNetworkInterface()
    throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    InetAddress address =
      (InetAddress) getImpl().getOption (SocketOptions.IP_MULTICAST_IF);
    NetworkInterface netIf = NetworkInterface.getByInetAddress (address);

    return netIf;
  }

  /**
   * Disable/Enable local loopback of multicast packets.  The option is used by
   * the platform's networking code as a hint for setting whether multicast
   * data will be looped back to the local socket. 
   *
   * Because this option is a hint, applications that want to verify what
   * loopback mode is set to should call #getLoopbackMode
   *
   * @param disable True to disable loopback mode
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public void setLoopbackMode(boolean disable) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().setOption (SocketOptions.IP_MULTICAST_LOOP, new Boolean (disable));
  }

  /**
   * Checks if local loopback mode is enabled or not
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public boolean getLoopbackMode() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object buf = getImpl().getOption (SocketOptions.IP_MULTICAST_LOOP);

    if (buf instanceof Boolean)
      return ((Boolean) buf).booleanValue();
    
    throw new SocketException("unexpected type");
  }

  /**
   * Sets the "Time to Live" value for a socket.  The value must be between
   * 1 and 255.
   *
   * @param ttl The new TTL value
   *
   * @exception IOException If an error occurs
   *
   * @deprecated 1.2 Replaced by <code>setTimeToLive</code>
   *
   * @see MulticastSocket#setTimeToLive(int ttl)
   */
  public void setTTL(byte ttl) throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    // Use setTTL here rather than setTimeToLive in case we're using an impl
    // other than the default PlainDatagramSocketImpl and it doesn't have
    // setTimeToLive yet.
    getImpl().setTTL(ttl);
  }

  /**
   * Sets the "Time to Live" value for a socket.  The value must be between
   * 1 and 255.  
   *
   * @param ttl The new TTL value
   *
   * @exception IOException If an error occurs
   * 
   * @since 1.2
   */
  public void setTimeToLive(int ttl) throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (ttl <= 0 || ttl > 255)
      throw new IllegalArgumentException("Invalid ttl: " + ttl);

    getImpl().setTimeToLive(ttl);
  }

  /**
   * Joins the specified mulitcast group.
   *
   * @param addr The address of the group to join
   * 
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkMulticast method doesn't allow the operation
   */
  public void joinGroup(InetAddress mcastaddr) throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (! mcastaddr.isMulticastAddress())
      throw new IOException("Not a Multicast address");

    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkMulticast(mcastaddr);

    getImpl().join(mcastaddr);
  }

  /**
   * Leaves the specified multicast group
   *
   * @param addr The address of the group to leave
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkMulticast method doesn't allow the operation
   */
  public void leaveGroup(InetAddress mcastaddr) throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (! mcastaddr.isMulticastAddress())
      throw new IOException("Not a Multicast address");

    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkMulticast(mcastaddr);

    getImpl().leave(mcastaddr);
  }

  /**
   * Joins the specified mulitcast group on a specified interface.
   *
   * @param mcastaddr The multicast address to join
   * @param netIf The local network interface to receive the multicast
   * messages on or null to defer the interface set by #setInterface or
   * #setNetworkInterface
   * 
   * @exception IOException If an error occurs
   * @exception IllegalArgumentException If address type is not supported
   * @exception SecurityException If a security manager exists and its
   * checkMulticast method doesn't allow the operation
   *
   * @see MulticastSocket#setInterface(InetAddress addr)
   * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf)
   *
   * @since 1.4
   */
  public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
    throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (! (mcastaddr instanceof InetSocketAddress))
      throw new IllegalArgumentException ("SocketAddress type not supported");

    InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
    
    if (! tmp.getAddress ().isMulticastAddress ())
      throw new IOException ("Not a Multicast address");

    SecurityManager s = System.getSecurityManager ();
    if (s != null)
      s.checkMulticast (tmp.getAddress ());

    getImpl().joinGroup (mcastaddr, netIf);
  }
  
  /**
   * Leaves the specified mulitcast group on a specified interface.
   *
   * @param mcastaddr The multicast address to leave
   * @param netIf The local networki interface or null to defer to the
   * interface set by setInterface or setNetworkInterface 
   *
   * @exception IOException If an error occurs
   * @exception IllegalArgumentException If address type is not supported
   * @exception SecurityException If a security manager exists and its
   * checkMulticast method doesn't allow the operation
   *
   * @see MulticastSocket#setInterface(InetAddress addr)
   * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf)
   *
   * @since 1.4
   */
  public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
    throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
    
    if (! tmp.getAddress ().isMulticastAddress ())
      throw new IOException ("Not a Multicast address");

    SecurityManager s = System.getSecurityManager ();
    if (s != null)
      s.checkMulticast (tmp.getAddress ());

    getImpl().leaveGroup (mcastaddr, netIf);
  }
  
  /**
   * Sends a packet of data to a multicast address with a TTL that is
   * different from the default TTL on this socket.  The default TTL for
   * the socket is not changed.
   *
   * @param packet The packet of data to send
   * @param ttl The TTL for this packet
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect or checkMulticast method doesn't allow the operation
   *
   * @deprecated
   */
  public synchronized void send(DatagramPacket p, byte ttl) throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    SecurityManager s = System.getSecurityManager();
    if (s != null)
      {
        InetAddress addr = p.getAddress();
        if (addr.isMulticastAddress())
          s.checkPermission (new SocketPermission
                             (addr.getHostName () + p.getPort (),
                              "accept,connect"));
        else
          s.checkConnect(addr.getHostAddress(), p.getPort());
      }

    int oldttl = getImpl().getTimeToLive();
    getImpl().setTimeToLive(((int) ttl) & 0xFF);
    getImpl().send(p);
    getImpl().setTimeToLive(oldttl);
  }
} // class MulticastSocket
