/* 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 <errno.h>
#include <unistd.h>

#include "gnetworkmonitornetlink.h"
#include "gcredentials.h"
#include "ginetaddressmask.h"
#include "ginitable.h"
#include "giomodule-priv.h"
#include "glibintl.h"
#include "gnetworkingprivate.h"
#include "gnetworkmonitor.h"
#include "gsocket.h"
#include "gunixcredentialsmessage.h"

/* must come at the end to pick system includes from
 * gnetworkingprivate.h */
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

static void g_network_monitor_netlink_iface_init (GNetworkMonitorInterface *iface);
static void g_network_monitor_netlink_initable_iface_init (GInitableIface *iface);

#define g_network_monitor_netlink_get_type _g_network_monitor_netlink_get_type
G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorNetlink, g_network_monitor_netlink, G_TYPE_NETWORK_MONITOR_BASE,
                         G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR,
                                                g_network_monitor_netlink_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                g_network_monitor_netlink_initable_iface_init)
                         _g_io_modules_ensure_extension_points_registered ();
                         g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
                                                         g_define_type_id,
                                                         "netlink",
                                                         20))

struct _GNetworkMonitorNetlinkPrivate
{
  GSocket *sock;
  GSource *source, *dump_source;

  GPtrArray *dump_networks;
};

static gboolean read_netlink_messages (GSocket             *socket,
                                       GIOCondition         condition,
                                       gpointer             user_data);
static gboolean request_dump (GNetworkMonitorNetlink  *nl,
                              GError                 **error);

static void
g_network_monitor_netlink_init (GNetworkMonitorNetlink *nl)
{
  nl->priv = G_TYPE_INSTANCE_GET_PRIVATE (nl,
                                          G_TYPE_NETWORK_MONITOR_NETLINK,
                                          GNetworkMonitorNetlinkPrivate);
}


static gboolean
g_network_monitor_netlink_initable_init (GInitable     *initable,
                                         GCancellable  *cancellable,
                                         GError       **error)
{
  GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (initable);
  gint sockfd, val;
  struct sockaddr_nl snl;

  /* We create the socket the old-school way because sockaddr_netlink
   * can't be represented as a GSocketAddress
   */
  sockfd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  if (sockfd == -1)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Could not create network monitor: %s"),
                   g_strerror (errno));
      return FALSE;
    }

  snl.nl_family = AF_NETLINK;
  snl.nl_pid = snl.nl_pad = 0;
  snl.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE;
  if (bind (sockfd, (struct sockaddr *)&snl, sizeof (snl)) != 0)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Could not create network monitor: %s"),
                   g_strerror (errno));
      close (sockfd);
      return FALSE;
    }

  val = 1;
  if (setsockopt (sockfd, SOL_SOCKET, SO_PASSCRED, &val, sizeof (val)) != 0)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Could not create network monitor: %s"),
                   g_strerror (errno));
      close (sockfd);
      return FALSE;
    }

  nl->priv->sock = g_socket_new_from_fd (sockfd, error);
  if (error)
    {
      g_prefix_error (error, "%s", _("Could not create network monitor: "));
      close (sockfd);
      return FALSE;
    }

  /* Request the current state */
  if (!request_dump (nl, error))
    return FALSE;

  /* And read responses; since we haven't yet marked the socket
   * non-blocking, each call will block until a message is received.
   */
  while (nl->priv->dump_networks)
    {
      if (!read_netlink_messages (NULL, G_IO_IN, nl))
        break;
    }

  g_socket_set_blocking (nl->priv->sock, FALSE);
  nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL);
  g_source_set_callback (nl->priv->source,
                         (GSourceFunc) read_netlink_messages, nl, NULL);
  g_source_attach (nl->priv->source,
                   g_main_context_get_thread_default ());

  return TRUE;
}

static gboolean
request_dump (GNetworkMonitorNetlink  *nl,
              GError                 **error)
{
  struct nlmsghdr *n;
  struct rtgenmsg *gen;
  gchar buf[NLMSG_SPACE (sizeof (*gen))];

  memset (buf, 0, sizeof (buf));
  n = (struct nlmsghdr*) buf;
  n->nlmsg_len = NLMSG_LENGTH (sizeof (*gen));
  n->nlmsg_type = RTM_GETROUTE;
  n->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  n->nlmsg_pid = 0;
  gen = NLMSG_DATA (n);
  gen->rtgen_family = AF_UNSPEC;

  if (g_socket_send (nl->priv->sock, buf, sizeof (buf),
                     NULL, error) < 0)
    {
      g_prefix_error (error, "%s", _("Could not get network status: "));
      return FALSE;
    }

  nl->priv->dump_networks = g_ptr_array_new_with_free_func (g_object_unref);
  return TRUE;
}

