/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright 2011 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <config.h>

#include <stdlib.h>
#include <string.h>

#include "ginetaddressmask.h"
#include "ginetaddress.h"
#include "ginitable.h"
#include "gioerror.h"
#include "gioenumtypes.h"
#include "glibintl.h"

/**
 * SECTION:ginetaddressmask
 * @short_description: An IPv4/IPv6 address mask
 *
 * #GInetAddressMask represents a range of IPv4 or IPv6 addresses
 * described by a base address and a length indicating how many bits
 * of the base address are relevant for matching purposes. These are
 * often given in string form. Eg, "10.0.0.0/8", or "fe80::/10".
 */

/**
 * GInetAddressMask:
 *
 * A combination of an IPv4 or IPv6 base address and a length,
 * representing a range of IP addresses.
 *
 * Since: 2.32
 */

struct _GInetAddressMaskPrivate
{
  GInetAddress *addr;
  guint         length;
};

static void     g_inet_address_mask_initable_iface_init (GInitableIface  *iface);

G_DEFINE_TYPE_WITH_CODE (GInetAddressMask, g_inet_address_mask, G_TYPE_OBJECT,
                         G_ADD_PRIVATE (GInetAddressMask)
			 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
						g_inet_address_mask_initable_iface_init))

enum
{
  PROP_0,
  PROP_FAMILY,
  PROP_ADDRESS,
  PROP_LENGTH
};

static void
g_inet_address_mask_set_property (GObject      *object,
				  guint         prop_id,
				  const GValue *value,
				  GParamSpec   *pspec)
{
  GInetAddressMask *mask = G_INET_ADDRESS_MASK (object);

  switch (prop_id)
    {
    case PROP_ADDRESS:
      if (mask->priv->addr)
	g_object_unref (mask->priv->addr);
      mask->priv->addr = g_value_dup_object (value);
      break;

    case PROP_LENGTH:
      mask->priv->length = g_value_get_uint (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }

}

static void
g_inet_address_mask_get_property (GObject    *object,
				  guint       prop_id,
				  GValue     *value,
				  GParamSpec *pspec)
{
  GInetAddressMask *mask = G_INET_ADDRESS_MASK (object);

  switch (prop_id)
    {
    case PROP_FAMILY:
      g_value_set_enum (value, g_inet_address_get_family (mask->priv->addr));
      break;

    case PROP_ADDRESS:
      g_value_set_object (value, mask->priv->addr);
      break;

    case PROP_LENGTH:
      g_value_set_uint (value, mask->priv->length);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
g_inet_address_mask_dispose (GObject *object)
{
  GInetAddressMask *mask = G_INET_ADDRESS_MASK (object);

  g_clear_object (&mask->priv->addr);

  G_OBJECT_CLASS (g_inet_address_mask_parent_class)->dispose (object);
}

static void
g_inet_address_mask_class_init (GInetAddressMaskClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->set_property = g_inet_address_mask_set_property;
  gobject_class->get_property = g_inet_address_mask_get_property;
  gobject_class->dispose = g_inet_address_mask_dispose;

  g_object_class_install_property (gobject_class, PROP_FAMILY,
                                   g_param_spec_enum ("family",
						      P_("Address family"),
						      P_("The address family (IPv4 or IPv6)"),
						      G_TYPE_SOCKET_FAMILY,
						      G_SOCKET_FAMILY_INVALID,
						      G_PARAM_READABLE |
                                                      G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_ADDRESS,
                                   g_param_spec_object ("address",
							P_("Address"),
							P_("The base address"),
							G_TYPE_INET_ADDRESS,
							G_PARAM_READWRITE |
							G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_LENGTH,
                                   g_param_spec_uint ("length",
						      P_("Length"),
						      P_("The prefix length"),
						      0, 128, 0,
						      G_PARAM_READWRITE |
						      G_PARAM_STATIC_STRINGS));
}

static gboolean
g_inet_address_mask_initable_init (GInitable     *initable,
				   GCancellable  *cancellable,
				   GError       **error)
{
  GInetAddressMask *mask = G_INET_ADDRESS_MASK (initable);
  guint addrlen, nbytes, nbits;
  const guint8 *bytes;
  gboolean ok;

  if (!mask->priv->addr)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
			   _("No address specified"));
      return FALSE;
    }

  addrlen = g_inet_address_get_native_size (mask->priv->addr);
  if (mask->priv->length > addrlen * 8)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
		   _("Length %u is too long for address"),
		   mask->priv->length);
      return FALSE;
    }

  /* Make sure all the bits after @length are 0 */
  bytes = g_inet_address_to_bytes (mask->priv->addr);
  ok = TRUE;

  nbytes = mask->priv->length / 8;
  bytes += nbytes;
  addrlen -= nbytes;

  nbits = mask->priv->length % 8;
  if (nbits)
    {
      if (bytes[0] & (0xFF >> nbits))
	ok = FALSE;
      bytes++;
      addrlen--;
    }

  while (addrlen)
    {
      if (bytes[0])
	ok = FALSE;
      bytes++;
      addrlen--;
    }

  if (!ok)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
			   _("Address has bits set beyond prefix length"));
      return FALSE;
    }

  return TRUE;
}

static void
g_inet_address_mask_initable_iface_init (GInitableIface  *iface)
{
  iface->init = g_inet_address_mask_initable_init;
}

static void
g_inet_address_mask_init (GInetAddressMask *mask)
{
  mask->priv = g_inet_address_mask_get_instance_private (mask);
}

/**
 * g_inet_address_mask_new:
 * @addr: a #GInetAddress
 * @length: number of bits of @addr to use
 * @error: return location for #GError, or %NULL
 *
 * Creates a new #GInetAddressMask representing all addresses whose
 * first @length bits match @addr.
 *
 * Returns: a new #GInetAddressMask, or %NULL on error
 *
 * Since: 2.32
 */
