Move capture_globals.h from ui/gtk/ to ui/. Show interface activity
[metze/wireshark/wip.git] / ui / gtk / capture_if_dlg.c
index 958e8cbae543795897a152f99aa75014135b951b..afbf7879687df653f56125eace91d0f0e2ed9123 100644 (file)
@@ -19,7 +19,7 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #ifdef HAVE_CONFIG_H
 
 #include <string.h>
 
-#ifdef __linux__
-#include <sys/types.h>
-#include <sys/stat.h>
-#endif
-
 #include <epan/prefs.h>
 
 #include "../capture_ifinfo.h"
-#include "../simple_dialog.h"
 #include "../capture.h"
 #include "../capture-pcap-util.h"
 #include "../capture_ui_utils.h"
 #include "wsutil/file_util.h"
 #include <wiretap/wtap.h>
 
+#include "ui/capture_globals.h"
+#include "ui/recent.h"
+#include "ui/simple_dialog.h"
+
 #ifdef _WIN32
 #include "ui/gtk/capture_if_details_dlg_win32.h"
+#include "../../capture-wpcap.h"
 #endif
 
 #include "ui/gtk/stock_icons.h"
 #include "ui/gtk/capture_dlg.h"
 #include "ui/gtk/capture_if_dlg.h"
-#include "ui/gtk/recent.h"
 #include "ui/gtk/gui_utils.h"
 #include "ui/gtk/dlg_utils.h"
 #include "ui/gtk/main.h"
 #include "ui/gtk/help_dlg.h"
 #include "ui/gtk/keys.h"
 #include "ui/gtk/webbrowser.h"
-#include "ui/gtk/capture_globals.h"
 #include "ui/gtk/network_icons.h"
+#include "ui/gtk/pipe_icon.h"
 #include "ui/gtk/main_welcome.h"
-#include "ui/gtk/menus.h"
 
 #include "ui/gtk/old-gtk-compat.h"
 
 #ifdef HAVE_AIRPCAP
-#include "../image/toolbar/capture_airpcap_16.xpm"
+#include "../../image/toolbar/capture_airpcap_16.xpm"
 #endif
 
 #if defined(HAVE_PCAP_REMOTE)
 #include "ui/gtk/remote_icons.h"
 #endif
 
-#ifdef _WIN32
-#include "../image/toolbar/capture_ethernet_16.xpm"
-#include "../image/toolbar/modem_16.xpm"
-#endif
+#include "../../image/toolbar/modem_16.xpm"
 
-#include "../image/toolbar/network_virtual_16.xpm"
+#include "../../image/toolbar/network_virtual_16.xpm"
 
 /* new buttons to be used instead of labels for 'Capture','Prepare',' */
-/*#include "../image/toolbar/capture_capture_16.xpm"*/
-/*#include "../image/toolbar/capture_prepare_16.xpm"*/
-/*#include "../image/toolbar/capture_details_16.xpm"*/
+/*#include "../../image/toolbar/capture_capture_16.xpm"*/
+/*#include "../../image/toolbar/capture_prepare_16.xpm"*/
+/*#include "../../image/toolbar/capture_details_16.xpm"*/
 
 
 #ifdef HAVE_AIRPCAP
  */
 static GtkWidget *cap_if_w;
 
-static GList     *if_data_list = NULL;
-
 static guint     timer_id;
 
-static GtkWidget *stop_bt, *capture_bt, *options_bt;
-
-static GList     *if_list;
+static GtkWidget *close_bt, *stop_bt, *capture_bt, *options_bt;
 
-static guint     currently_selected = 0;
+static GArray    *if_array;
 
 static if_stat_cache_t   *sc;