static gboolean
timeout_request_dump (gpointer user_data)
{
  GNetworkMonitorNetlink *nl = user_data;

  g_source_destroy (nl->priv->dump_source);
  g_source_unref (nl->priv->dump_source);
  nl->priv->dump_source = NULL;

  request_dump (nl, NULL);

  return FALSE;
}

static void
queue_request_dump (GNetworkMonitorNetlink *nl)
{
  if (nl->priv->dump_networks)
    return;

  if (nl->priv->dump_source)
    {
      g_source_destroy (nl->priv->dump_source);
      g_source_unref (nl->priv->dump_source);
    }

  nl->priv->dump_source = g_timeout_source_new (1000);
  g_source_set_callback (nl->priv->dump_source,
                         (GSourceFunc) timeout_request_dump, nl, NULL);
  g_source_attach (nl->priv->dump_source,
                   g_main_context_get_thread_default ());
}

static void
add_network (GNetworkMonitorNetlink *nl,
             GSocketFamily           family,
             gint                    dest_len,
             guint8                 *dest,
             guint8                 *gateway)
{
  GInetAddress *dest_addr;
  GInetAddressMask *network;

  if (dest)
    dest_addr = g_inet_address_new_from_bytes (dest, family);
  else
    dest_addr = g_inet_address_new_any (family);
  network = g_inet_address_mask_new (dest_addr, dest_len, NULL);
  g_object_unref (dest_addr);
  g_return_if_fail (network != NULL);

  if (nl->priv->dump_networks)
    g_ptr_array_add (nl->priv->dump_networks, network);
  else
    {
      g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (nl), network);
      g_object_unref (network);
    }
}

static void
remove_network (GNetworkMonitorNetlink *nl,
                GSocketFamily           family,
                gint                    dest_len,
                guint8                 *dest,
                guint8                 *gateway)
{
  GInetAddress *dest_addr;
  GInetAddressMask *network;

  if (dest)
    dest_addr = g_inet_address_new_from_bytes (dest, family);
  else
    dest_addr = g_inet_address_new_any (family);
  network = g_inet_address_mask_new (dest_addr, dest_len, NULL);
  g_object_unref (dest_addr);
  g_return_if_fail (network != NULL);

  if (nl->priv->dump_networks)
    {
      GInetAddressMask **dump_networks = (GInetAddressMask **)nl->priv->dump_networks->pdata;
      int i;

      for (i = 0; i < nl->priv->dump_networks->len; i++)
        {
          if (g_inet_address_mask_equal (network, dump_networks[i]))
            g_ptr_array_remove_index_fast (nl->priv->dump_networks, i--);
        }
      g_object_unref (network);
    }
  else
    {
      g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (nl), network);
      g_object_unref (network);
    }
}

static void
finish_dump (GNetworkMonitorNetlink *nl)
{
  g_network_monitor_base_set_networks (G_NETWORK_MONITOR_BASE (nl),
                                       (GInetAddressMask **)nl->priv->dump_networks->pdata,
                                       nl->priv->dump_networks->len);
  g_ptr_array_free (nl->priv->dump_networks, TRUE);
  nl->priv->dump_networks = NULL;
}

