/* 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., 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.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,
                        Boolean.valueOf(disable));
  }

  /**
   * Checks if local loopback mode is enabled
   *
   * @return true if loopback mode is enabled, false otherwise
   * 
   * @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 multicast group.
   *
   * @param mcastaddr 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 mcastaddr 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 packet, byte ttl)
    throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

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

    int oldttl = getImpl().getTimeToLive();
    getImpl().setTimeToLive(((int) ttl) & 0xFF);
    getImpl().send(packet);
    getImpl().setTimeToLive(oldttl);
  }
}