+static GtkWidget *cap_if_top_vb, *cap_if_sw;
 
 /*
  * Timeout, in milliseconds, for reads from the stream of captured packets.
@@ -128,6 +119,7 @@ static if_stat_cache_t   *sc;
 
 /* the "runtime" data of one interface */
 typedef struct if_dlg_data_s {
+    gchar       *device;
     GtkWidget   *device_lb;
     GtkWidget   *descr_lb;
     GtkWidget   *ip_lb;
@@ -137,149 +129,104 @@ typedef struct if_dlg_data_s {
 #ifdef _WIN32
     GtkWidget   *details_bt;
 #endif
-    guint32     last_packets;
-    gchar       *device;
-    if_info_t   if_info;
-    gboolean    selected;
+    gboolean    hidden;
 } if_dlg_data_t;
 
 static gboolean gbl_capture_in_progress = FALSE;
 
+#if 0
 void
-update_selected_interface(gchar *name, gboolean activate)
+add_interface(void)
 {
-  guint ifs;
-  GList *curr;
-  if_dlg_data_t *temp;
-
-  for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) {
-    curr = g_list_nth(if_data_list, ifs);
-    temp = (if_dlg_data_t *)(curr->data);
-    if (strcmp(name, temp->if_info.name) == 0) {
-      if (activate) {
-        gtk_toggle_button_set_active((GtkToggleButton *)temp->choose_bt, TRUE);
-      } else {
-        gtk_toggle_button_set_active((GtkToggleButton *)temp->choose_bt, FALSE);
-      }
+  if_dlg_data_t data;
+
+  data.device_lb = NULL;
+  data.descr_lb   = NULL;
+  data.ip_lb      = NULL;
+  data.curr_lb    = NULL;
+  data.last_lb    = NULL;
+  data.choose_bt  = NULL;
+#ifdef _WIN32
+  data.details_bt = NULL;
+#endif
+  data.hidden     = FALSE;
+  g_array_append_val(if_array, data);
+  refresh_if_window();
+}
+#endif
+
+void
+update_selected_interface(gchar *name)
+{
+  guint i;
+  interface_t device;
+  if_dlg_data_t data;
+
+  for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+    device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+    data = g_array_index(if_array, if_dlg_data_t, i);
+    if (strcmp(name, device.name) == 0) {
+      gtk_toggle_button_set_active((GtkToggleButton *)data.choose_bt, device.selected);
       break;
     }
   }
 }
 
 static void
-store_selected(GtkWidget *choose_bt, gpointer if_data)
+store_selected(GtkWidget *choose_bt, gpointer name)
 {
-  if_dlg_data_t *if_dlg_data = (if_dlg_data_t *)if_data, *temp;
-  GList *curr;
-  unsigned int ifs, i;
-  gboolean found;
-  cap_settings_t cap_settings;
-  interface_options interface_opts;
-
-  for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) {
-    curr = g_list_nth(if_data_list, ifs);
-    temp = (if_dlg_data_t *)(curr->data);
-    found = FALSE;
-    if (strcmp(if_dlg_data->if_info.name, temp->if_info.name) == 0) {
-      temp->selected ^=1;
-      if_data_list = g_list_remove(if_data_list, curr->data);
-      if_data_list = g_list_insert(if_data_list, temp, ifs);
-
-      for (i = 0; i < global_capture_opts.ifaces->len; i++) {
-        if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, temp->if_info.name) == 0) {
-          found = TRUE;
-          if (!temp->selected) {
-            interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
-            global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
-            if (gtk_widget_is_focus(choose_bt) && get_welcome_window()) {
-              change_interface_selection(interface_opts.name, FALSE);
-            }
-            if (gtk_widget_is_focus(choose_bt) && dlg_window_present()) {
-              enable_selected_interface(interface_opts.name, FALSE);
-            }
-            g_free(interface_opts.name);
-            g_free(interface_opts.descr);
-            g_free(interface_opts.cfilter);
-#ifdef HAVE_PCAP_REMOTE
-            g_free(interface_opts.remote_host);
-            g_free(interface_opts.remote_port);
-            g_free(interface_opts.auth_username);
-            g_free(interface_opts.auth_password);
-#endif
-            break;
-          }
+  interface_t device;
+  guint i;
+
+  for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+    device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+    if (strcmp(name, device.if_info.name) == 0) {
+      if (!device.locked) {
+        device.selected ^= 1;
+        if (device.selected) {
+          global_capture_opts.num_selected++;
+        } else {
+          global_capture_opts.num_selected--;
         }
-      }
-      if (!found && temp->selected) {
-        interface_opts.name = g_strdup(temp->if_info.name);
-        interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
-        interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name);
-        interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
-        interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen;
-        interface_opts.snaplen = global_capture_opts.default_options.snaplen;
-        cap_settings = capture_get_cap_settings (interface_opts.name);;
-        interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode;
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-        interface_opts.buffer_size =  global_capture_opts.default_options.buffer_size;
-#endif
-        interface_opts.monitor_mode = cap_settings.monitor_mode;
-#ifdef HAVE_PCAP_REMOTE
-        interface_opts.src_type = global_capture_opts.default_options.src_type;
-        interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
-        interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
-        interface_opts.auth_type = global_capture_opts.default_options.auth_type;
-        interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
-        interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
-        interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
-        interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
-        interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
-#endif
-#ifdef HAVE_PCAP_SETSAMPLING
-        interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
-        interface_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
-#endif
-        g_array_append_val(global_capture_opts.ifaces, interface_opts);
-        if (gtk_widget_is_focus(choose_bt) && get_welcome_window() != NULL) {
-          change_interface_selection(g_strdup(temp->if_info.name), TRUE);
+        global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+        g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+        if (gtk_widget_is_focus(choose_bt) && get_welcome_window()) {
+          change_interface_selection(device.name, device.selected);
         }
-        if (gtk_widget_is_focus(choose_bt) && dlg_window_present()) {
-          enable_selected_interface(interface_opts.name, TRUE);
+        if (gtk_widget_is_focus(choose_bt) && capture_dlg_window_present()) {
+          enable_selected_interface(device.name, device.selected);
         }
+        device.locked = FALSE;
+        global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+        g_array_insert_val(global_capture_opts.all_ifaces, i, device);
       }
-
-      if (temp->selected)
-        currently_selected += 1;
-      else
-        currently_selected -= 1;
       break;
     }
   }
   if (cap_if_w) {
-    gtk_widget_set_sensitive(capture_bt, !gbl_capture_in_progress && (currently_selected > 0));
+    gtk_widget_set_sensitive(capture_bt, !gbl_capture_in_progress && (global_capture_opts.num_selected > 0));
   }
 }
 
 /* start capture button was pressed */
 static void
-#ifdef HAVE_AIRPCAP
-capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data)
-#else
 capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data _U_)
-#endif
 {
-  if_dlg_data_t *temp;
-  GList *curr;
-  int ifs;
-#ifdef HAVE_AIRPCAP
-  if_dlg_data_t *if_dlg_data = if_data;
+  if_dlg_data_t data;
+  guint ifs;
 
-  airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, if_dlg_data->if_info.name);
-  airpcap_if_selected = airpcap_if_active;
+  for (ifs = 0; ifs < if_array->len; ifs++) {
+    data = g_array_index(if_array, if_dlg_data_t, ifs);
+    if (data.hidden) {
+      continue;
+    }
+    gtk_widget_set_sensitive(data.choose_bt, FALSE);
+    if_array = g_array_remove_index(if_array, ifs);
+    g_array_insert_val(if_array, ifs, data);
+#ifdef HAVE_AIRPCAP
+    airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, gtk_label_get_text(GTK_LABEL(data.device_lb)));
+    airpcap_if_selected = airpcap_if_active;
 #endif
-
-  for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) {
-    temp = (if_dlg_data_t *)(curr->data);
-    gtk_widget_set_sensitive(temp->choose_bt, FALSE);
   }
 
   /* XXX - remove this? */
@@ -314,22 +261,22 @@ capture_prepare_cb(GtkWidget *prepare_bt _U_, gpointer if_data _U_)
 #ifdef _WIN32
 /* capture details button was pressed */
 static void
