Blame gio/gnetworkmonitornetlink.c

Packit Service d3d246
/* GIO - GLib Input, Output and Streaming Library
Packit Service d3d246
 *
Packit Service d3d246
 * Copyright 2011 Red Hat, Inc.
Packit Service d3d246
 *
Packit Service d3d246
 * This library is free software; you can redistribute it and/or
Packit Service d3d246
 * modify it under the terms of the GNU Lesser General Public
Packit Service d3d246
 * License as published by the Free Software Foundation; either
Packit Service d3d246
 * version 2.1 of the License, or (at your option) any later version.
Packit Service d3d246
 *
Packit Service d3d246
 * This library is distributed in the hope that it will be useful,
Packit Service d3d246
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d3d246
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service d3d246
 * Lesser General Public License for more details.
Packit Service d3d246
 *
Packit Service d3d246
 * You should have received a copy of the GNU Lesser General
Packit Service d3d246
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
#include "config.h"
Packit Service d3d246
Packit Service d3d246
#include <errno.h>
Packit Service d3d246
#include <string.h>
Packit Service d3d246
#include <unistd.h>
Packit Service d3d246
Packit Service d3d246
#include "gnetworkmonitornetlink.h"
Packit Service d3d246
#include "gcredentials.h"
Packit Service d3d246
#include "ginetaddressmask.h"
Packit Service d3d246
#include "ginitable.h"
Packit Service d3d246
#include "giomodule-priv.h"
Packit Service d3d246
#include "glibintl.h"
Packit Service d3d246
#include "glib/gstdio.h"
Packit Service d3d246
#include "gnetworkingprivate.h"
Packit Service d3d246
#include "gnetworkmonitor.h"
Packit Service d3d246
#include "gsocket.h"
Packit Service d3d246
#include "gunixcredentialsmessage.h"
Packit Service d3d246
Packit Service d3d246
/* must come at the end to pick system includes from
Packit Service d3d246
 * gnetworkingprivate.h */
Packit Service d3d246
#include <linux/netlink.h>
Packit Service d3d246
#include <linux/rtnetlink.h>
Packit Service d3d246
Packit Service d3d246
static GInitableIface *initable_parent_iface;
Packit Service d3d246
static void g_network_monitor_netlink_iface_init (GNetworkMonitorInterface *iface);
Packit Service d3d246
static void g_network_monitor_netlink_initable_iface_init (GInitableIface *iface);
Packit Service d3d246
Packit Service d3d246
struct _GNetworkMonitorNetlinkPrivate
Packit Service d3d246
{
Packit Service d3d246
  GSocket *sock;
Packit Service d3d246
  GSource *source, *dump_source;
Packit Service d3d246
  GMainContext *context;
Packit Service d3d246
Packit Service d3d246
  GPtrArray *dump_networks;
Packit Service d3d246
};
Packit Service d3d246
Packit Service d3d246
static gboolean read_netlink_messages (GSocket             *socket,
Packit Service d3d246
                                       GIOCondition         condition,
Packit Service d3d246
                                       gpointer             user_data);
Packit Service d3d246
static gboolean request_dump (GNetworkMonitorNetlink  *nl,
Packit Service d3d246
                              GError                 **error);
Packit Service d3d246
Packit Service d3d246
#define g_network_monitor_netlink_get_type _g_network_monitor_netlink_get_type
Packit Service d3d246
G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorNetlink, g_network_monitor_netlink, G_TYPE_NETWORK_MONITOR_BASE,
Packit Service d3d246
                         G_ADD_PRIVATE (GNetworkMonitorNetlink)
Packit Service d3d246
                         G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR,
Packit Service d3d246
                                                g_network_monitor_netlink_iface_init)
Packit Service d3d246
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
Packit Service d3d246
                                                g_network_monitor_netlink_initable_iface_init)
Packit Service d3d246
                         _g_io_modules_ensure_extension_points_registered ();
Packit Service d3d246
                         g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
Packit Service d3d246
                                                         g_define_type_id,
