X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgnetworkmonitornetlink.c;h=21a7ad543d49e331a8ac534cc2e9d79809e3ab50;hb=356a3987cee7ceddcb3fe623edf0bd2881895add;hp=3f67654ffdfefcd2bc31a2125fe9893221ac590b;hpb=211ed1775dfc514077984d0fea5d2529dcc5036e;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gnetworkmonitornetlink.c b/gio/gnetworkmonitornetlink.c index 3f67654..21a7ad5 100644 --- a/gio/gnetworkmonitornetlink.c +++ b/gio/gnetworkmonitornetlink.c @@ -13,14 +13,13 @@ * 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. + * Public License along with this library; if not, see . */ #include "config.h" #include +#include #include #include "gnetworkmonitornetlink.h" @@ -29,6 +28,7 @@ #include "ginitable.h" #include "giomodule-priv.h" #include "glibintl.h" +#include "glib/gstdio.h" #include "gnetworkingprivate.h" #include "gnetworkmonitor.h" #include "gsocket.h" @@ -42,18 +42,6 @@ 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; @@ -68,12 +56,23 @@ static gboolean read_netlink_messages (GSocket *socket, static gboolean request_dump (GNetworkMonitorNetlink *nl, GError **error); +#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_ADD_PRIVATE (GNetworkMonitorNetlink) + 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)) + static void g_network_monitor_netlink_init (GNetworkMonitorNetlink *nl) { - nl->priv = G_TYPE_INSTANCE_GET_PRIVATE (nl, - G_TYPE_NETWORK_MONITOR_NETLINK, - GNetworkMonitorNetlinkPrivate); + nl->priv = g_network_monitor_netlink_get_instance_private (nl); } @@ -89,7 +88,7 @@ g_network_monitor_netlink_initable_init (GInitable *initable, /* 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); + sockfd = g_socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, NULL); if (sockfd == -1) { int errsv = errno; @@ -108,7 +107,7 @@ g_network_monitor_netlink_initable_init (GInitable *initable, g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Could not create network monitor: %s"), g_strerror (errno)); - close (sockfd); + (void) g_close (sockfd, NULL); return FALSE; } @@ -116,7 +115,7 @@ g_network_monitor_netlink_initable_init (GInitable *initable, if (error) { g_prefix_error (error, "%s", _("Could not create network monitor: ")); - close (sockfd); + (void) g_close (sockfd, NULL); return FALSE; } @@ -218,8 +217,7 @@ static void add_network (GNetworkMonitorNetlink *nl, GSocketFamily family, gint dest_len, - guint8 *dest, - guint8 *gateway) + guint8 *dest) { GInetAddress *dest_addr; GInetAddressMask *network; @@ -245,8 +243,7 @@ static void remove_network (GNetworkMonitorNetlink *nl, GSocketFamily family, gint dest_len, - guint8 *dest, - guint8 *gateway) + guint8 *dest) { GInetAddress *dest_addr; GInetAddressMask *network; @@ -305,7 +302,7 @@ read_netlink_messages (GSocket *socket, struct rtmsg *rtmsg; struct rtattr *attr; gsize attrlen; - guint8 *dest, *gateway; + guint8 *dest, *gateway, *oif; gboolean retval = TRUE; iv.buffer = NULL; @@ -367,22 +364,37 @@ read_netlink_messages (GSocket *socket, attrlen = NLMSG_PAYLOAD (msg, sizeof (struct rtmsg)); attr = RTM_RTA (rtmsg); - dest = gateway = NULL; + dest = gateway = oif = 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); + else if (attr->rta_type == RTA_OIF) + oif = RTA_DATA (attr); attr = RTA_NEXT (attr, attrlen); } - if (dest || gateway) + if (dest || gateway || oif) { + /* Unless we're processing the results of a dump, ignore + * IPv6 link-local multicast routes, which are added and + * removed all the time for some reason. + */ +#define UNALIGNED_IN6_IS_ADDR_MC_LINKLOCAL(a) \ + ((a[0] == 0xff) && ((a[1] & 0xf) == 0x2)) + + if (!nl->priv->dump_networks && + rtmsg->rtm_family == AF_INET6 && + rtmsg->rtm_dst_len != 0 && + UNALIGNED_IN6_IS_ADDR_MC_LINKLOCAL (dest)) + continue; + if (msg->nlmsg_type == RTM_NEWROUTE) - add_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway); + add_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest); else - remove_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway); + remove_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest); queue_request_dump (nl); } break; @@ -450,8 +462,6 @@ 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; }