-capture_details_cb(GtkWidget *details_bt _U_, gpointer if_data)
+capture_details_cb(GtkWidget *details_bt _U_, gpointer name)
 {
-  if_dlg_data_t *if_dlg_data = if_data;
-
-
-  capture_if_details_open(if_dlg_data->device);
+  capture_if_details_open(name);
 }
 #endif
 
 /* update a single interface */
 static void
-update_if(if_dlg_data_t *if_dlg_data, if_stat_cache_t *sc)
+update_if(gchar *name, if_stat_cache_t *sc)
 {
   struct pcap_stat stats;
   gchar *str;
-  guint diff;
+  guint diff, ifs, data_ifs;
+  interface_t  device;
+  if_dlg_data_t data;
+  gboolean  found = FALSE;
 
 
   /*
@@ -340,23 +287,46 @@ update_if(if_dlg_data_t *if_dlg_data, if_stat_cache_t *sc)
    * That's a bug, and should be fixed; "pcap_stats()" is supposed
    * to work the same way on all platforms.
    */
+  device.last_packets = 0;
+  data.curr_lb = NULL;
+  data.last_lb = NULL;
   if (sc) {
-    if (capture_stats(sc, if_dlg_data->device, &stats)) {
-      diff = stats.ps_recv - if_dlg_data->last_packets;
-      if_dlg_data->last_packets = stats.ps_recv;
-
-      str = g_strdup_printf("%u", if_dlg_data->last_packets);
-      gtk_label_set_text(GTK_LABEL(if_dlg_data->curr_lb), str);
-      g_free(str);
-      str = g_strdup_printf("%u", diff);
-      gtk_label_set_text(GTK_LABEL(if_dlg_data->last_lb), str);
-      g_free(str);
-
-      gtk_widget_set_sensitive(if_dlg_data->curr_lb, diff);
-      gtk_widget_set_sensitive(if_dlg_data->last_lb, diff);
-    } else {
-      gtk_label_set_text(GTK_LABEL(if_dlg_data->curr_lb), "error");
-      gtk_label_set_text(GTK_LABEL(if_dlg_data->last_lb), "error");
+    for (ifs = 0, data_ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) {
+      device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs);
+      if (device.type != IF_PIPE) {
+        data = g_array_index(if_array, if_dlg_data_t, data_ifs++);
+        if (!device.hidden && strcmp(name, device.name) == 0) {
+          found = TRUE;
+          break;
+        }
+      }
+    }
+    if (found) {
+      if (capture_stats(sc, name, &stats)) {
+        if ((int)(stats.ps_recv - device.last_packets) < 0) {
+          diff = 0;
+        } else {
+          diff = stats.ps_recv - device.last_packets;
+        }
+        device.last_packets = stats.ps_recv;
+
+        str = g_strdup_printf("%u", device.last_packets);
+        gtk_label_set_text(GTK_LABEL(data.curr_lb), str);
+        g_free(str);
+        str = g_strdup_printf("%u", diff);
+        gtk_label_set_text(GTK_LABEL(data.last_lb), str);
+        g_free(str);
+
+        gtk_widget_set_sensitive(data.curr_lb, diff);
+        gtk_widget_set_sensitive(data.last_lb, diff);
+      } else {
+        gtk_label_set_text(GTK_LABEL(data.curr_lb), "error");
+        gtk_label_set_text(GTK_LABEL(data.last_lb), "error");
+      }
+      global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, ifs);
+      g_array_insert_val(global_capture_opts.all_ifaces, ifs, device);
+      if_array = g_array_remove_index(if_array, ifs);
+      g_array_insert_val(if_array, ifs, data);
     }
   }
 }
@@ -365,19 +335,20 @@ update_if(if_dlg_data_t *if_dlg_data, if_stat_cache_t *sc)
 static gboolean
 update_all(gpointer data)
 {
-    GList *curr;
-    int ifs;
-    if_stat_cache_t *sc = (if_stat_cache_t *)data;
+  interface_t device;
+  guint ifs;
+  if_stat_cache_t *sc = data;
 
-    if (!cap_if_w) {
-        return FALSE;
-    }
+  if (!cap_if_w) {
+    return FALSE;
+  }
 
-    for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) {
-        update_if((if_dlg_data_t *)curr->data, sc);
-    }
+  for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) {
+    device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs);
+    update_if(device.name, sc);
+  }
 
-    return TRUE;
+  return TRUE;
 }
 
 /* a live capture has started or stopped */
@@ -387,7 +358,16 @@ set_capture_if_dialog_for_capture_in_progress(gboolean capture_in_progress)
   gbl_capture_in_progress = capture_in_progress;
   if (cap_if_w) {
     gtk_widget_set_sensitive(stop_bt, capture_in_progress);
-    gtk_widget_set_sensitive(capture_bt, !capture_in_progress && (currently_selected > 0));
+    gtk_widget_set_sensitive(capture_bt, !capture_in_progress && (global_capture_opts.num_selected > 0));
+  }
+}
+
+/* a live capture is being stopped */
+void
+set_capture_if_dialog_for_capture_stopping(void)
+{
+  if (cap_if_w) {
+    gtk_widget_set_sensitive(stop_bt, FALSE);
   }
 }
 
@@ -396,170 +376,57 @@ set_capture_if_dialog_for_capture_in_progress(gboolean capture_in_progress)
 static void
 capture_if_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
 {
-    GList *curr;
-    int ifs;
-
-    g_source_remove(timer_id);
-
-    for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) {
-        g_free(curr->data);
-    }
-
-    if_data_list = NULL;
-
-    free_interface_list(if_list);
-
-    /* Note that we no longer have a "Capture Options" dialog box. */
-    cap_if_w = NULL;
+  g_source_remove(timer_id);
 
+  if (sc) {
     capture_stat_stop(sc);
-
+    sc = NULL;
+  }
+  window_destroy(GTK_WIDGET(cap_if_w));
+  /* Note that we no longer have a "Capture Options" dialog box. */
+  cap_if_w = NULL;
+  cap_if_top_vb = NULL;
+  cap_if_sw = NULL;
 #ifdef HAVE_AIRPCAP
