/* 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 "glib/gstdio.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;
  struct sockaddr_nl snl;

  /* We create the socket the old-school way because sockaddr_netlink
   * can't be represented as a GSocketAddress
   */
  sockfd = g_socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, NULL);
  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));
      (void) g_close (sockfd, NULL);
      return FALSE;
    }

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

  if (!g_socket_set_option (nl->priv->sock, SOL_SOCKET, SO_PASSCRED,
			    TRUE, NULL))
    {
      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;
    }

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