From Pontus Fuchs:
authorGuy Harris <guy@alum.mit.edu>
Thu, 28 Jun 2012 16:21:51 +0000 (16:21 -0000)
committerGuy Harris <guy@alum.mit.edu>
Thu, 28 Jun 2012 16:21:51 +0000 (16:21 -0000)
Add an interface monitor that, on Linux distributions with libnl,
watches for interfaces to appear or disappear and, on such an event,
causes windows showing interface lists to update.

svn path=/trunk/; revision=43521

CMakeLists.txt
Makefile.common
configure.in
iface_monitor.c [new file with mode: 0644]
iface_monitor.h [new file with mode: 0644]
ui/gtk/CMakeLists.txt
ui/gtk/Makefile.common
ui/gtk/gtk_iface_monitor.c [new file with mode: 0644]
ui/gtk/gtk_iface_monitor.h [new file with mode: 0644]
ui/gtk/main.c

index a985234d07f02f92961711693c530f96c396a40a..b90758957ee8f28ffb68e91a3880663a24d4eb58 100644 (file)
@@ -693,6 +693,7 @@ if( (BUILD_wireshark AND GTK_FOUND) OR (BUILD_qtshark AND QT_FOUND) )
                fileset.c
                filters.c
                g711.c
+               iface_monitor.c
                merge.c
                proto_hier_stats.c
                recent.c
@@ -718,6 +719,7 @@ if(BUILD_wireshark AND GTK_FOUND)
                ${LIBEPAN_LIBS}
                ${APPLE_CORE_SERVICES_LIBRARY}
                ${APPLE_COCOA_LIBRARY}
+               ${LIBNL_LIBRARIES}
        )
        # qtshark and wireshark share wireshark_FILES
 
index d0c63f820b6419df87aa148b4ab22f08c08b0dda..2437672f9d3a70571e16f084551cd2bf715fc9c8 100644 (file)
@@ -111,6 +111,7 @@ wireshark_SOURCES = \
        fileset.c       \
        filters.c       \
        g711.c \
+       iface_monitor.c \
        merge.c \
        proto_hier_stats.c      \
        recent.c        \
@@ -130,6 +131,7 @@ wireshark_INCLUDES =        \
        filters.h       \
        g711.h  \
        globals.h       \
+       iface_monitor.h \
        log.h   \
        merge.h \
        proto_hier_stats.h      \
index ad6c733e71346cfa9a033709fbeebe0bff4f6db5..b6f9eeadb01cd24644784514733d389f32e20f3f 100644 (file)
@@ -228,7 +228,7 @@ AC_ARG_WITH([qt],
   with_qt="$withval", with_qt="no")
 
 libnl_message="no"
-PKG_CHECK_MODULES(LIBNL3, libnl-genl-3.0 >= 3.0, [have_libnl3=yes], [have_libnl3=no])
+PKG_CHECK_MODULES(LIBNL3, [libnl-route-3.0 >= 3.0 libnl-genl-3.0] >= 3.0, [have_libnl3=yes], [have_libnl3=no])
 PKG_CHECK_MODULES(LIBNL2, libnl-2.0 >= 2.0, [have_libnl2=yes], [have_libnl2=no])
 PKG_CHECK_MODULES(LIBNL1, libnl-1 >= 1.0, [have_libnl1=yes], [have_libnl1=no])
 if (test "${have_libnl3}" = "yes"); then