+  if (airpcap_if_active)
     airpcap_set_toolbar_stop_capture(airpcap_if_active);
 #endif
 }
 
 
-/*
- * Sorts the Interface List in alphabetical order
- */
-gint if_list_comparator_alph (const void *first_arg, const void *second_arg){
-  const if_info_t *first = first_arg, *second = second_arg;
-
-  if (first != NULL && first->description != NULL &&
-      second != NULL && second->description != NULL) {
-    return g_ascii_strcasecmp(first->description, second->description);
-  } else {
-    return 0;
-  }
-}
-
-
 /*
  * Used to retrieve the interface icon.
- * This is hideously platform-dependent.
  */
-GtkWidget * capture_get_if_icon(const if_info_t* if_info)
+GtkWidget * capture_get_if_icon(interface_t *device)
 {
-#if defined(__linux__)
-  ws_statb64 statb;
-  char *wireless_path;
-#endif
-
 #ifdef HAVE_PCAP_REMOTE
-  if (if_info->description && strstr(if_info->description, "on remote node") != NULL ) {
+  if (!device->local) {
     return pixbuf_to_widget(remote_sat_pb_data);
   }
 #endif
-#if defined(_WIN32)
-  /*
-   * Much digging failed to reveal any obvious way to get something such
-   * as the SNMP MIB-II ifType value for an interface:
-   *
-   *   http://www.iana.org/assignments/ianaiftype-mib
-   *
-   * by making some NDIS request.
-   */
-  if ( if_info->description && ( strstr(if_info->description,"generic dialup") != NULL ||
-       strstr(if_info->description,"PPP/SLIP") != NULL ) ) {
+  switch (device->type) {
+  case IF_DIALUP:
     return xpm_to_widget(modem_16_xpm);
-  }
-
-  if ( if_info->description && ( strstr(if_info->description,"Wireless") != NULL ||
-       strstr(if_info->description,"802.11") != NULL || strstr(if_info->description,"AirPcap") != NULL ) ) {
-    return pixbuf_to_widget(network_wireless_pb_data);
-  }
-
-  if ( strstr(if_info->name,"airpcap") != NULL ) {
-    return pixbuf_to_widget(network_wireless_pb_data);
-  }
-
-  if ( if_info->description && strstr(if_info->description, "Bluetooth") != NULL ) {
-    return pixbuf_to_widget(network_bluetooth_pb_data);
-  }
-#elif defined(__APPLE__)
-  /*
-   * XXX - yes, fetching all the network addresses for an interface
-   * gets you an AF_LINK address, of type "struct sockaddr_dl", and,
-   * yes, that includes an SNMP MIB-II ifType value.
-   *
-   * However, it's IFT_ETHER, i.e. Ethernet, for AirPort interfaces,
-   * not IFT_IEEE80211 (which isn't defined in OS X in any case).
-   *
-   * Perhaps some other BSD-flavored OSes won't make this mistake;
-   * however, FreeBSD 7.0 and OpenBSD 4.2, at least, appear to have
-   * made the same mistake, at least for my Belkin ZyDAS stick.
-   *
-   * On Mac OS X, one might be able to get the information one wants from
-   * IOKit.
-   */
-  if ( strcmp(if_info->name, "en1") == 0) {
+  case IF_WIRELESS:
     return pixbuf_to_widget(network_wireless_pb_data);
-  }
-
-  /*
-   * XXX - PPP devices have names beginning with "ppp" and an IFT_ of
-   * IFT_PPP, but they could be dial-up, or PPPoE, or mobile phone modem,
-   * or VPN, or... devices.  One might have to dive into the bowels of
-   * IOKit to find out.
-   */
-
-  /*
-   * XXX - there's currently no support for raw Bluetooth capture,
-   * and IP-over-Bluetooth devices just look like fake Ethernet
-   * devices.  There's also Bluetooth modem support, but that'll
-   * probably just give you a device that looks like a PPP device.
-   */
-#elif defined(__linux__)
-  /*
-   * Look for /sys/class/net/{device}/wireless.
-   */
-  wireless_path = g_strdup_printf("/sys/class/net/%s/wireless", if_info->name);
-  if (wireless_path != NULL) {
-    if (ws_stat64(wireless_path, &statb) == 0) {
-      g_free(wireless_path);
-      return pixbuf_to_widget(network_wireless_pb_data);
-    }
-    g_free(wireless_path);
-  }
-
-  /*
-   * Bluetooth devices.
-   *
-   * XXX - this is for raw Bluetooth capture; what about IP-over-Bluetooth
-   * devices?
-   */
-  if ( strstr(if_info->name,"bluetooth") != NULL) {
+#ifdef HAVE_AIRPCAP
+  case IF_AIRPCAP:
+    return xpm_to_widget(capture_airpcap_16_xpm);
+#endif
+  case IF_BLUETOOTH:
     return pixbuf_to_widget(network_bluetooth_pb_data);
-  }
-
-  /*
-   * USB devices.
-   */
-  if ( strstr(if_info->name,"usbmon") != NULL ) {
+  case IF_USB:
     return pixbuf_to_widget(network_usb_pb_data);
-  }
-#endif
-
-  /*
-   * TODO: find a better icon!
-   * Bridge, NAT, or host-only interfaces on VMWare hosts have the name
-   * vmnet[0-9]+ or VMnet[0-9+ on Windows. Guests might use a native
-   * (LANCE or E1000) driver or the vmxnet driver. These devices have an
-   * IFT_ of IFT_ETHER, so we have to check the name.
-   */
-  if ( g_ascii_strncasecmp(if_info->name, "vmnet", 5) == 0) {
-    return xpm_to_widget(network_virtual_16_xpm);
-  }
-
-  if ( g_ascii_strncasecmp(if_info->name, "vmxnet", 6) == 0) {
+  case IF_VIRTUAL:
     return xpm_to_widget(network_virtual_16_xpm);
+  case IF_WIRED:
+    return pixbuf_to_widget(network_wired_pb_data);
+  case IF_PIPE:
+  case IF_STDIN:
+    return pixbuf_to_widget(pipe_pb_data);
+  default:
+    printf("unknown device type\n");
   }
-
-  if ( if_info->description && strstr(if_info->description, "VMware") != NULL ) {
-    return xpm_to_widget(network_virtual_16_xpm);
-  }
-
   return pixbuf_to_widget(network_wired_pb_data);
 }
 
@@ -691,128 +558,121 @@ static void
 capture_if_stop_cb(GtkWidget *w _U_, gpointer d _U_)
 {
   guint ifs;
-  GList *curr;
-  if_dlg_data_t *if_data;
+  if_dlg_data_t data;
 
-  for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) {
-    curr = g_list_nth(if_data_list, ifs);
-    if_data = (if_dlg_data_t *)(curr->data);
-    gtk_widget_set_sensitive(if_data->choose_bt, TRUE);
+  for (ifs = 0; ifs < if_array->len; ifs++) {
+    data = g_array_index(if_array, if_dlg_data_t, ifs);
+    if (data.hidden) {
+      continue;
+    }
+    gtk_widget_set_sensitive(data.choose_bt, TRUE);
+    if_array = g_array_remove_index(if_array, ifs);
+    g_array_insert_val(if_array, ifs, data);
   }
   capture_stop_cb(NULL, NULL);
 }
 
-
-/* start getting capture stats from all interfaces */
-void
-capture_if_cb(GtkWidget *w _U_, gpointer d _U_)
+static void
+make_if_array(void)
 {
-  GtkWidget         *main_vb,
-                    *main_sw,
-                    *bbox,
-                    *close_bt,
-                    *help_bt,
-                    *icon;
-
-#ifdef HAVE_AIRPCAP
-  GtkWidget         *decryption_cb;
+  if_dlg_data_t data;
+  guint         i;
+
+  if_array = g_array_new(FALSE, FALSE, sizeof(if_dlg_data_t));
+
+  for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+     data.device_lb  = NULL;
+     data.descr_lb   = NULL;
+     data.ip_lb      = NULL;
+     data.curr_lb    = NULL;
+     data.last_lb    = NULL;
+     data.choose_bt  = NULL;
+#ifdef _WIN32
+     data.details_bt = NULL;
 #endif
+     data.hidden     = FALSE;
+     g_array_append_val(if_array, data);
+  }
+}
 
-  GtkWidget         *if_tb;
-  GtkWidget         *if_lb;
-  GtkWidget         *eb;
-  int               err;
-  gchar             *err_str;
-  GtkRequisition    requisition;
-  int               row, height;
-  if_dlg_data_t     *if_dlg_data = NULL;
-  int               ifs;
-  GList             *curr;
-  if_info_t         *if_info;
-  GString           *if_tool_str = g_string_new("");
-  const gchar       *addr_str;
-  gchar             *user_descr;
-  int               preselected = 0, i;
-  interface_options interface_opts;
-  gboolean      found = FALSE;
+/*
+ * If this is Windows, is WinPcap loaded?  If not, pop up a dialog noting
+ * that fact and return FALSE, as we can't capture traffic.
+ *
+ * Otherwise (not Windows or WinPcap loaded), are there any interfaces?
+ * If not, pop up a dialog noting that fact and return FALSE, as there
+ * are no interfaces on which to capture traffic.
+ *
+ * Otherwise, return TRUE, as we can capture.
+ */
+static gboolean
+can_capture(void)
+{
+#ifdef _WIN32
+  /* Is WPcap loaded? */
+  if (!has_wpcap) {
+    char *detailed_err;
 
-  if (cap_if_w != NULL) {
-    /* There's already a "Capture Interfaces" dialog box; reactivate it. */
-    reactivate_window(cap_if_w);
-    return;
+    detailed_err = cant_load_winpcap_err("Wireshark");
+    simple_error_message_box("%s", detailed_err);
+    g_free(detailed_err);
+    return FALSE;
   }
+#endif
 
-  preselected = global_capture_opts.ifaces->len;
-  /* LOAD THE INTERFACES */
-  if_list = capture_interface_list(&err, &err_str);
-  if_list = g_list_sort (if_list, if_list_comparator_alph);
-  if (if_list == NULL) {
-    switch (err) {
-
-    case CANT_GET_INTERFACE_LIST:
-    case DONT_HAVE_PCAP:
-      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
-      g_free(err_str);
-      break;
-
-    case NO_INTERFACES_FOUND:
-      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                    "There are no interfaces on which a capture can be done.");
-      break;
-    }
-    return;
+  if (global_capture_opts.all_ifaces->len == 0) {
+    simple_error_message_box("There are no interfaces on which a capture can be done.");
+    return FALSE;
   }
 
-#ifdef HAVE_AIRPCAP
-  /* LOAD AIRPCAP INTERFACES */
-  airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
-  if (airpcap_if_list == NULL)
-    airpcap_if_active = airpcap_if_selected = NULL;
+  return TRUE;
+}
 
-  decryption_cb = g_object_get_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY);
-  update_decryption_mode_list(decryption_cb);
+static void
+capture_if_refresh_if_list(void)
+{
+  GtkWidget         *if_vb, *if_tb, *icon, *if_lb, *eb;
+  GString           *if_tool_str = g_string_new("");
+  GtkRequisition    requisition;
+  int               row = 0, height = 0, curr_height, curr_width;
+  guint             ifs;
+  interface_t       device;
+  const gchar       *addr_str;
+  gchar             *user_descr;
+  if_dlg_data_t     data;
 
-  if (airpcap_if_list == NULL && err == CANT_GET_AIRPCAP_INTERFACE_LIST) {
-#if 0
-    /* XXX - Do we need to show an error here? */
-    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
-#endif
-    g_free(err_str);
+  if (!can_capture()) {
+    /* No interfaces or, on Windows, no WinPcap; we've already popped
+       up a message, so just get rid of the interface dialog. */
+    destroy_if_window();
+    return;
   }
 
-  /* If no airpcap interface is present, gray everything */
-  if (airpcap_if_active == NULL) {
-    if (airpcap_if_list == NULL) {
-      /*No airpcap device found */
-      airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
-    } else {
-      /* default adapter is not airpcap... or is airpcap but is not found*/
-      airpcap_set_toolbar_stop_capture(airpcap_if_active);
-      airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
-    }
+  if (cap_if_sw) {
+    /* First, get rid of the old interface list, and stop updating
+       the statistics on it. */
+    gtk_container_remove(GTK_CONTAINER(cap_if_top_vb), cap_if_sw);
+    capture_stat_stop(sc);
+    g_source_remove(timer_id);
   }
 
-  airpcap_set_toolbar_start_capture(airpcap_if_active);
-#endif
+  /* Now construct the new interface list, and start updating the
+     statistics on it. */
 
-  cap_if_w = dlg_window_new("Wireshark: Capture Interfaces");  /* transient_for top_level */
-  gtk_window_set_destroy_with_parent (GTK_WINDOW(cap_if_w), TRUE);
+  make_if_array();
 
-  main_sw = gtk_scrolled_window_new(NULL, NULL);
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(main_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-  gtk_container_add(GTK_CONTAINER(cap_if_w), main_sw);
+  cap_if_sw = gtk_scrolled_window_new(NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cap_if_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start(GTK_BOX(cap_if_top_vb), cap_if_sw, TRUE, TRUE, 0);
 
-  main_vb = gtk_vbox_new(FALSE, 0);
-  gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
-  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(main_sw), main_vb);
+  if_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+  gtk_container_set_border_width(GTK_CONTAINER(if_vb), 5);
+  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(cap_if_sw), if_vb);
 
   if_tb = gtk_table_new(1,9, FALSE);
   gtk_table_set_row_spacings(GTK_TABLE(if_tb), 3);
   gtk_table_set_col_spacings(GTK_TABLE(if_tb), 3);
-  gtk_box_pack_start(GTK_BOX(main_vb), if_tb, FALSE, FALSE, 0);
-
-  row = 0;
-  height = 0;
+  gtk_box_pack_start(GTK_BOX(if_vb), if_tb, FALSE, FALSE, 0);
 
   /* This is the icon column, used to display which kind of interface we have */
   if_lb = gtk_label_new("");
@@ -842,152 +702,189 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_)
 
   height += 30;
   /* Start gathering statistics (using dumpcap) */
-  sc = capture_stat_start(if_list);
+  sc = capture_stat_start(&global_capture_opts);
 
   /* List the interfaces */
-  currently_selected = 0;
-  for (ifs = 0; (curr = g_list_nth(if_list, ifs)); ifs++) {
+  for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) {
+    device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs);
+    data = g_array_index(if_array, if_dlg_data_t, ifs);
     g_string_assign(if_tool_str, "");
-    if_info = (if_info_t *)curr->data;
-
     /* Continue if capture device is hidden */
-    if (prefs_is_capture_device_hidden(if_info->name)) {
+    if (device.hidden) {
+      data.hidden = TRUE;
+      if_array = g_array_remove_index(if_array, ifs);
+      g_array_insert_val(if_array, ifs, data);
       continue;
     }
-
-    if_dlg_data = g_new0(if_dlg_data_t,1);
-
-    if (preselected > 0) {
-      found = FALSE;
-      for (i = 0; i < (gint)global_capture_opts.ifaces->len; i++) {
-        interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
-        if ((interface_opts.name == NULL) ||
-            (strcmp(interface_opts.name, (char*)if_info->name) != 0)) {
-          continue;
-        } else {
-          found = TRUE;
-          currently_selected++;
-          preselected--;
-          break;
-        }
-      }
-      if_dlg_data->selected = found;
-    } else {
-      if_dlg_data->selected = FALSE;
-    }
-    if_dlg_data->if_info = *if_info;
-
-    if_dlg_data->choose_bt = gtk_check_button_new();
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->choose_bt, 0, 1, row, row+1);
+    data.choose_bt = gtk_check_button_new();
+    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.choose_bt, 0, 1, row, row+1);
     if (gbl_capture_in_progress) {
-      gtk_widget_set_sensitive(if_dlg_data->choose_bt, FALSE);
+      gtk_widget_set_sensitive(data.choose_bt, FALSE);
     } else {
-      gtk_widget_set_sensitive(if_dlg_data->choose_bt, TRUE);
+      gtk_widget_set_sensitive(data.choose_bt, TRUE);
     }
-    gtk_toggle_button_set_active((GtkToggleButton *)if_dlg_data->choose_bt, if_dlg_data->selected);
-    g_signal_connect(if_dlg_data->choose_bt, "toggled", G_CALLBACK(store_selected), if_dlg_data);
-     /* Kind of adaptor (icon) */
-#ifdef HAVE_AIRPCAP
-    if (get_airpcap_if_from_name(airpcap_if_list,if_info->name) != NULL)
-      icon = xpm_to_widget(capture_airpcap_16_xpm);
-    else
-      icon = capture_get_if_icon(if_info);
-#else
-    icon = capture_get_if_icon(if_info);
-#endif
+    gtk_toggle_button_set_active((GtkToggleButton *)data.choose_bt, device.selected);
+    g_signal_connect(data.choose_bt, "toggled", G_CALLBACK(store_selected), device.name);
+    /* Kind of adaptor (icon) */
+    icon = capture_get_if_icon(&(device));
     gtk_table_attach_defaults(GTK_TABLE(if_tb), icon, 1, 2, row, row+1);
 
       /* device name */
-    if_dlg_data->device_lb = gtk_label_new(if_info->name);
-    if_dlg_data->device = if_info->name;
+    data.device_lb = gtk_label_new(device.name);
 #ifndef _WIN32
-    gtk_misc_set_alignment(GTK_MISC(if_dlg_data->device_lb), 0.0f, 0.5f);
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->device_lb, 2, 4, row, row+1);
+    gtk_misc_set_alignment(GTK_MISC(data.device_lb), 0.0f, 0.5f);
+    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.device_lb, 2, 4, row, row+1);
 #endif
     g_string_append(if_tool_str, "Device: ");