Packit Service d3d246
                                                         "netlink",
Packit Service d3d246
                                                         20))
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_network_monitor_netlink_init (GNetworkMonitorNetlink *nl)
Packit Service d3d246
{
Packit Service d3d246
  nl->priv = g_network_monitor_netlink_get_instance_private (nl);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gboolean
Packit Service d3d246
g_network_monitor_netlink_initable_init (GInitable     *initable,
Packit Service d3d246
                                         GCancellable  *cancellable,
Packit Service d3d246
                                         GError       **error)
Packit Service d3d246
{
Packit Service d3d246
  GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (initable);
Packit Service d3d246
  gint sockfd;
Packit Service d3d246
  struct sockaddr_nl snl;
Packit Service d3d246
Packit Service d3d246
  /* We create the socket the old-school way because sockaddr_netlink
Packit Service d3d246
   * can't be represented as a GSocketAddress
Packit Service d3d246
   */
Packit Service d3d246
  sockfd = g_socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, NULL);
Packit Service d3d246
  if (sockfd == -1)
Packit Service d3d246
    {
Packit Service d3d246
      int errsv = errno;
Packit Service d3d246
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
Packit Service d3d246
                   _("Could not create network monitor: %s"),
Packit Service d3d246
                   g_strerror (errsv));
Packit Service d3d246
      return FALSE;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  snl.nl_family = AF_NETLINK;
Packit Service d3d246
  snl.nl_pid = snl.nl_pad = 0;
Packit Service d3d246
  snl.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE;
Packit Service d3d246
  if (bind (sockfd, (struct sockaddr *)&snl, sizeof (snl)) != 0)
Packit Service d3d246
    {
Packit Service d3d246
      int errsv = errno;
Packit Service d3d246
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
Packit Service d3d246
                   _("Could not create network monitor: %s"),
Packit Service d3d246
                   g_strerror (errsv));
Packit Service d3d246
      (void) g_close (sockfd, NULL);
Packit Service d3d246
      return FALSE;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  nl->priv->sock = g_socket_new_from_fd (sockfd, error);
Packit Service d3d246
  if (!nl->priv->sock)
Packit Service d3d246
    {
Packit Service d3d246
      g_prefix_error (error, "%s", _("Could not create network monitor: "));
Packit Service d3d246
      (void) g_close (sockfd, NULL);
Packit Service d3d246
      return FALSE;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  if (!g_socket_set_option (nl->priv->sock, SOL_SOCKET, SO_PASSCRED,
Packit Service d3d246
			    TRUE, NULL))
Packit Service d3d246
    {
Packit Service d3d246
      int errsv = errno;
Packit Service d3d246
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
Packit Service d3d246
                   _("Could not create network monitor: %s"),
Packit Service d3d246
                   g_strerror (errsv));
Packit Service d3d246
      return FALSE;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* Request the current state */
Packit Service d3d246
  if (!request_dump (nl, error))
Packit Service d3d246
    return FALSE;
Packit Service d3d246
Packit Service d3d246
  /* And read responses; since we haven't yet marked the socket
Packit Service d3d246
   * non-blocking, each call will block until a message is received.
Packit Service d3d246
   */
Packit Service d3d246
  while (nl->priv->dump_networks)
Packit Service d3d246
    {
Packit Service d3d246
      if (!read_netlink_messages (NULL, G_IO_IN, nl))
Packit Service d3d246
        break;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  g_socket_set_blocking (nl->priv->sock, FALSE);
Packit Service d3d246
  nl->priv->context = g_main_context_ref_thread_default ();
Packit Service d3d246
  nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL);
Packit Service d3d246
  g_source_set_callback (nl->priv->source,
Packit Service d3d246
                         (GSourceFunc) read_netlink_messages, nl, NULL);
Packit Service d3d246
  g_source_attach (nl->priv->source, nl->priv->context);
Packit Service d3d246
Packit Service d3d246
  return initable_parent_iface->init (initable, cancellable, error);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gboolean
Packit Service d3d246
request_dump (GNetworkMonitorNetlink  *nl,
Packit Service d3d246
              GError                 **error)
Packit Service d3d246
{
Packit Service d3d246
  struct nlmsghdr *n;
Packit Service d3d246
  struct rtgenmsg *gen;
Packit Service d3d246
  gchar buf[NLMSG_SPACE (sizeof (*gen))];
Packit Service d3d246
Packit Service d3d246
  memset (buf, 0, sizeof (buf));
Packit Service d3d246
  n = (struct nlmsghdr*) buf;
Packit Service d3d246
  n->nlmsg_len = NLMSG_LENGTH (sizeof (*gen));
Packit Service d3d246
  n->nlmsg_type = RTM_GETROUTE;
Packit Service d3d246
  n->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
Packit Service d3d246
  n->nlmsg_pid = 0;
Packit Service d3d246
  gen = NLMSG_DATA (n);
Packit Service d3d246
  gen->rtgen_family = AF_UNSPEC;
Packit Service d3d246
Packit Service d3d246
  if (g_socket_send (nl->priv->sock, buf, sizeof (buf),
Packit Service d3d246
                     NULL, error) < 0)
Packit Service d3d246
    {
Packit Service d3d246
      g_prefix_error (error, "%s", _("Could not get network status: "));
Packit Service d3d246
      return FALSE;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  nl->priv->dump_networks = g_ptr_array_new_with_free_func (g_object_unref);
Packit Service d3d246
  return TRUE;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gboolean
Packit Service d3d246
timeout_request_dump (gpointer user_data)
Packit Service d3d246
{
Packit Service d3d246
  GNetworkMonitorNetlink *nl = user_data;
Packit Service d3d246
Packit Service d3d246
  g_source_destroy (nl->priv->dump_source);
Packit Service d3d246
  g_source_unref (nl->priv->dump_source);
Packit Service d3d246
  nl->priv->dump_source = NULL;
Packit Service d3d246
Packit Service d3d246
  request_dump (nl, NULL);
Packit Service d3d246
Packit Service d3d246
  return FALSE;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
queue_request_dump (GNetworkMonitorNetlink *nl)
Packit Service d3d246
{
Packit Service d3d246
  if (nl->priv->dump_networks)
Packit Service d3d246
    return;
Packit Service d3d246
Packit Service d3d246
  if (nl->priv->dump_source)
Packit Service d3d246
    {
Packit Service d3d246
      g_source_destroy (nl->priv->dump_source);
Packit Service d3d246
      g_source_unref (nl->priv->dump_source);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  nl->priv->dump_source = g_timeout_source_new_seconds (1);
Packit Service d3d246
  g_source_set_callback (nl->priv->dump_source,
Packit Service d3d246
                         (GSourceFunc) timeout_request_dump, nl, NULL);
Packit Service d3d246
  g_source_attach (nl->priv->dump_source, nl->priv->context);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static GInetAddressMask *
Packit Service d3d246
create_inet_address_mask (GSocketFamily  family,
Packit Service d3d246
                          const guint8  *dest,
Packit Service d3d246
                          gsize          dest_len)
Packit Service d3d246
{
Packit Service d3d246
  GInetAddress *dest_addr;
Packit Service d3d246
  GInetAddressMask *network;
Packit Service d3d246
Packit Service d3d246
  if (dest)
Packit Service d3d246
    dest_addr = g_inet_address_new_from_bytes (dest, family);
Packit Service d3d246
  else
Packit Service d3d246
    dest_addr = g_inet_address_new_any (family);
Packit Service d3d246
  network = g_inet_address_mask_new (dest_addr, dest_len, NULL);
Packit Service d3d246
  g_object_unref (dest_addr);
Packit Service d3d246
Packit Service d3d246
  return network;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
add_network (GNetworkMonitorNetlink *nl,
Packit Service d3d246
             GSocketFamily           family,
Packit Service d3d246
             const guint8           *dest,
Packit Service d3d246
             gsize                   dest_len)
Packit Service d3d246
{
Packit Service d3d246
  GInetAddressMask *network = create_inet_address_mask (family, dest, dest_len);
Packit Service d3d246
  g_return_if_fail (network != NULL);
Packit Service d3d246
Packit Service d3d246
  if (nl->priv->dump_networks)
Packit Service d3d246
    g_ptr_array_add (nl->priv->dump_networks, g_object_ref (network));
Packit Service d3d246
  else
Packit Service d3d246
    g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (nl), network);
Packit Service d3d246
Packit Service d3d246
  g_object_unref (network);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
remove_network (GNetworkMonitorNetlink *nl,
Packit Service d3d246
                GSocketFamily           family,
Packit Service d3d246
                const guint8           *dest,
Packit Service d3d246
                gsize                   dest_len)
Packit Service d3d246
{
Packit Service d3d246
  GInetAddressMask *network = create_inet_address_mask (family, dest, dest_len);
Packit Service d3d246
  g_return_if_fail (network != NULL);
Packit Service d3d246
Packit Service d3d246
  if (nl->priv->dump_networks)
Packit Service d3d246
    {
Packit Service d3d246
      GInetAddressMask **dump_networks = (GInetAddressMask **)nl->priv->dump_networks->pdata;
Packit Service d3d246
      int i;
Packit Service d3d246
Packit Service d3d246
      for (i = 0; i < nl->priv->dump_networks->len; i++)
Packit Service d3d246
        {
Packit Service d3d246
          if (g_inet_address_mask_equal (network, dump_networks[i]))
Packit Service d3d246
            g_ptr_array_remove_index_fast (nl->priv->dump_networks, i--);
Packit Service d3d246
        }
Packit Service d3d246
    }
Packit Service d3d246
  else
Packit Service d3d246
    {
Packit Service d3d246
      g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (nl), network);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  g_object_unref (network);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
finish_dump (GNetworkMonitorNetlink *nl)
Packit Service d3d246
{
Packit Service d3d246
  g_network_monitor_base_set_networks (G_NETWORK_MONITOR_BASE (nl),
Packit Service d3d246
                                       (GInetAddressMask **)nl->priv->dump_networks->pdata,
Packit Service d3d246
                                       nl->priv->dump_networks->len);
Packit Service d3d246
  g_ptr_array_free (nl->priv->dump_networks, TRUE);
Packit Service d3d246
  nl->priv->dump_networks = NULL;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gboolean
Packit Service d3d246
read_netlink_messages (GSocket      *socket,
Packit Service d3d246
                       GIOCondition  condition,
Packit Service d3d246
                       gpointer      user_data)
Packit Service d3d246
{
Packit Service d3d246
  GNetworkMonitorNetlink *nl = user_data;
Packit Service d3d246
  GInputVector iv;
Packit Service d3d246
  gssize len;
Packit Service d3d246
  gint flags;
Packit Service d3d246
  GError *error = NULL;
Packit Service d3d246
  GSocketAddress *addr = NULL;
Packit Service d3d246
  struct nlmsghdr *msg;
Packit Service d3d246
  struct rtmsg *rtmsg;
Packit Service d3d246
  struct rtattr *attr;
Packit Service d3d246
  struct sockaddr_nl source_sockaddr;
Packit Service d3d246
  gsize attrlen;
Packit Service d3d246
  guint8 *dest, *gateway, *oif;
Packit Service d3d246
  gboolean retval = TRUE;
Packit Service d3d246
Packit Service d3d246
  iv.buffer = NULL;
Packit Service d3d246
  iv.size = 0;
Packit Service d3d246
Packit Service d3d246
  flags = MSG_PEEK | MSG_TRUNC;
Packit Service d3d246
  len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1,
Packit Service d3d246
                                  NULL, NULL, &flags, NULL, &error);
Packit Service d3d246
  if (len < 0)
Packit Service d3d246
    {
Packit Service d3d246
      g_warning ("Error on netlink socket: %s", error->message);
Packit Service d3d246
      g_clear_error (&error);
Packit Service d3d246
      retval = FALSE;
Packit Service d3d246
      goto done;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  iv.buffer = g_malloc (len);
Packit Service d3d246
  iv.size = len;
Packit Service d3d246
  len = g_socket_receive_message (nl->priv->sock, &addr, &iv, 1,
Packit Service d3d246
                                  NULL, NULL, NULL, NULL, &error);
Packit Service d3d246
  if (len < 0)
Packit Service d3d246
    {
Packit Service d3d246
      g_warning ("Error on netlink socket: %s", error->message);
Packit Service d3d246
      g_clear_error (&error);
Packit Service d3d246
      retval = FALSE;
Packit Service d3d246
      goto done;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  if (!g_socket_address_to_native (addr, &source_sockaddr, sizeof (source_sockaddr), &error))
Packit Service d3d246
    {
Packit Service d3d246
      g_warning ("Error on netlink socket: %s", error->message);
Packit Service d3d246
      g_clear_error (&error);
Packit Service d3d246
      retval = FALSE;
Packit Service d3d246
      goto done;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* If the sender port id is 0 (not fakeable) then the message is from the kernel */
Packit Service d3d246
  if (source_sockaddr.nl_pid != 0)
Packit Service d3d246
    goto done;
Packit Service d3d246
Packit Service d3d246
  msg = (struct nlmsghdr *) iv.buffer;
Packit Service d3d246
  for (; len > 0; msg = NLMSG_NEXT (msg, len))
Packit Service d3d246
    {
Packit Service d3d246
      if (!NLMSG_OK (msg, (size_t) len))
Packit Service d3d246
        {
Packit Service d3d246
          g_warning ("netlink message was truncated; shouldn't happen...");
Packit Service d3d246
          retval = FALSE;
Packit Service d3d246
          goto done;
Packit Service d3d246
        }
Packit Service d3d246
Packit Service d3d246
      switch (msg->nlmsg_type)
Packit Service d3d246
        {
Packit Service d3d246
        case RTM_NEWROUTE:
Packit Service d3d246
        case RTM_DELROUTE:
Packit Service d3d246
          rtmsg = NLMSG_DATA (msg);
Packit Service d3d246
Packit Service d3d246
          if (rtmsg->rtm_family != AF_INET && rtmsg->rtm_family != AF_INET6)
Packit Service d3d246
            continue;
Packit Service d3d246
          if (rtmsg->rtm_type == RTN_UNREACHABLE)
Packit Service d3d246
            continue;
Packit Service d3d246
Packit Service d3d246
          attrlen = NLMSG_PAYLOAD (msg, sizeof (struct rtmsg));
Packit Service d3d246
          attr = RTM_RTA (rtmsg);
Packit Service d3d246
          dest = gateway = oif = NULL;
Packit Service d3d246
          while (RTA_OK (attr, attrlen))
Packit Service d3d246
            {
Packit Service d3d246
              if (attr->rta_type == RTA_DST)
Packit Service d3d246
                dest = RTA_DATA (attr);
Packit Service d3d246
              else if (attr->rta_type == RTA_GATEWAY)
Packit Service d3d246
                gateway = RTA_DATA (attr);
Packit Service d3d246
              else if (attr->rta_type == RTA_OIF)
Packit Service d3d246
                oif = RTA_DATA (attr);
Packit Service d3d246
              attr = RTA_NEXT (attr, attrlen);
Packit Service d3d246
            }
Packit Service d3d246
Packit Service d3d246
          if (dest || gateway || oif)
Packit Service d3d246
            {
Packit Service d3d246
              /* Unless we're processing the results of a dump, ignore
Packit Service d3d246
               * IPv6 link-local multicast routes, which are added and
Packit Service d3d246
               * removed all the time for some reason.
Packit Service d3d246
               */
Packit Service d3d246
#define UNALIGNED_IN6_IS_ADDR_MC_LINKLOCAL(a)           \
Packit Service d3d246
              ((a[0] == 0xff) && ((a[1] & 0xf) == 0x2))
Packit Service d3d246
Packit Service d3d246
              if (!nl->priv->dump_networks &&
Packit Service d3d246
                  rtmsg->rtm_family == AF_INET6 &&
Packit Service d3d246
                  rtmsg->rtm_dst_len != 0 &&
Packit Service d3d246
                  UNALIGNED_IN6_IS_ADDR_MC_LINKLOCAL (dest))
Packit Service d3d246
                continue;
Packit Service d3d246
Packit Service d3d246
              if (msg->nlmsg_type == RTM_NEWROUTE)
Packit Service d3d246
                add_network (nl, rtmsg->rtm_family, dest, rtmsg->rtm_dst_len);
Packit Service d3d246
              else
Packit Service d3d246
                remove_network (nl, rtmsg->rtm_family, dest, rtmsg->rtm_dst_len);
Packit Service d3d246
              queue_request_dump (nl);
Packit Service d3d246
            }
Packit Service d3d246
          break;
Packit Service d3d246
Packit Service d3d246
        case NLMSG_DONE:
Packit Service d3d246
          finish_dump (nl);
Packit Service d3d246
          goto done;
Packit Service d3d246
Packit Service d3d246
        case NLMSG_ERROR:
Packit Service d3d246
          {
Packit Service d3d246
            struct nlmsgerr *e = NLMSG_DATA (msg);
Packit Service d3d246
Packit Service d3d246
            g_warning ("netlink error: %s", g_strerror (-e->error));
Packit Service d3d246
          }
Packit Service d3d246
          retval = FALSE;
Packit Service d3d246
          goto done;
Packit Service d3d246
Packit Service d3d246
        default:
Packit Service d3d246
          g_warning ("unexpected netlink message %d", msg->nlmsg_type);
Packit Service d3d246
          retval = FALSE;
Packit Service d3d246
          goto done;
Packit Service d3d246
        }
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
 done:
Packit Service d3d246
  g_free (iv.buffer);
Packit Service d3d246
  g_clear_object (&addr);
Packit Service d3d246
Packit Service d3d246
  if (!retval && nl->priv->dump_networks)
Packit Service d3d246
    finish_dump (nl);
Packit Service d3d246
  return retval;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_network_monitor_netlink_finalize (GObject *object)
Packit Service d3d246
{
Packit Service d3d246
  GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (object);
Packit Service d3d246
Packit Service d3d246
  if (nl->priv->source)
Packit Service d3d246
    {
Packit Service d3d246
      g_source_destroy (nl->priv->source);
Packit Service d3d246
      g_source_unref (nl->priv->source);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  if (nl->priv->dump_source)
Packit Service d3d246
    {
Packit Service d3d246
      g_source_destroy (nl->priv->dump_source);
Packit Service d3d246
      g_source_unref (nl->priv->dump_source);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  if (nl->priv->sock)
Packit Service d3d246
    {
Packit Service d3d246
      g_socket_close (nl->priv->sock, NULL);
Packit Service d3d246
      g_object_unref (nl->priv->sock);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  g_clear_pointer (&nl->priv->context, g_main_context_unref);
Packit Service d3d246
  g_clear_pointer (&nl->priv->dump_networks, g_ptr_array_unref);
Packit Service d3d246
Packit Service d3d246
  G_OBJECT_CLASS (g_network_monitor_netlink_parent_class)->finalize (object);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_network_monitor_netlink_class_init (GNetworkMonitorNetlinkClass *nl_class)
Packit Service d3d246
{
Packit Service d3d246
  GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);
Packit Service d3d246
Packit Service d3d246
  gobject_class->finalize = g_network_monitor_netlink_finalize;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_network_monitor_netlink_iface_init (GNetworkMonitorInterface *monitor_iface)
Packit Service d3d246
{
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_network_monitor_netlink_initable_iface_init (GInitableIface *iface)
Packit Service d3d246
{
Packit Service d3d246
  initable_parent_iface = g_type_interface_peek_parent (iface);
Packit Service d3d246
Packit Service d3d246
  iface->init = g_network_monitor_netlink_initable_init;
Packit Service d3d246
}