diff --git a/iface_monitor.c b/iface_monitor.c
new file mode 100644 (file)
index 0000000..ec65bd4
--- /dev/null
@@ -0,0 +1,177 @@
+/* iface_monitor.c
+ * interface monitor by Pontus Fuchs <pontus.fuchs@gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include "config.h"
+#include "iface_monitor.h"
+
+#ifdef HAVE_LIBNL
+
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+
+#include <net/if.h>
+
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+#include <netlink/route/link.h>
+
+/* libnl 1.x compatibility code */
+#ifdef HAVE_LIBNL1
+#define nl_sock nl_handle
+#define nl_socket_disable_seq_check nl_disable_sequence_check
+
+static inline struct nl_handle *nl_socket_alloc(void)
+{
+    return nl_handle_alloc();
+}
+
+static inline void nl_socket_free(struct nl_sock *h)
+{
+    nl_handle_destroy(h);
+}
+#endif /* HAVE_LIBNL1 */
+
+static struct nl_sock *iface_mon_sock;
+
+static void
+iface_mon_handler2(struct nl_object *obj, void *arg)
+{
+    struct rtnl_link *filter;
+    struct rtnl_link *link_obj;
+    int flags, up;
+    char *ifname;
+    iface_mon_cb cb = arg;
+
+    filter = rtnl_link_alloc();
+    if (!filter) {
+        fprintf(stderr, "error allocating filter\n");
+        return;
+    }
+
+    if (nl_object_match_filter (obj, OBJ_CAST (filter)) == 0) {
+        rtnl_link_put(filter);
+        return;
+    }
+
+    link_obj = (struct rtnl_link *) obj;
+    flags = rtnl_link_get_flags (link_obj);
+    ifname = rtnl_link_get_name(link_obj);
+
+    up = (flags & IFF_UP) ? 1 : 0;
+
+    cb(ifname, up);
+
+    rtnl_link_put(filter);
+
+    return;
+}
+
+static int
+iface_mon_handler(struct nl_msg *msg, void *arg)
+{
+    nl_msg_parse (msg, &iface_mon_handler2, arg);
+    return 0;
+}
+
+static int
+iface_mon_nl_init(void *arg)
+{
+    int err;
+
+    iface_mon_sock = nl_socket_alloc();
+    if (!iface_mon_sock) {
+        fprintf(stderr, "Failed to allocate netlink socket.\n");
+        return -ENOMEM;
+    }
+
+    nl_socket_disable_seq_check(iface_mon_sock);
+
+    nl_socket_modify_cb(iface_mon_sock, NL_CB_VALID, NL_CB_CUSTOM, iface_mon_handler, arg);
+
+    if (nl_connect(iface_mon_sock, NETLINK_ROUTE)) {
+        fprintf(stderr, "Failed to connect to generic netlink.\n");
+        err = -ENOLINK;
+        goto out_handle_destroy;
+    }
+
+    nl_socket_add_membership(iface_mon_sock, RTNLGRP_LINK);
+
+    return 0;
+
+out_handle_destroy:
+    nl_socket_free(iface_mon_sock);
+    return err;
+}
+
+void
+iface_mon_event(void)
+{
+    nl_recvmsgs_default(iface_mon_sock);
+}
+
+int
+iface_mon_get_sock(void)
+{
+    return nl_socket_get_fd(iface_mon_sock);
+}
+
+int
+iface_mon_start(iface_mon_cb cb)
+{
+    return iface_mon_nl_init(cb);
+}
+
+void
+iface_mon_stop(void)
+{
+    if(iface_mon_sock)
+        nl_socket_free(iface_mon_sock);
+    iface_mon_sock = NULL;
+}
+
+#else /* HAVE_LIBNL */
+
+int
+iface_mon_start(iface_mon_cb cb _U_)
+{
+    return -1;
+}
+
+void
+iface_mon_stop(void)
+{
+}
+
+int
+iface_mon_get_sock(void)
+{
+    return -1;
+}
+
+void
+iface_mon_event(void)
+{
+}
+
+#endif /* HAVE_LIBNL */
diff --git a/iface_monitor.h b/iface_monitor.h
new file mode 100644 (file)
index 0000000..a33df9b
--- /dev/null
@@ -0,0 +1,40 @@
+/* iface_monitor.h
+ * interface monitor by Pontus Fuchs <pontus.fuchs@gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#ifndef IFACE_MONITOR_H
+#define IFACE_MONITOR_H
+
+typedef void (*iface_mon_cb)(const char *iface, int up);
+int
+iface_mon_start(iface_mon_cb cb);
+
+void
+iface_mon_stop(void);
+
+int
+iface_mon_get_sock(void);
+
+void
+iface_mon_event(void);
+
+#endif
index ed8edc7b7bed6ee43c20ba3fe6ca155507ade9bf..55ba918d0b388327ceed18a8832a32adae3bc84a 100644 (file)
@@ -65,6 +65,7 @@ set(WIRESHARK_GTK_SRC
        font_utils.c
        goto_dlg.c
        graph_analysis.c
+       gtk_iface_monitor.c
        gui_stat_util.c
        gui_utils.c
        help_dlg.c
index 3e54f3caefe7b1388633e8e4984eb18945f6068b..6cdee8cd63a3bb05f1dea09f631570b4cd782b65 100644 (file)
@@ -90,6 +90,7 @@ WIRESHARK_GTK_SRC = \
        font_utils.c    \
        goto_dlg.c      \
        graph_analysis.c \
+       gtk_iface_monitor.c     \
        gui_stat_util.c \
        gui_utils.c     \
        help_dlg.c      \
@@ -280,6 +281,7 @@ noinst_HEADERS = \
        goto_dlg.h      \
        graph_analysis.h \
        gsm_map_stat.h  \
+       gtk_iface_monitor.h     \
        gtkglobals.h    \
        gui_stat_menu.h \
        gui_stat_util.h \
diff --git a/ui/gtk/gtk_iface_monitor.c b/ui/gtk/gtk_iface_monitor.c
new file mode 100644 (file)
index 0000000..553c707
--- /dev/null
@@ -0,0 +1,93 @@
+/* gtk_iface_monitor.c
+ * interface monitor by Pontus Fuchs <pontus.fuchs@gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "../../iface_monitor.h"
+
+#include <gtk/gtk.h>
+
+#include "gtkglobals.h"
+
+#include "main.h"
+#include "main_toolbar.h"
+
+#include "ui/gtk/capture_globals.h"
+#include "ui/gtk/main_welcome.h"
+#include "ui/gtk/capture_if_dlg.h"
+#include "ui/gtk/capture_dlg.h"
+
+GIOChannel *iface_mon_channel;
+
+static void
+gtk_iface_mon_event_cb(const char *iface, int up)
+{
+    int present = 0;
+    guint ifs;
+    interface_t device;
+
+    for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) {
+      device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs);
+      if (!strcmp(device.name, iface))
+          present = 1;
+    }
+
+    if (present == up)
+        return;
+
+    refresh_local_interface_lists();
+}
+
+static gboolean
+gtk_iface_mon_event(GIOChannel *source _U_, GIOCondition condition _U_, gpointer data _U_)
+{
+    iface_mon_event();
+    return TRUE;
+}
+
+int
+gtk_iface_mon_start(void)
+{
+    int sock, err;
+    err = iface_mon_start(&gtk_iface_mon_event_cb);
+    if (err)
+        return err;
+    sock = iface_mon_get_sock();
+
+    iface_mon_channel = g_io_channel_unix_new(sock);
+    g_io_channel_set_encoding(iface_mon_channel, NULL, NULL);
+    g_io_add_watch(iface_mon_channel,
+                             G_IO_IN|G_IO_ERR|G_IO_HUP,
+                             &gtk_iface_mon_event,
+                             NULL);
+    return 0;
+}
+
+int
+gtk_iface_mon_stop(void)
+{
+    iface_mon_stop();
+    return 0;
+}
+
diff --git a/ui/gtk/gtk_iface_monitor.h b/ui/gtk/gtk_iface_monitor.h
new file mode 100644 (file)
index 0000000..c5ef1f9
--- /dev/null
@@ -0,0 +1,34 @@
+/* gtk_iface_monitor.h
+ * interface monitor by Pontus Fuchs <pontus.fuchs@gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef GTK_IFACE_MONITOR_H
+#define GTK_IFACE_MONITOR_H
+
+int
+gtk_iface_mon_start(void);
+
+int
+gtk_iface_mon_stop(void);
+
+#endif
index 72df70f70c2e3136cdbf5a0f082d646667952428..83863fc275d8163685536a340a30b9b6ab22ec81 100644 (file)
 #include "../log.h"
 #include "../u3.h"
 
+#include "gtk_iface_monitor.h"
+
 #include "ui/alert_box.h"
 #include "ui/main_statusbar.h"
 #include "ui/recent.h"
@@ -3663,10 +3665,14 @@ main(int argc, char *argv[])
 
   g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
 
+  gtk_iface_mon_start();
+
   /* we'll enter the GTK loop now and hand the control over to GTK ... */
   gtk_main();
   /* ... back from GTK, we're going down now! */
 
+  gtk_iface_mon_stop();
+
   /* deregister our pid */
   u3_deregister_pid();