-    g_string_append(if_tool_str, if_info->name);
+    g_string_append(if_tool_str, device.name);
     g_string_append(if_tool_str, "\n");
 
     /* description */
-    user_descr = capture_dev_user_descr_find(if_info->name);
+    user_descr = capture_dev_user_descr_find(device.name);
     if (user_descr) {
-      if_dlg_data->descr_lb = gtk_label_new(user_descr);
+      data.descr_lb = gtk_label_new(user_descr);
       g_free (user_descr);
     } else {
-      if (if_info->description)
-        if_dlg_data->descr_lb = gtk_label_new(if_info->description);
+      if (device.if_info.description)
+        data.descr_lb = gtk_label_new(device.if_info.description);
       else
-        if_dlg_data->descr_lb = gtk_label_new("");
+        data.descr_lb = gtk_label_new("");
     }
-    gtk_misc_set_alignment(GTK_MISC(if_dlg_data->descr_lb), 0.0f, 0.5f);
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->descr_lb, 4, 5, row, row+1);
-
-    if (if_info->description) {
+    gtk_misc_set_alignment(GTK_MISC(data.descr_lb), 0.0f, 0.5f);
+    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.descr_lb, 4, 5, row, row+1);
+    if (device.if_info.description) {
       g_string_append(if_tool_str, "Description: ");
-      g_string_append(if_tool_str, if_info->description);
+      g_string_append(if_tool_str, device.if_info.description);
       g_string_append(if_tool_str, "\n");
     }
 
     /* IP address */
     /* Only one IP address will be shown, start with the first */
     g_string_append(if_tool_str, "IP: ");