GInetAddressMask *
g_inet_address_mask_new (GInetAddress  *addr,
			 guint          length,
			 GError       **error)
{
  return g_initable_new (G_TYPE_INET_ADDRESS_MASK, NULL, error,
			 "address", addr,
			 "length", length,
			 NULL);
}

/**
 * g_inet_address_mask_new_from_string:
 * @mask_string: an IP address or address/length string
 * @error: return location for #GError, or %NULL
 *
 * Parses @mask_string as an IP address and (optional) length, and
 * creates a new #GInetAddressMask. The length, if present, is
 * delimited by a "/". If it is not present, then the length is
 * assumed to be the full length of the address.
 *
 * Returns: a new #GInetAddressMask corresponding to @string, or %NULL
 * on error.
 *
 * Since: 2.32
 */
GInetAddressMask *
g_inet_address_mask_new_from_string (const gchar  *mask_string,
				     GError      **error)
{
  GInetAddressMask *mask;
  GInetAddress *addr;
  gchar *slash;
  guint length;

  slash = strchr (mask_string, '/');
  if (slash)
    {
      gchar *address, *end;

      length = strtoul (slash + 1, &end, 10);
      if (*end || !*(slash + 1))
	{
	parse_error:
	  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
		       _("Could not parse '%s' as IP address mask"),
		       mask_string);
	  return NULL;
	}

      address = g_strndup (mask_string, slash - mask_string);
      addr = g_inet_address_new_from_string (address);
      g_free (address);

      if (!addr)
	goto parse_error;
    }
  else
    {
      addr = g_inet_address_new_from_string (mask_string);
      if (!addr)
	goto parse_error;

      length = g_inet_address_get_native_size (addr) * 8;
    }

  mask = g_inet_address_mask_new (addr, length, error);
  g_object_unref (addr);

  return mask;
}

/**
 * g_inet_address_mask_to_string:
 * @mask: a #GInetAddressMask
 *
 * Converts @mask back to its corresponding string form.
 *
 * Return value: a string corresponding to @mask.
 *
 * Since: 2.32
 */
gchar *
g_inet_address_mask_to_string (GInetAddressMask *mask)
{
  gchar *addr_string, *mask_string;

  g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), NULL);

  addr_string = g_inet_address_to_string (mask->priv->addr);

  if (mask->priv->length == (g_inet_address_get_native_size (mask->priv->addr) * 8))
    return addr_string;

  mask_string = g_strdup_printf ("%s/%u", addr_string, mask->priv->length);
  g_free (addr_string);

  return mask_string;
}

/**
 * g_inet_address_mask_get_family:
 * @mask: a #GInetAddressMask
 *
 * Gets the #GSocketFamily of @mask's address
 *
 * Return value: the #GSocketFamily of @mask's address
 *
 * Since: 2.32
 */
GSocketFamily
g_inet_address_mask_get_family (GInetAddressMask *mask)
{
  g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), G_SOCKET_FAMILY_INVALID);

  return g_inet_address_get_family (mask->priv->addr);
}

/**
 * g_inet_address_mask_get_address:
 * @mask: a #GInetAddressMask
 *
 * Gets @mask's base address
 *
 * Return value: (transfer none): @mask's base address
 *
 * Since: 2.32
 */
GInetAddress *
g_inet_address_mask_get_address (GInetAddressMask *mask)
{
  g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), NULL);

  return mask->priv->addr;
}

/**
 * g_inet_address_mask_get_length:
 * @mask: a #GInetAddressMask
 *
 * Gets @mask's length
 *
 * Return value: @mask's length
 *
 * Since: 2.32
 */
guint
g_inet_address_mask_get_length (GInetAddressMask *mask)
{
  g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), 0);

  return mask->priv->length;
}

/**
 * g_inet_address_mask_matches:
 * @mask: a #GInetAddressMask
 * @address: a #GInetAddress
 *
 * Tests if @address falls within the range described by @mask.
 *
 * Return value: whether @address falls within the range described by
 * @mask.
 *
 * Since: 2.32
 */
gboolean
g_inet_address_mask_matches (GInetAddressMask *mask,
			     GInetAddress     *address)
{
  const guint8 *maskbytes, *addrbytes;
  int nbytes, nbits;

  g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), FALSE);
  g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);

  if (g_inet_address_get_family (mask->priv->addr) !=
      g_inet_address_get_family (address))
    return FALSE;

  if (mask->priv->length == 0)
    return TRUE;

  maskbytes = g_inet_address_to_bytes (mask->priv->addr);
  addrbytes = g_inet_address_to_bytes (address);

  nbytes = mask->priv->length / 8;
  if (nbytes != 0 && memcmp (maskbytes, addrbytes, nbytes) != 0)
    return FALSE;

  nbits = mask->priv->length % 8;
  if (nbits == 0)
    return TRUE;

  return maskbytes[nbytes] == (addrbytes[nbytes] & (0xFF << (8 - nbits)));
}


/**
 * g_inet_address_mask_equal:
 * @mask: a #GInetAddressMask
 * @mask2: another #GInetAddressMask
 *
 * Tests if @mask and @mask2 are the same mask.
 *
 * Return value: whether @mask and @mask2 are the same mask
 *
 * Since: 2.32
 */
gboolean
g_inet_address_mask_equal (GInetAddressMask  *mask,
			   GInetAddressMask  *mask2)
{
  return ((mask->priv->length == mask2->priv->length) &&
	  g_inet_address_equal (mask->priv->addr, mask2->priv->addr));
}