static gboolean
read_netlink_messages (GSocket      *socket,
                       GIOCondition  condition,
                       gpointer      user_data)
{
  GNetworkMonitorNetlink *nl = user_data;
  GInputVector iv;
  gssize len;
  GSocketControlMessage **cmsgs = NULL;
  gint num_cmsgs = 0, i, flags;
  GError *error = NULL;
  GCredentials *creds;
  uid_t sender;
  struct nlmsghdr *msg;
  struct rtmsg *rtmsg;
  struct rtattr *attr;
  gsize attrlen;
  guint8 *dest, *gateway;
  gboolean retval = TRUE;

  iv.buffer = NULL;
  iv.size = 0;

  flags = MSG_PEEK | MSG_TRUNC;
  len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1,
                                  NULL, NULL, &flags, NULL, &error);
  if (len < 0)
    {
      g_warning ("Error on netlink socket: %s", error->message);
      g_error_free (error);
      if (nl->priv->dump_networks)
        finish_dump (nl);
      return FALSE;
    }

  iv.buffer = g_malloc (len);
  iv.size = len;
  len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1,
                                  &cmsgs, &num_cmsgs, NULL, NULL, &error);
  if (len < 0)
    {
      g_warning ("Error on netlink socket: %s", error->message);
      g_error_free (error);
      if (nl->priv->dump_networks)
        finish_dump (nl);
      return FALSE;
    }

  if (num_cmsgs != 1 || !G_IS_UNIX_CREDENTIALS_MESSAGE (cmsgs[0]))
    goto done;

  creds = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (cmsgs[0]));
  sender = g_credentials_get_unix_user (creds, NULL);
  if (sender != 0)
    goto done;

  msg = (struct nlmsghdr *) iv.buffer;
  for (; len > 0; msg = NLMSG_NEXT (msg, len))
    {
      if (!NLMSG_OK (msg, (size_t) len))
        {
          g_warning ("netlink message was truncated; shouldn't happen...");
          retval = FALSE;
          goto done;
        }

      switch (msg->nlmsg_type)
        {
        case RTM_NEWROUTE:
        case RTM_DELROUTE:
          rtmsg = NLMSG_DATA (msg);

          if (rtmsg->rtm_family != AF_INET && rtmsg->rtm_family != AF_INET6)
            continue;
          if (rtmsg->rtm_type == RTN_UNREACHABLE)
            continue;

          attrlen = NLMSG_PAYLOAD (msg, sizeof (struct rtmsg));
          attr = RTM_RTA (rtmsg);
          dest = gateway = NULL;
          while (RTA_OK (attr, attrlen))
            {
              if (attr->rta_type == RTA_DST)
                dest = RTA_DATA (attr);
              else if (attr->rta_type == RTA_GATEWAY)
                gateway = RTA_DATA (attr);
              attr = RTA_NEXT (attr, attrlen);
            }

          if (dest || gateway)
            {
              if (msg->nlmsg_type == RTM_NEWROUTE)
                add_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway);
              else
                remove_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway);
              queue_request_dump (nl);
            }
          break;

        case NLMSG_DONE:
          finish_dump (nl);
          goto done;

        case NLMSG_ERROR:
          {
            struct nlmsgerr *e = NLMSG_DATA (msg);

            g_warning ("netlink error: %s", g_strerror (-e->error));
          }
          retval = FALSE;
          goto done;

        default:
          g_warning ("unexpected netlink message %d", msg->nlmsg_type);
          retval = FALSE;
          goto done;
        }
    }

 done:
  for (i = 0; i < num_cmsgs; i++)
    g_object_unref (cmsgs[i]);
  g_free (cmsgs);

  g_free (iv.buffer);

  if (!retval && nl->priv->dump_networks)
    finish_dump (nl);
  return retval;
}

static void
g_network_monitor_netlink_finalize (GObject *object)
{
  GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (object);

  if (nl->priv->sock)
    {
      g_socket_close (nl->priv->sock, NULL);
      g_object_unref (nl->priv->sock);
    }

  if (nl->priv->source)
    {
      g_source_destroy (nl->priv->source);
      g_source_unref (nl->priv->source);
    }

  if (nl->priv->dump_source)
    {
      g_source_destroy (nl->priv->dump_source);
      g_source_unref (nl->priv->dump_source);
    }

  G_OBJECT_CLASS (g_network_monitor_netlink_parent_class)->finalize (object);
}

static void
g_network_monitor_netlink_class_init (GNetworkMonitorNetlinkClass *nl_class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);

  g_type_class_add_private (nl_class, sizeof (GNetworkMonitorNetlinkPrivate));

  gobject_class->finalize  = g_network_monitor_netlink_finalize;
}

static void
g_network_monitor_netlink_iface_init (GNetworkMonitorInterface *monitor_iface)
{
}

static void
g_network_monitor_netlink_initable_iface_init (GInitableIface *iface)
{
  iface->init = g_network_monitor_netlink_initable_init;
}