-    if_dlg_data->ip_lb = gtk_label_new("");
-    addr_str = set_ip_addr_label (if_info->addrs, if_dlg_data->ip_lb, 0);
+    data.ip_lb = gtk_label_new("");
+    addr_str = set_ip_addr_label (device.if_info.addrs, data.ip_lb, 0);
     if (addr_str) {
-      gtk_widget_set_sensitive(if_dlg_data->ip_lb, TRUE);
+      gtk_widget_set_sensitive(data.ip_lb, TRUE);
       g_string_append(if_tool_str, addr_str);
     } else {
-      gtk_widget_set_sensitive(if_dlg_data->ip_lb, FALSE);
+      gtk_widget_set_sensitive(data.ip_lb, FALSE);
       g_string_append(if_tool_str, "none");
     }
     eb = gtk_event_box_new ();
-    gtk_container_add(GTK_CONTAINER(eb), if_dlg_data->ip_lb);
+    gtk_container_add(GTK_CONTAINER(eb), data.ip_lb);
     gtk_table_attach_defaults(GTK_TABLE(if_tb), eb, 5, 6, row, row+1);
-    if (get_ip_addr_count(if_info->addrs) > 1) {
+    if (get_ip_addr_count(device.if_info.addrs) > 1) {
       /* More than one IP address, make it possible to toggle */
-      g_object_set_data(G_OBJECT(eb), CAPTURE_IF_IP_ADDR_LABEL, if_dlg_data->ip_lb);
+      g_object_set_data(G_OBJECT(eb), CAPTURE_IF_IP_ADDR_LABEL, data.ip_lb);
       g_signal_connect(eb, "enter-notify-event", G_CALLBACK(ip_label_enter_cb), NULL);
       g_signal_connect(eb, "leave-notify-event", G_CALLBACK(ip_label_leave_cb), NULL);
-      g_signal_connect(eb, "button-press-event", G_CALLBACK(ip_label_press_cb), if_info->addrs);
+      g_signal_connect(eb, "button-press-event", G_CALLBACK(ip_label_press_cb), device.if_info.addrs);
     }
     g_string_append(if_tool_str, "\n");
 
     /* packets */
-    if_dlg_data->curr_lb = gtk_label_new("-");
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->curr_lb, 6, 7, row, row+1);
+    data.curr_lb = gtk_label_new("-");
+    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.curr_lb, 6, 7, row, row+1);
 
     /* packets/s */
