/* 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, FALSE);
  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;
}