-    if_dlg_data->last_lb = gtk_label_new("-");
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->last_lb, 7, 8, row, row+1);
+    data.last_lb = gtk_label_new("-");
+    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.last_lb, 7, 8, row, row+1);
 
     /* details button */
 #ifdef _WIN32
-    if_dlg_data->details_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_CAPTURE_DETAILS);
-    gtk_widget_set_tooltip_text(if_dlg_data->details_bt, "Open the capture details dialog of this interface.");
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->details_bt, 8, 9, row, row+1);
-    if (capture_if_has_details(if_dlg_data->device)) {
-      g_signal_connect(if_dlg_data->details_bt, "clicked", G_CALLBACK(capture_details_cb), if_dlg_data);
+    data.details_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_CAPTURE_DETAILS);
+    gtk_widget_set_tooltip_text(data.details_bt, "Open the capture details dialog of this interface.");
+    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.details_bt, 8, 9, row, row+1);
+    if (capture_if_has_details(device.name)) {
+      g_signal_connect(data.details_bt, "clicked", G_CALLBACK(capture_details_cb), device.name);
     } else {
-      gtk_widget_set_sensitive(if_dlg_data->details_bt, FALSE);
+      gtk_widget_set_sensitive(data.details_bt, FALSE);
     }
 #endif
-
-    if_data_list = g_list_append(if_data_list, if_dlg_data);
+    if_array = g_array_remove_index(if_array, ifs);
+    g_array_insert_val(if_array, ifs, data);
 
     row++;
-    if (row <= 10) {
-        /* Lets add up 10 rows of interfaces, otherwise the window may become too high */
-      gtk_widget_get_preferred_size(GTK_WIDGET(if_dlg_data->choose_bt), &requisition, NULL);
+    if (row <= 20) {
+        /* Lets add up 20 rows of interfaces, otherwise the window may become too high */
+      gtk_widget_get_preferred_size(GTK_WIDGET(data.choose_bt), &requisition, NULL);
       height += requisition.height;
     }
   }
 
+  gtk_widget_get_preferred_size(GTK_WIDGET(close_bt), &requisition, NULL);
+  /* height + static offset + what the GTK MS Windows Engine needs in addition per interface */
+  height += requisition.height + 40 + ifs;
+
+  if (cap_if_w) {
+    gtk_window_get_size(GTK_WINDOW(cap_if_w), &curr_width, &curr_height);
+    if (curr_height < height)
+       gtk_window_resize(GTK_WINDOW(cap_if_w), curr_width, height);
+  }
+  else
+    gtk_window_set_default_size(GTK_WINDOW(cap_if_w), -1, height);
+
   g_string_free(if_tool_str, TRUE);
+  gtk_widget_show_all(cap_if_w);
+
+  /* update the interface list every 1000ms */
+  timer_id = g_timeout_add(1000, update_all, sc);
+}
+
+/* start getting capture stats from all interfaces */
+void
+capture_if_cb(GtkWidget *w _U_, gpointer d _U_)
+{
+  GtkWidget         *bbox,
+                    *help_bt;
+#ifdef HAVE_AIRPCAP
+  GtkWidget         *decryption_cb;
+#endif
+
+  if (cap_if_w != NULL) {
+    /* There's already a "Capture Interfaces" dialog box; reactivate it. */
+    reactivate_window(cap_if_w);
+    return;
+  }
+
+  if (!can_capture()) {
+    /* No interfaces or, on Windows, no WinPcap; just give up. */
+    return;
+  }
+
+#ifdef HAVE_AIRPCAP
+  /* LOAD AIRPCAP INTERFACES */
+
+  decryption_cb = g_object_get_data(G_OBJECT(wireless_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY);
+  update_decryption_mode_list(decryption_cb);
+
+  /* If no airpcap interface is present, gray everything */
+  if (airpcap_if_active == NULL) {
+    if (airpcap_if_list == NULL) {
+      /*No airpcap device found */
+      airpcap_enable_toolbar_widgets(wireless_tb,FALSE);
+    } else {
+      /* default adapter is not airpcap... or is airpcap but is not found*/
+      if (airpcap_if_active)
+        airpcap_set_toolbar_stop_capture(airpcap_if_active);
+      airpcap_enable_toolbar_widgets(wireless_tb,FALSE);
+    }
+  }
+  if (airpcap_if_active)
+    airpcap_set_toolbar_start_capture(airpcap_if_active);
+#endif
+
+  cap_if_w = dlg_window_new("Wireshark: Capture Interfaces");  /* transient_for top_level */
+  gtk_window_set_destroy_with_parent (GTK_WINDOW(cap_if_w), TRUE);
+
+  cap_if_top_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+  gtk_container_add(GTK_CONTAINER(cap_if_w), cap_if_top_vb);
 
   /* Button row: close, help, stop, start, and options button */
   bbox = dlg_button_row_new(GTK_STOCK_HELP, WIRESHARK_STOCK_CAPTURE_START, WIRESHARK_STOCK_CAPTURE_OPTIONS, WIRESHARK_STOCK_CAPTURE_STOP, GTK_STOCK_CLOSE, NULL);
 
-  gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
+  gtk_container_set_border_width(GTK_CONTAINER(bbox), 0);
+  gtk_box_pack_end(GTK_BOX(cap_if_top_vb), bbox, FALSE, FALSE, 10);
   help_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
   g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)(HELP_CAPTURE_INTERFACES_DIALOG));
 
@@ -997,26 +894,20 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_)
   window_set_cancel_button(cap_if_w, close_bt, window_cancel_button_cb);
   gtk_widget_set_tooltip_text(close_bt, "Close this window.");
   options_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_OPTIONS);
-  g_signal_connect(options_bt, "clicked", G_CALLBACK(capture_prepare_cb), if_dlg_data);
+  g_signal_connect(options_bt, "clicked", G_CALLBACK(capture_prepare_cb), NULL);
   capture_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_START);
-  g_signal_connect(capture_bt, "clicked", G_CALLBACK(capture_do_cb), if_dlg_data);
-  gtk_widget_get_preferred_size(GTK_WIDGET(close_bt), &requisition, NULL);
-  /* height + static offset + what the GTK MS Windows Engine needs in addition per interface */
-  height += requisition.height + 40 + ifs;
-  gtk_window_set_default_size(GTK_WINDOW(cap_if_w), -1, height);
+  g_signal_connect(capture_bt, "clicked", G_CALLBACK(capture_do_cb), NULL);
 
   gtk_widget_grab_default(close_bt);
 
   g_signal_connect(cap_if_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
   g_signal_connect(cap_if_w, "destroy", G_CALLBACK(capture_if_destroy_cb), sc);
 
-  gtk_widget_show_all(cap_if_w);
+  capture_if_refresh_if_list();
+
   window_present(cap_if_w);
 
   set_capture_if_dialog_for_capture_in_progress(gbl_capture_in_progress);
-
-  /* update the interface list every 1000ms */
-  timer_id = g_timeout_add(1000, update_all, sc);
 }
 
 gboolean interfaces_dialog_window_present(void)
@@ -1026,21 +917,20 @@ gboolean interfaces_dialog_window_present(void)
 
 void refresh_if_window(void)
 {
-  capture_if_destroy_cb(NULL, NULL);
-  capture_if_cb(NULL, NULL);
+  if (cap_if_w) {
+    capture_if_refresh_if_list();
+  }
 }
 
-void select_all_interfaces(gboolean enable)
+void select_all_interfaces(gboolean enable _U_)
 {
-  if_dlg_data_t *temp;
   guint ifs;
-  GList *curr;
+  interface_t device;
 
-  for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) {
-    curr = g_list_nth(if_data_list, ifs);
-    temp = (if_dlg_data_t *)(curr->data);
-    update_selected_interface(temp->if_info.name, enable);
- }
+  for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) {
+    device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs);
+    update_selected_interface(device.if_info.name);
+  }
 }
 
 void destroy_if_window(void)