We need a 3rd try. (After learning how to run the testuite on Windows locally).
authortuexen <tuexen@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 24 Jan 2012 17:12:56 +0000 (17:12 +0000)
committertuexen <tuexen@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 24 Jan 2012 17:12:56 +0000 (17:12 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@40695 f5534014-38df-0310-8fa8-9805f1628bb7

17 files changed:
capture.c
capture.h
capture_opts.c
capture_opts.h
capture_sync.c
capture_ui_utils.c
tshark.c
ui/gtk/capture_dlg.c
ui/gtk/capture_dlg.h
ui/gtk/capture_if_dlg.c
ui/gtk/capture_if_dlg.h
ui/gtk/main.c
ui/gtk/main.h
ui/gtk/main_welcome.c
ui/gtk/main_welcome.h
ui/gtk/prefs_capture.c
ui/gtk/prefs_taps.c

index f778a35621c6b30106f4c5866ac5a0e41593134f..eb3b042311f4b5166c0f00f31e90f2ed912986fc 100644 (file)
--- a/capture.c
+++ b/capture.c
@@ -81,49 +81,49 @@ static GList *capture_callbacks = NULL;
 static void
 capture_callback_invoke(int event, capture_options *capture_opts)
 {
-  capture_callback_data_t *cb;
-  GList *cb_item = capture_callbacks;
+    capture_callback_data_t *cb;
+    GList *cb_item = capture_callbacks;
 
-  /* there should be at least one interested */
-  g_assert(cb_item != NULL);
+    /* there should be at least one interested */
+    g_assert(cb_item != NULL);
 
-  while(cb_item != NULL) {
-    cb = cb_item->data;
-    cb->cb_fct(event, capture_opts, cb->user_data);
-    cb_item = g_list_next(cb_item);
-  }
+    while(cb_item != NULL) {
+        cb = cb_item->data;
+        cb->cb_fct(event, capture_opts, cb->user_data);
+        cb_item = g_list_next(cb_item);
+    }
 }
 
 
 void
 capture_callback_add(capture_callback_t func, gpointer user_data)
 {
-  capture_callback_data_t *cb;
+    capture_callback_data_t *cb;
 
-  cb = g_malloc(sizeof(capture_callback_data_t));
-  cb->cb_fct = func;
-  cb->user_data = user_data;
+    cb = g_malloc(sizeof(capture_callback_data_t));
+    cb->cb_fct = func;
+    cb->user_data = user_data;
 
-  capture_callbacks = g_list_append(capture_callbacks, cb);
+    capture_callbacks = g_list_append(capture_callbacks, cb);
 }
 
 void
 capture_callback_remove(capture_callback_t func)
 {
-  capture_callback_data_t *cb;
-  GList *cb_item = capture_callbacks;
-
-  while(cb_item != NULL) {
-    cb = cb_item->data;
-    if(cb->cb_fct == func) {
-      capture_callbacks = g_list_remove(capture_callbacks, cb);
-      g_free(cb);
-      return;
+    capture_callback_data_t *cb;
+    GList *cb_item = capture_callbacks;
+
+    while(cb_item != NULL) {
+        cb = cb_item->data;
+        if(cb->cb_fct == func) {
+            capture_callbacks = g_list_remove(capture_callbacks, cb);
+            g_free(cb);
+            return;
+        }
+        cb_item = g_list_next(cb_item);
     }
-    cb_item = g_list_next(cb_item);
-  }
 
-  g_assert_not_reached();
+    g_assert_not_reached();
 }
 
 /**
@@ -144,7 +144,7 @@ capture_start(capture_options *capture_opts)
 
   /* close the currently loaded capture file */
   cf_close(capture_opts->cf);
-  collect_ifaces(capture_opts);
+
   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start ...");
 
 #ifdef _WIN32
@@ -176,6 +176,7 @@ capture_start(capture_options *capture_opts)
   }
   cf_set_tempfile_source(capture_opts->cf, source->str);
   g_string_free(source, TRUE);
+
   /* try to start the capture child process */
   ret = sync_pipe_start(capture_opts);
   if(!ret) {
@@ -547,242 +548,239 @@ capture_input_cfilter_error_message(capture_options *capture_opts, guint i, char
 void
 capture_input_closed(capture_options *capture_opts, gchar *msg)
 {
-  int  err;
-  int  packet_count_save;
-
-  g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!");
-  g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
-
-  if (msg != NULL)
-    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg);
-
-  /* if we didn't start the capture, do a fake start. */
-  /* (happens if we got an error message - we won't get a filename then). */
-  if(capture_opts->state == CAPTURE_PREPARING) {
-    if(capture_opts->real_time_mode) {
-      capture_callback_invoke(capture_cb_capture_update_started, capture_opts);
-    } else {
-      capture_callback_invoke(capture_cb_capture_fixed_started, capture_opts);
+    int  err;
+    int  packet_count_save;
+
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!");
+    g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
+
+    if (msg != NULL)
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg);
+
+    /* if we didn't start the capture, do a fake start. */
+    /* (happens if we got an error message - we won't get a filename then). */
+    if(capture_opts->state == CAPTURE_PREPARING) {
+        if(capture_opts->real_time_mode) {
+            capture_callback_invoke(capture_cb_capture_update_started, capture_opts);
+        } else {
+            capture_callback_invoke(capture_cb_capture_fixed_started, capture_opts);
+        }
     }
-  }
 
-  if(capture_opts->real_time_mode) {
-    cf_read_status_t status;
+    if(capture_opts->real_time_mode) {
+        cf_read_status_t status;
 
-    /* Read what remains of the capture file. */
-    status = cf_finish_tail(capture_opts->cf, &err);
+        /* Read what remains of the capture file. */
+        status = cf_finish_tail(capture_opts->cf, &err);
 
-    /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */
-    packet_count_save = cf_get_packet_count(capture_opts->cf);
-    /* Tell the GUI we are not doing a capture any more.
-       Must be done after the cf_finish_tail(), so file lengths are 
-       correctly displayed */
-    capture_callback_invoke(capture_cb_capture_update_finished, capture_opts);
+        /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */
+        packet_count_save = cf_get_packet_count(capture_opts->cf);
+        /* Tell the GUI we are not doing a capture any more.
+           Must be done after the cf_finish_tail(), so file lengths are 
+           correctly displayed */
+        capture_callback_invoke(capture_cb_capture_update_finished, capture_opts);
 
-    /* Finish the capture. */
-    switch (status) {
+        /* Finish the capture. */
+        switch (status) {
 
-    case CF_READ_OK:
-      if ((packet_count_save == 0) && !capture_opts->restart) {
-        simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
-          "%sNo packets captured!%s\n"
-          "\n"
-          "As no data was captured, closing the %scapture file!\n"
-          "\n"
-          "\n"
-          "Help about capturing can be found at:\n"
-          "\n"
-          "       http://wiki.wireshark.org/CaptureSetup"
+        case CF_READ_OK:
+            if ((packet_count_save == 0) && !capture_opts->restart) {
+                simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
+"%sNo packets captured!%s\n"
+"\n"
+"As no data was captured, closing the %scapture file!\n"
+"\n"
+"\n"
+"Help about capturing can be found at:\n"
+"\n"
+"       http://wiki.wireshark.org/CaptureSetup"
 #ifdef _WIN32
-          "\n\n"
-          "Wireless (Wi-Fi/WLAN):\n"
-          "Try to switch off promiscuous mode in the Capture Options!"
+"\n\n"
+"Wireless (Wi-Fi/WLAN):\n"
+"Try to switch off promiscuous mode in the Capture Options!"
 #endif
-          "",
-          simple_dialog_primary_start(), simple_dialog_primary_end(),
-          cf_is_tempfile(capture_opts->cf) ? "temporary " : "");
-        cf_close(capture_opts->cf);
-      }
-      break;
-    case CF_READ_ERROR:
-      /* Just because we got an error, that doesn't mean we were unable
-         to read any of the file; we handle what we could get from the
-         file. */
-      break;
-
-    case CF_READ_ABORTED:
-      /* Exit by leaving the main loop, so that any quit functions
-         we registered get called. */
-      main_window_quit();
-      break;
-    }
-
-  } else {
-    /* first of all, we are not doing a capture any more */
-    capture_callback_invoke(capture_cb_capture_fixed_finished, capture_opts);
+"",
+              simple_dialog_primary_start(), simple_dialog_primary_end(),
+              cf_is_tempfile(capture_opts->cf) ? "temporary " : "");
+              cf_close(capture_opts->cf);
+            }
+            break;
+        case CF_READ_ERROR:
+          /* Just because we got an error, that doesn't mean we were unable
+             to read any of the file; we handle what we could get from the
+             file. */
+          break;
+
+        case CF_READ_ABORTED:
+          /* Exit by leaving the main loop, so that any quit functions
+             we registered get called. */
+          main_window_quit();
+         break;
+        }
 
-    /* this is a normal mode capture and if no error happened, read in the capture file data */
-    if(capture_opts->save_file != NULL) {
-      capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf),
-        cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
+    } else {
+        /* first of all, we are not doing a capture any more */
+        capture_callback_invoke(capture_cb_capture_fixed_finished, capture_opts);
+
+        /* this is a normal mode capture and if no error happened, read in the capture file data */
+        if(capture_opts->save_file != NULL) {
+            capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf),
+                cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
+        }
     }
-  }
 
-  if(capture_opts->show_info)
-    capture_info_close();
+    if(capture_opts->show_info)
+      capture_info_close();
 
-  capture_opts->state = CAPTURE_STOPPED;
+    capture_opts->state = CAPTURE_STOPPED;
 
-  /* if we couldn't open a capture file, there's nothing more for us to do */
-  if(capture_opts->save_file == NULL) {
-    cf_close(capture_opts->cf);
-    return;
-  }
+    /* if we couldn't open a capture file, there's nothing more for us to do */
+    if(capture_opts->save_file == NULL) {
+        cf_close(capture_opts->cf);
+        return;
+    }
 
-  /* does the user wants to restart the current capture? */
-  if(capture_opts->restart) {
-    capture_opts->restart = FALSE;
+    /* does the user wants to restart the current capture? */
+    if(capture_opts->restart) {
+        capture_opts->restart = FALSE;
 
-    ws_unlink(capture_opts->save_file);
+        ws_unlink(capture_opts->save_file);
 
-    /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
-    if(cf_is_tempfile(capture_opts->cf)) {
-      g_free(capture_opts->save_file);
-      capture_opts->save_file = NULL;
-    }
+        /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
+        if(cf_is_tempfile(capture_opts->cf)) {
+            g_free(capture_opts->save_file);
+            capture_opts->save_file = NULL;
+        }
 
-    /* ... and start the capture again */
-    if (capture_opts->ifaces->len == 0) {
-      collect_ifaces(capture_opts);
+        /* ... and start the capture again */
+        capture_start(capture_opts);
+    } else {
+        /* We're not doing a capture any more, so we don't have a save file. */
+        g_free(capture_opts->save_file);
+        capture_opts->save_file = NULL;
     }
-    capture_start(capture_opts);
-  } else {
-    /* We're not doing a capture any more, so we don't have a save file. */
-    g_free(capture_opts->save_file);
-    capture_opts->save_file = NULL;
-  }
 }
 
 if_stat_cache_t *
-capture_stat_start(capture_options *capture_opts) {
-  int stat_fd, fork_child;
-  gchar *msg;
-  if_stat_cache_t *sc = NULL;
-  if_stat_cache_item_t *sc_item;
-  guint i;
-  interface_t device;
-
-  /* Fire up dumpcap. */
-  /*
-   * XXX - on systems with BPF, the number of BPF devices limits the
-   * number of devices on which you can capture simultaneously.
-   *
-   * This means that
-   *
-   *    1) this might fail if you run out of BPF devices
-   *
-   * and
-   *
-   *    2) opening every interface could leave too few BPF devices
-   *       for *other* programs.
-   *
-   * It also means the system could end up getting a lot of traffic
-   * that it has to pass through the networking stack and capture
-   * mechanism, so opening all the devices and presenting packet
-   * counts might not always be a good idea.
-   */
-  if (sync_interface_stats_open(&stat_fd, &fork_child, &msg) == 0) {
-    sc = g_malloc(sizeof(if_stat_cache_t));
-    sc->stat_fd = stat_fd;
-    sc->fork_child = fork_child;
-    sc->cache_list = NULL;
-
-    /* Initialize the cache */
-    for (i = 0; i < capture_opts->all_ifaces->len; i++) {
-      device = g_array_index(capture_opts->all_ifaces, interface_t, i);
-      if (&(device.if_info)) {
-        sc_item = g_malloc0(sizeof(if_stat_cache_item_t));
-        sc_item->name = g_strdup(device.if_info.name);
-        sc->cache_list = g_list_append(sc->cache_list, sc_item);
-      }
+capture_stat_start(GList *if_list) {
+    int stat_fd, fork_child;
+    gchar *msg;
+    if_stat_cache_t *sc = NULL;
+    GList *if_entry;
+    if_info_t *if_info;
+    if_stat_cache_item_t *sc_item;
+
+    /* Fire up dumpcap. */
+    /*
+     * XXX - on systems with BPF, the number of BPF devices limits the
+     * number of devices on which you can capture simultaneously.
+     *
+     * This means that
+     *
+     *    1) this might fail if you run out of BPF devices
+     *
+     * and
+     *
+     *    2) opening every interface could leave too few BPF devices
+     *       for *other* programs.
+     *
+     * It also means the system could end up getting a lot of traffic
+     * that it has to pass through the networking stack and capture
+     * mechanism, so opening all the devices and presenting packet
+     * counts might not always be a good idea.
+     */
+     if (sync_interface_stats_open(&stat_fd, &fork_child, &msg) == 0) {
+        sc = g_malloc(sizeof(if_stat_cache_t));
+        sc->stat_fd = stat_fd;
+        sc->fork_child = fork_child;
+        sc->cache_list = NULL;
+
+        /* Initialize the cache */
+        for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
+            if_info = if_entry->data;
+            if (if_info) {
+                sc_item = g_malloc0(sizeof(if_stat_cache_item_t));
+                sc_item->name = g_strdup(if_info->name);
+                sc->cache_list = g_list_append(sc->cache_list, sc_item);
+            }
+        }
     }
-  }
-  return sc;
+    return sc;
 }
 
 #define MAX_STAT_LINE_LEN 500
 
 static void
 capture_stat_cache_update(if_stat_cache_t *sc) {
-  gchar stat_line[MAX_STAT_LINE_LEN];
-  gchar **stat_parts;
-  GList *sc_entry;
-  if_stat_cache_item_t *sc_item;
-
-  if (!sc)
-    return;
-
-  while (sync_pipe_gets_nonblock(sc->stat_fd, stat_line, MAX_STAT_LINE_LEN) > 0) {
-    g_strstrip(stat_line);
-    stat_parts = g_strsplit(stat_line, "\t", 3);
-    if (stat_parts[0] == NULL || stat_parts[1] == NULL ||
-      stat_parts[2] == NULL) {
-      g_strfreev(stat_parts);
-      continue;
-    }
-    for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
-      sc_item = sc_entry->data;
-      if (strcmp(sc_item->name, stat_parts[0]) == 0) {
-        sc_item->ps.ps_recv = (u_int) strtoul(stat_parts[1], NULL, 10);
-        sc_item->ps.ps_drop = (u_int) strtoul(stat_parts[2], NULL, 10);
-      }
+    gchar stat_line[MAX_STAT_LINE_LEN];
+    gchar **stat_parts;
+    GList *sc_entry;
+    if_stat_cache_item_t *sc_item;
+
+    if (!sc)
+        return;
+
+    while (sync_pipe_gets_nonblock(sc->stat_fd, stat_line, MAX_STAT_LINE_LEN) > 0) {
+        g_strstrip(stat_line);
+        stat_parts = g_strsplit(stat_line, "\t", 3);
+        if (stat_parts[0] == NULL || stat_parts[1] == NULL ||
+            stat_parts[2] == NULL) {
+            g_strfreev(stat_parts);
+            continue;
+        }
+        for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
+            sc_item = sc_entry->data;
+            if (strcmp(sc_item->name, stat_parts[0]) == 0) {
+                sc_item->ps.ps_recv = (u_int) strtoul(stat_parts[1], NULL, 10);
+                sc_item->ps.ps_drop = (u_int) strtoul(stat_parts[2], NULL, 10);
+            }
+        }
+        g_strfreev(stat_parts);
     }
-  g_strfreev(stat_parts);
-  }
 }
 
 gboolean
 capture_stats(if_stat_cache_t *sc, char *ifname, struct pcap_stat *ps) {
-  GList *sc_entry;
-  if_stat_cache_item_t *sc_item;
+    GList *sc_entry;
+    if_stat_cache_item_t *sc_item;
 
-  if (!sc || !ifname || !ps) {
-    return FALSE;
-  }
+    if (!sc || !ifname || !ps) {
+        return FALSE;
+    }
 
-  capture_stat_cache_update(sc);
-  for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
-    sc_item = sc_entry->data;
-    if (strcmp(sc_item->name, ifname) == 0) {
-      memcpy(ps, &sc_item->ps, sizeof(struct pcap_stat));
-      return TRUE;
+    capture_stat_cache_update(sc);
+    for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
+        sc_item = sc_entry->data;
+        if (strcmp(sc_item->name, ifname) == 0) {
+            memcpy(ps, &sc_item->ps, sizeof(struct pcap_stat));
+            return TRUE;
+        }
     }
-  }
-  return FALSE;
+    return FALSE;
 }
 
 void
 capture_stat_stop(if_stat_cache_t *sc) {
-  GList *sc_entry;
-  if_stat_cache_item_t *sc_item;
-  int ret;
-  gchar *msg;
-
-  if (!sc)
-    return;
-
-  ret = sync_interface_stats_close(&sc->stat_fd, &sc->fork_child, &msg);
-  if (ret == -1) {
-    /* XXX - report failure? */
-    g_free(msg);
-  }
+    GList *sc_entry;
+    if_stat_cache_item_t *sc_item;
+    int ret;
+    gchar *msg;
+
+    if (!sc)
+        return;
+
+    ret = sync_interface_stats_close(&sc->stat_fd, &sc->fork_child, &msg);
+    if (ret == -1) {
+        /* XXX - report failure? */
+        g_free(msg);
+    }
 
-  for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
-    sc_item = sc_entry->data;
-    g_free(sc_item->name);
-    g_free(sc_item);
-  }
-  g_free(sc);
+    for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
+        sc_item = sc_entry->data;
+        g_free(sc_item->name);
+        g_free(sc_item);
+    }
+    g_free(sc);
 }
 
 #endif /* HAVE_LIBPCAP */
index 93ea812ba2ae77b3a1b267d1160186463789e7e0..d4cc76986b63eede2a5c57bc7398780dbc76f0a6 100644 (file)
--- a/capture.h
+++ b/capture.h
@@ -114,7 +114,7 @@ typedef struct if_stat_cache_s if_stat_cache_t;
  * @param if_list A GList of if_info_t items
  * @return A pointer to the statistics state data.
  */
-extern if_stat_cache_t * capture_stat_start(capture_options *capture_opts);
+extern if_stat_cache_t * capture_stat_start(GList *if_list);
 
 /**
  * Fetch capture statistics, similar to pcap_stats().
index 732e48124e8592d9d4391b6d6eb8372230a75e69..f200be3735b608b300e8087170deee0d16c02ce8 100644 (file)
@@ -38,9 +38,6 @@
 #include <glib.h>
 
 #include <epan/packet.h>
-#include <epan/prefs.h>
-#include "ui/simple_dialog.h"
-#include "capture_ui_utils.h"
 
 #include "capture_opts.h"
 #include "ringbuffer.h"
@@ -60,8 +57,6 @@ capture_opts_init(capture_options *capture_opts, void *cf)
 {
   capture_opts->cf                              = cf;
   capture_opts->ifaces                          = g_array_new(FALSE, FALSE, sizeof(interface_options));
-  capture_opts->all_ifaces                      = g_array_new(FALSE, FALSE, sizeof(interface_t));
-  capture_opts->num_selected                    = 0;
   capture_opts->default_options.name            = NULL;
   capture_opts->default_options.descr           = NULL;
   capture_opts->default_options.cfilter         = NULL;
@@ -532,169 +527,6 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
     return 0;
 }
 
-int
-capture_opts_select_iface(capture_options *capture_opts, const char *optarg_str_p)
-{
-    long        adapter_index;
-    char        *p;
-    GList       *if_list;
-    if_info_t   *if_info;
-    int         err;
-    guint       i;
-    gchar       *err_str, *name = NULL;
-    interface_t device;
-    gboolean    found = FALSE;
-    interface_options interface_opts;
-
-    /*
-     * If the argument is a number, treat it as an index into the list
-     * of adapters, as printed by "tshark -D".
-     *
-     * This should be OK on UNIX systems, as interfaces shouldn't have
-     * names that begin with digits.  It can be useful on Windows, where
-     * more than one interface can have the same name.
-     */
-    adapter_index = strtol(optarg_str_p, &p, 10);
-    if (p != NULL && *p == '\0') {
-        if (adapter_index < 0) {
-            cmdarg_err("The specified adapter index is a negative number");
-            return 1;
-        }
-        if (adapter_index > INT_MAX) {
-            cmdarg_err("The specified adapter index is too large (greater than %d)",
-                       INT_MAX);
-            return 1;
-        }
-        if (adapter_index == 0) {
-            cmdarg_err("There is no interface with that adapter index");
-            return 1;
-        }
-        if_list = capture_interface_list(&err, &err_str);
-        if (if_list == NULL) {
-            switch (err) {
-
-            case CANT_GET_INTERFACE_LIST:
-                cmdarg_err("%s", err_str);
-                g_free(err_str);
-                break;
-
-            case NO_INTERFACES_FOUND:
-                cmdarg_err("There are no interfaces on which a capture can be done");
-                break;
-            }
-            return 2;
-        }
-        if_info = (if_info_t *)g_list_nth_data(if_list, adapter_index - 1);
-        if (if_info == NULL) {
-            cmdarg_err("There is no interface with that adapter index");
-            return 1;
-        }
-        name = g_strdup(if_info->name);
-        /*  We don't set iface_descr here because doing so requires
-         *  capture_ui_utils.c which requires epan/prefs.c which is
-         *  probably a bit too much dependency for here...
-         */
-        free_interface_list(if_list);
-    } else {
-        name = g_strdup(optarg_str_p);
-    }
-    if (capture_opts->all_ifaces->len > 0) {
-        for(i = 0; i < capture_opts->all_ifaces->len; i++) {
-            device = g_array_index(capture_opts->all_ifaces, interface_t, i);
-            if (strcmp(device.name, name) == 0) {
-                if (device.hidden) {
-                    cmdarg_err("Interface %s is hidden. You can't capture on hidden interfaces.", name);
-                    return 1;
-                }
-                device.selected = TRUE;
-                capture_opts->num_selected++;
-                capture_opts->all_ifaces = g_array_remove_index(capture_opts->all_ifaces, i);
-                g_array_insert_val(capture_opts->all_ifaces, i, device);
-                found = TRUE;
-                break;
-            }
-        } 
-        if (!found) {
-            device.name         = g_strdup(name);
-            device.display_name = g_strdup_printf("%s", device.name);
-            device.hidden       = FALSE;
-            device.selected     = TRUE;
-            device.type         = IF_PIPE;
-            device.pmode        = capture_opts->default_options.promisc_mode;
-            device.has_snaplen  = capture_opts->default_options.has_snaplen;
-            device.snaplen      = capture_opts->default_options.snaplen;
-            device.cfilter      = g_strdup(capture_opts->default_options.cfilter);
-            device.addresses    = NULL;
-            device.no_addresses = 0;
-            device.last_packets = 0;
-            device.links        = NULL;
-            device.active_dlt   = -1;
-            device.local        = TRUE;
-            device.locked       = FALSE;
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-            device.buffer = 1;
-            device.monitor_mode_enabled   = FALSE;
-            device.monitor_mode_supported = FALSE;
-#endif
-            g_array_append_val(capture_opts->all_ifaces, device);
-            capture_opts->num_selected++;
-        }
-    } else {
-        interface_opts.name = g_strdup(optarg_str_p);
-        interface_opts.descr = g_strdup(capture_opts->default_options.descr);
-        interface_opts.cfilter = g_strdup(capture_opts->default_options.cfilter);
-        interface_opts.snaplen = capture_opts->default_options.snaplen;
-        interface_opts.has_snaplen = capture_opts->default_options.has_snaplen;
-        interface_opts.linktype = capture_opts->default_options.linktype;
-        interface_opts.promisc_mode = capture_opts->default_options.promisc_mode;
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-        interface_opts.buffer_size = capture_opts->default_options.buffer_size;
-#endif
-        interface_opts.monitor_mode = capture_opts->default_options.monitor_mode;
-#ifdef HAVE_PCAP_REMOTE
-        interface_opts.src_type = capture_opts->default_options.src_type;
-        interface_opts.remote_host = g_strdup(capture_opts->default_options.remote_host);
-        interface_opts.remote_port = g_strdup(capture_opts->default_options.remote_port);
-        interface_opts.auth_type = capture_opts->default_options.auth_type;
-        interface_opts.auth_username = g_strdup(capture_opts->default_options.auth_username);
-        interface_opts.auth_password = g_strdup(capture_opts->default_options.auth_password);
-        interface_opts.datatx_udp = capture_opts->default_options.datatx_udp;
-        interface_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap;
-        interface_opts.nocap_local = capture_opts->default_options.nocap_local;
-#endif
-#ifdef HAVE_PCAP_SETSAMPLING
-        interface_opts.sampling_method = capture_opts->default_options.sampling_method;
-        interface_opts.sampling_param  = capture_opts->default_options.sampling_param;
-#endif
-        g_array_append_val(capture_opts->ifaces, interface_opts);
-
-        device.name         = g_strdup(name);
-        device.display_name = g_strdup_printf("%s", device.name);
-        device.hidden       = FALSE;
-        device.selected     = TRUE;
-        device.type         = IF_PIPE;
-        device.pmode        = capture_opts->default_options.promisc_mode;
-        device.has_snaplen  = capture_opts->default_options.has_snaplen;
-        device.snaplen      = capture_opts->default_options.snaplen;
-        device.cfilter      = g_strdup(capture_opts->default_options.cfilter);
-        device.addresses    = NULL;
-        device.no_addresses = 0;
-        device.last_packets = 0;
-        device.links        = NULL;
-        device.active_dlt   = -1;
-        device.local        = TRUE;
-        device.locked       = FALSE;
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-            device.buffer = 1;
-        device.monitor_mode_enabled   = FALSE;
-        device.monitor_mode_supported = FALSE;
-#endif
-        g_array_append_val(capture_opts->all_ifaces, device);
-        capture_opts->num_selected++;
-    }
-    return 0;
-}
-
 int
 capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture)
 {
@@ -995,7 +827,7 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt
 
 
     /* Did the user specify an interface to use? */
-    if (capture_opts->num_selected == 0 && capture_opts->ifaces->len == 0) {
+    if (capture_opts->ifaces->len == 0) {
         /* No - is a default specified in the preferences file? */
         if (capture_device != NULL) {
             /* Yes - use it. */
@@ -1127,49 +959,4 @@ static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_
   return 0;
 }
 
-void
-collect_ifaces(capture_options *capture_opts)
-{
-  guint i;
-  interface_t device;
-  interface_options interface_opts;
-  for (i = 0; i < capture_opts->all_ifaces->len; i++) {
-    device = g_array_index(capture_opts->all_ifaces, interface_t, i);
-    if (!device.hidden && device.selected) {
-      interface_opts.name = g_strdup(device.name);
-      interface_opts.descr = g_strdup(device.display_name);
-      interface_opts.monitor_mode = device.monitor_mode_enabled;
-      interface_opts.linktype = device.active_dlt;
-      interface_opts.cfilter = g_strdup(device.cfilter);
-      interface_opts.snaplen = device.snaplen;
-      interface_opts.has_snaplen = device.has_snaplen;
-      interface_opts.promisc_mode = device.pmode;
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-      interface_opts.buffer_size =  device.buffer;
-#endif
-      if (!device.local) {
-#ifdef HAVE_PCAP_REMOTE 
-        interface_opts.src_type = CAPTURE_IFREMOTE;
-        interface_opts.remote_host = g_strdup(device.remote_opts.remote_host_opts.remote_host);
-        interface_opts.remote_port = g_strdup(device.remote_opts.remote_host_opts.remote_port);
-        interface_opts.auth_type = device.remote_opts.remote_host_opts.auth_type;
-        interface_opts.auth_username = g_strdup(device.remote_opts.remote_host_opts.auth_username);
-        interface_opts.auth_password = g_strdup(device.remote_opts.remote_host_opts.auth_password);
-        interface_opts.datatx_udp = device.remote_opts.remote_host_opts.datatx_udp;
-        interface_opts.nocap_rpcap = device.remote_opts.remote_host_opts.nocap_rpcap;
-        interface_opts.nocap_local = device.remote_opts.remote_host_opts.nocap_local;
-#endif
-#ifdef HAVE_PCAP_SETSAMPLING
-        interface_opts.sampling_method = device.remote_opts.sampling_method;
-        interface_opts.sampling_param  = device.remote_opts.sampling_param;
-#endif
-      }
-      g_array_append_val(capture_opts->ifaces, interface_opts);
-    } else {
-      continue;
-    }
-  }
-}
-
-
 #endif /* HAVE_LIBPCAP */
index c3805d1a93dc8e3d791aed6e77847e98607c9f12..baa40099a704a07f06405065f5436a59d82d8f60 100644 (file)
@@ -77,73 +77,6 @@ typedef enum {
 } capture_sampling;
 #endif
 
-typedef enum {
-    IF_WIRED,
-    IF_AIRPCAP,
-    IF_PIPE,
-    IF_STDIN,
-    IF_BLUETOOTH,
-    IF_WIRELESS,
-    IF_DIALUP,
-    IF_USB,
-    IF_VIRTUAL
-} interface_type;
-
-#ifdef HAVE_PCAP_REMOTE
-struct remote_host {
-    gchar *remote_host;          /**< Host name or network address for remote capturing */
-    gchar *remote_port;          /**< TCP port of remote RPCAP server */
-    gint auth_type;              /**< Authentication type */
-    gchar *auth_username;        /**< Remote authentication parameters */
-    gchar *auth_password;        /**< Remote authentication parameters */
-    gboolean datatx_udp;
-    gboolean nocap_rpcap;
-    gboolean nocap_local;
-};
-
-typedef struct remote_options_tag {
-    capture_source src_type;
-    struct remote_host remote_host_opts;
-#ifdef HAVE_PCAP_SETSAMPLING
-    capture_sampling sampling_method;
-    int sampling_param;
-#endif
-} remote_options;
-#endif /* HAVE_PCAP_REMOTE */
-
-typedef struct interface_tag {
-    gchar *name;
-    gchar *display_name;
-    guint type;
-    gchar *addresses;
-    gint no_addresses;
-    gchar *cfilter;
-    GList *links;
-    gint active_dlt;
-    gboolean pmode;
-    gboolean has_snaplen;
-    guint snaplen;
-    gboolean local;
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-    gint buffer;
-    gboolean monitor_mode_enabled;
-    gboolean monitor_mode_supported;
-#endif
-#ifdef HAVE_PCAP_REMOTE
-    remote_options remote_opts;
-#endif
-    guint32     last_packets;
-    if_info_t   if_info;
-    gboolean    selected;
-    gboolean    hidden;
-    gboolean    locked;
-} interface_t;
-
-typedef struct link_row_tag {
-    gchar *name;
-    gint dlt;
-} link_row;
-
 typedef struct interface_options_tag {
     gchar *name;
     gchar *descr;
@@ -179,8 +112,6 @@ typedef struct capture_options_tag {
     void     *cf;                   /**< handle to cfile (note: untyped handle) */
     GArray   *ifaces;               /**< array of interfaces.
                                          Currently only used by dumpcap. */
-    GArray   *all_ifaces;
-    guint    num_selected;
     interface_options default_options;
     gboolean saving_to_file;        /**< TRUE if capture is writing to a file */
     gchar    *save_file;            /**< the capture file name */
@@ -263,27 +194,6 @@ capture_opts_trim_ring_num_files(capture_options *capture_opts);
 extern gboolean
 capture_opts_trim_iface(capture_options *capture_opts, const char *capture_device);
 
-extern void
-collect_ifaces(capture_options *capture_opts);
-
-typedef struct {
-    gboolean monitor_mode;
-    int linktype;
-} cap_settings_t;
-
-/** Get capture settings for interface
- *
- * @param if_name interface name
- */
-cap_settings_t
-capture_get_cap_settings (gchar *if_name);
-
-extern void 
-scan_local_interfaces(capture_options* capture_opts, int *error);
-
-int
-capture_opts_select_iface(capture_options *capture_opts, const char *optarg_str_p);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 04614b2ebeab2d90cce3e9a39cfb4fd80c8317f6..02223ef28a80d978cffb1d0b3f9e540d3a7529e5 100644 (file)
@@ -463,11 +463,9 @@ sync_pipe_start(capture_options *capture_opts) {
         }
 #endif
 
-#ifdef HAVE_PCAP_CREATE
         if (interface_opts.monitor_mode) {
             argv = sync_pipe_add_arg(argv, &argc, "-I");
         }
-#endif
 
 #ifdef HAVE_PCAP_REMOTE
         if (interface_opts.datatx_udp)
index 48bca7a31b5d89204d9d4a37e37a86a48b95ee09..1ebe978c6831282c653c364e982c1a3e234637c7 100644 (file)
@@ -38,9 +38,6 @@
 #include "epan/ex-opt.h"
 #include "capture_ifinfo.h"
 #include "capture_ui_utils.h"
-#include "ui/simple_dialog.h"
-#include "wiretap/wtap.h"
-#include "epan/to_str.h"
 
 /*
  * Find user-specified capture device description that matches interface
index efe2936d7388f4da201ac2ca74bb584cb35cf77c..3419f5e5c4a80d59cb3b462ca683822cb2205d4a 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -95,7 +95,6 @@
 #endif /* HAVE_LIBPCAP */
 #include "log.h"
 #include <epan/funnel.h>
-#include "capture_opts.h"
 
 /*
  * This is the template for the decode as option; it is shared between the
index 84e0fb6dd1ba1148902a121c99697250cf2fdc02..69965a03252f37a65ccad6d9a21d697ebff24fb6 100644 (file)
@@ -182,7 +182,8 @@ static GtkWidget *cap_open_w = NULL, *opt_edit_w = NULL, *ok_bt;
 static gboolean   cap_open_complete;  /* valid only if cap_open_w != NULL */
 
 static GHashTable *cap_settings_history=NULL;
-static gint marked_interface;
+static gint16 num_selected;
+static GArray *rows = NULL;
 static gint marked_row;
 
 #ifdef HAVE_PCAP_REMOTE
@@ -217,6 +218,9 @@ capture_dlg_prep(gpointer parent_w);
 
 extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg);
 
+static void
+make_and_fill_rows(void);
+
 /* stop the currently running capture */
 void
 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
@@ -793,7 +797,7 @@ error_list_remote_interface_cb (gpointer dialog _U_, gint btn _U_, gpointer data
 static void 
 insert_new_rows(GList *list)
 {
-  interface_t device;
+  interface_row row;
   GtkTreeIter iter;
   GList *if_entry;
   if_info_t *if_info;
@@ -802,9 +806,10 @@ insert_new_rows(GList *list)
   if_capabilities_t *caps;
   gint linktype_count;
   cap_settings_t cap_settings;
+  gchar *err_str, *err_str_norfmon;
   GSList *curr_addr;
   int ips = 0;
-  guint i;
+  guint i, count=0;
   if_addr_t *addr;
   GList *lt_entry;
   data_link_info_t *data_link_info;
@@ -813,19 +818,21 @@ insert_new_rows(GList *list)
   GString *ip_str;
   GtkTreeView  *if_cb;
   GtkTreeModel *model;
+  interface_options interface_opts;
   link_row *link = NULL;
 
   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
   model = gtk_tree_view_get_model(if_cb);
+  count = rows->len;
   /* Scan through the list and build a list of strings to display. */
   for (if_entry = g_list_first(list); if_entry != NULL; if_entry = g_list_next(if_entry)) {
     if_info = (if_info_t *)if_entry->data;
 #ifdef HAVE_PCAP_REMOTE
     add_interface_to_remote_list(if_info);
 #endif
-    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(device.name, if_info->name) == 0) {
+    for (i = 0; i < count; i++) {
+      row = g_array_index(rows, interface_row, i);
+      if (strcmp(row.name, if_info->name) == 0) {
         found = TRUE;
         break;
       }
@@ -835,9 +842,8 @@ insert_new_rows(GList *list)
       continue;
     }
     ip_str = g_string_new("");
-    str = "";
     ips = 0;
-    device.name = g_strdup(if_info->name);
+    row.name = g_strdup(if_info->name);
     /* Is this interface hidden and, if so, should we include it
        anyway? */
     descr = capture_dev_user_descr_find(if_info->name);
@@ -857,19 +863,82 @@ insert_new_rows(GList *list)
       }
     } /* else descr != NULL */
     if (if_info->loopback) {
-      device.display_name = g_strdup_printf("%s (loopback)", if_string);
+      row.display_name = g_strdup_printf("%s (loopback)", if_string);
     } else {
-      device.display_name = g_strdup(if_string);
+      row.display_name = g_strdup(if_string);
+    }
+    found = FALSE;
+    for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+      interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
+      if (strcmp(interface_opts.name, (char*)row.name)!=0)
+        continue;
+      else {
+        found = TRUE;
+        break;
+      }
     }
+    if (found) {
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+      row.buffer = interface_opts.buffer_size;
+#endif
+      row.pmode = interface_opts.promisc_mode;
+      row.has_snaplen = interface_opts.has_snaplen;
+      row.snaplen = interface_opts.snaplen;
+      row.cfilter = g_strdup(interface_opts.cfilter);
+    } else {
 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-    device.buffer = global_capture_opts.default_options.buffer_size;
+      row.buffer = global_capture_opts.default_options.buffer_size;
 #endif
-    device.pmode = global_capture_opts.default_options.promisc_mode;
-    device.has_snaplen = global_capture_opts.default_options.has_snaplen;
-    device.snaplen = global_capture_opts.default_options.snaplen;
-    device.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
+      row.pmode = global_capture_opts.default_options.promisc_mode;
+      row.has_snaplen = global_capture_opts.default_options.has_snaplen;
+      row.snaplen = global_capture_opts.default_options.snaplen;
+      row.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
+    }
     cap_settings = capture_get_cap_settings(if_string);
-    caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, NULL);
+    caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode,
+                                       &err_str);
+    if (caps == NULL) {
+      /* Error attempting to get interface capabilities. */
+      if (cap_settings.monitor_mode) {
+        /*
+         * Perhaps this is the libpcap bug on Linux where
+         * attempting to set monitor mode with the Wireless
+         * Extensions ioctls doesn't work correctly.
+         *
+         * Try fetching the capabilities without monitor mode;
+         * if that succeeds, report the monitor-mode problem,
+         * and use the no-monitor-mode capabilities.  If that
+         * fails, report that failure.  In either case, force
+         * monitor mode off.
+         */
+        cap_settings.monitor_mode = FALSE;
+        caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode,
+                                           &err_str_norfmon);
+        if (caps == NULL) {
+          /* Epic fail. */
+          simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str_norfmon);
+          g_free(err_str_norfmon);
+          g_free(err_str);
+        } else {
+          /*
+           * OK, it's probably that bug.  Suggest using airmon-ng,
+           * just in case the adapter has a mac80211 driver and
+           * libpcap was built without libnl so that it can't
+           * use the mac80211 features to create a monitor-mode
+           * device.
+           */
+          simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                        "%s\n\n"
+                        "Try using airmon-ng, as suggested by CaptureSetup/WLAN in the Wireshark Wiki.",
+                        err_str);
+          g_free(err_str);
+        }
+      } else {
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
+        g_free(err_str);
+      }
+    }
+
     gtk_list_store_append (GTK_LIST_STORE(model), &iter);
     for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
       if (ips != 0) {
@@ -890,11 +959,11 @@ insert_new_rows(GList *list)
       }
     } /* for curr_addr */
     linktype_count = 0;
-    device.links = NULL;
+    row.links = NULL;
     if (caps != NULL) {
 #ifdef HAVE_PCAP_CREATE
-      device.monitor_mode_enabled = cap_settings.monitor_mode;
-      device.monitor_mode_supported = caps->can_set_rfmon;
+      row.monitor_mode_enabled = cap_settings.monitor_mode;
+      row.monitor_mode_supported = caps->can_set_rfmon;
 #endif
       for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
         data_link_info = (data_link_info_t *)lt_entry->data;
@@ -905,69 +974,68 @@ insert_new_rows(GList *list)
         }
         if (linktype_count == 0) {
           link_type_name = g_strdup(str);
-          device.active_dlt = data_link_info->dlt;
+          row.active_dlt = data_link_info->dlt;
         }
         link = (link_row *)g_malloc(sizeof(link_row));
         link->dlt = data_link_info->dlt;
         link->name = g_strdup(str);
-        device.links = g_list_append(device.links, link);
+        row.links = g_list_append(row.links, link);
         linktype_count++;
       } /* for link_types */
     } else {
       cap_settings.monitor_mode = FALSE;
 #if defined(HAVE_PCAP_CREATE)
-      device.monitor_mode_enabled = FALSE;
-      device.monitor_mode_supported = FALSE;
+      row.monitor_mode_enabled = FALSE;
+      row.monitor_mode_supported = FALSE;
 #endif
-      device.active_dlt = -1;
+      row.active_dlt = -1;
       link_type_name = g_strdup("default");
     }
-    device.addresses = g_strdup(ip_str->str);
-    device.no_addresses = ips;
+    row.addresses = g_strdup(ip_str->str);
+    row.no_addresses = ips;
     if (ips == 0) {
-      temp = g_strdup_printf("<b>%s</b>", device.display_name);
+      temp = g_strdup_printf("<b>%s</b>", row.display_name);
     } else {
-      temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", device.display_name, device.addresses);
+      temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", row.display_name, row.addresses);
     }
 #ifdef HAVE_PCAP_REMOTE
-    device.remote_opts.src_type= global_remote_opts.src_type;
-    device.remote_opts.remote_host_opts.remote_host = g_strdup(global_remote_opts.remote_host_opts.remote_host);
-    device.remote_opts.remote_host_opts.remote_port = g_strdup(global_remote_opts.remote_host_opts.remote_port);
-    device.remote_opts.remote_host_opts.auth_type = global_remote_opts.remote_host_opts.auth_type;
-    device.remote_opts.remote_host_opts.auth_username = g_strdup(global_remote_opts.remote_host_opts.auth_username);
-    device.remote_opts.remote_host_opts.auth_password = g_strdup(global_remote_opts.remote_host_opts.auth_password);
-    device.remote_opts.remote_host_opts.datatx_udp = global_remote_opts.remote_host_opts.datatx_udp;
-    device.remote_opts.remote_host_opts.nocap_rpcap = global_remote_opts.remote_host_opts.nocap_rpcap;
-    device.remote_opts.remote_host_opts.nocap_local = global_remote_opts.remote_host_opts.nocap_local;
+    row.remote_opts.src_type= global_remote_opts.src_type;
+    row.remote_opts.remote_host_opts.remote_host = g_strdup(global_remote_opts.remote_host_opts.remote_host);
+    row.remote_opts.remote_host_opts.remote_port = g_strdup(global_remote_opts.remote_host_opts.remote_port);
+    row.remote_opts.remote_host_opts.auth_type = global_remote_opts.remote_host_opts.auth_type;
+    row.remote_opts.remote_host_opts.auth_username = g_strdup(global_remote_opts.remote_host_opts.auth_username);
+    row.remote_opts.remote_host_opts.auth_password = g_strdup(global_remote_opts.remote_host_opts.auth_password);
+    row.remote_opts.remote_host_opts.datatx_udp = global_remote_opts.remote_host_opts.datatx_udp;
+    row.remote_opts.remote_host_opts.nocap_rpcap = global_remote_opts.remote_host_opts.nocap_rpcap;
+    row.remote_opts.remote_host_opts.nocap_local = global_remote_opts.remote_host_opts.nocap_local;
 #endif
 #ifdef HAVE_PCAP_SETSAMPLING
-    device.remote_opts.sampling_method = global_remote_opts.sampling_method;
-    device.remote_opts.sampling_param = global_remote_opts.sampling_param;
+    row.remote_opts.sampling_method = global_remote_opts.sampling_method;
+    row.remote_opts.sampling_param = global_remote_opts.sampling_param;
 #endif
-    g_array_append_val(global_capture_opts.all_ifaces, device);
-    if (device.has_snaplen) {
-      snaplen_string = g_strdup_printf("%d", device.snaplen);
+    g_array_append_val(rows, row);
+    if (row.has_snaplen) {
+      snaplen_string = g_strdup_printf("%d", row.snaplen);
     } else {
       snaplen_string = g_strdup("default");
     }
 
 #if defined(HAVE_PCAP_CREATE)
-    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, MONITOR, "no",FILTER, "",-1);
+    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, MONITOR, "no",FILTER, "",-1);
 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
-    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, FILTER, "",-1);
+    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, FILTER, "",-1);
  #else
-    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, -1);
+    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, -1);
 #endif
+    count++;
     g_string_free(ip_str, TRUE);
 #ifdef HAVE_PCAP_REMOTE
-    add_interface_to_list(global_capture_opts.all_ifaces->len-1);
+    add_interface_to_list(if_info->name, if_info->description, &row.remote_opts);
 #endif
   } /*for*/
   gtk_tree_view_set_model(GTK_TREE_VIEW(if_cb), model);
 }
-#endif
 
-#ifdef HAVE_PCAP_REMOTE
 /* Retrieve the list of local or remote interfaces according to selected
  * options and re-fill interface name combobox */
 static void
@@ -1288,19 +1356,19 @@ options_remote_ok_cb(GtkWidget *win _U_, GtkWidget *parent_w)
   GtkWidget *samp_none_rb, *samp_count_rb, *samp_timer_rb,
             *samp_count_sb, *samp_timer_sb;
 #endif
-  interface_t device;
+  interface_row row;
 
   if (parent_w == NULL)
     return;
 
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
-  g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
+  row = g_array_index(rows, interface_row, marked_row);
+  g_array_remove_index(rows, marked_row);
   datatx_udp_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_DATATX_UDP_CB_KEY);
   nocap_rpcap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_NOCAP_RPCAP_CB_KEY);
 
-  device.remote_opts.remote_host_opts.datatx_udp =
+  row.remote_opts.remote_host_opts.datatx_udp =
     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(datatx_udp_cb));
-  device.remote_opts.remote_host_opts.nocap_rpcap =
+  row.remote_opts.remote_host_opts.nocap_rpcap =
     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb));
 
 #ifdef HAVE_PCAP_SETSAMPLING
@@ -1311,16 +1379,16 @@ options_remote_ok_cb(GtkWidget *win _U_, GtkWidget *parent_w)
   samp_timer_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_SB_KEY);
 
   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_none_rb)))
-    device.remote_opts.sampling_method = CAPTURE_SAMP_NONE;
+    row.remote_opts.sampling_method = CAPTURE_SAMP_NONE;
   else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb))) {
-    device.remote_opts.sampling_method = CAPTURE_SAMP_BY_COUNT;
-    device.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_count_sb));
+    row.remote_opts.sampling_method = CAPTURE_SAMP_BY_COUNT;
+    row.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_count_sb));
   } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb))) {
-    device.remote_opts.sampling_method = CAPTURE_SAMP_BY_TIMER;
-    device.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_timer_sb));
+    row.remote_opts.sampling_method = CAPTURE_SAMP_BY_TIMER;
+    row.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_timer_sb));
   }
 #endif /* HAVE_PCAP_SETSAMPLING*/
-  g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
+  g_array_insert_val(rows, marked_row, row);
   window_destroy(GTK_WIDGET(parent_w));
 }
 #endif /*HAVE_PCAP_REMOTE*/
@@ -1362,7 +1430,7 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
   GtkAdjustment *samp_count_adj, *samp_timer_adj;
   GSList        *samp_group;
 #endif
-  interface_t device;
+  interface_row row;
 
   caller = gtk_widget_get_toplevel(w);
   opt_remote_w = g_object_get_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY);
@@ -1371,7 +1439,7 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
     return;
   }
 
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
+  row = g_array_index(rows, interface_row, marked_row);
   opt_remote_w = dlg_window_new("Remote Capture Settings");
   g_object_set_data(G_OBJECT(opt_remote_w), E_OPT_REMOTE_CALLER_PTR_KEY, caller);
   g_object_set_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY, opt_remote_w);
@@ -1390,12 +1458,12 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
 
   nocap_rpcap_cb = gtk_check_button_new_with_mnemonic("Do not capture own RPCAP traffic");
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb),
-          device.remote_opts.remote_host_opts.nocap_rpcap);
+          row.remote_opts.remote_host_opts.nocap_rpcap);
   gtk_container_add(GTK_CONTAINER(capture_vb), nocap_rpcap_cb);
 
   datatx_udp_cb = gtk_check_button_new_with_mnemonic("Use UDP for data transfer");
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(datatx_udp_cb),
-          device.remote_opts.remote_host_opts.datatx_udp);
+          row.remote_opts.remote_host_opts.datatx_udp);
   gtk_container_add(GTK_CONTAINER(capture_vb), datatx_udp_cb);
 
 #ifdef HAVE_PCAP_SETSAMPLING
@@ -1414,7 +1482,7 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
 
   /* "No sampling" row */
   samp_none_rb = gtk_radio_button_new_with_label(NULL, "None");
-  if (device.remote_opts.sampling_method == CAPTURE_SAMP_NONE)
+  if (row.remote_opts.sampling_method == CAPTURE_SAMP_NONE)
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_none_rb), TRUE);
   g_signal_connect(samp_none_rb, "toggled",
                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
@@ -1423,14 +1491,14 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
   /* "Sampling by counter" row */
   samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_none_rb));
   samp_count_rb = gtk_radio_button_new_with_label(samp_group, "1 of");
-  if (device.remote_opts.sampling_method == CAPTURE_SAMP_BY_COUNT)
+  if (row.remote_opts.sampling_method == CAPTURE_SAMP_BY_COUNT)
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_count_rb), TRUE);
   g_signal_connect(samp_count_rb, "toggled",
                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_count_rb, 0, 1, 1, 2);
 
   samp_count_adj = (GtkAdjustment *) gtk_adjustment_new(
-                        (gfloat)device.remote_opts.sampling_param,
+                        (gfloat)row.remote_opts.sampling_param,
                         1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
   samp_count_sb = gtk_spin_button_new(samp_count_adj, 0, 0);
   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_count_sb), TRUE);
@@ -1443,14 +1511,14 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
   /* "Sampling by timer" row */
   samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_count_rb));
   samp_timer_rb = gtk_radio_button_new_with_label(samp_group, "1 every");
-  if (device.remote_opts.sampling_method == CAPTURE_SAMP_BY_TIMER)
+  if (row.remote_opts.sampling_method == CAPTURE_SAMP_BY_TIMER)
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_timer_rb), TRUE);
   g_signal_connect(samp_timer_rb, "toggled",
                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_timer_rb, 0, 1, 2, 3);
 
   samp_timer_adj = (GtkAdjustment *) gtk_adjustment_new(
-                        (gfloat)device.remote_opts.sampling_param,
+                        (gfloat)row.remote_opts.sampling_param,
                         1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
   samp_timer_sb = gtk_spin_button_new(samp_timer_adj, 0, 0);
   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_timer_sb), TRUE);
@@ -1641,83 +1709,131 @@ options_edit_destroy_cb(GtkWidget *win, gpointer user_data _U_)
 static void
 update_options_table(gint index)
 {
-  interface_t  device;
+  guint i;
+  gboolean found = FALSE;
+  interface_row row;
+  interface_options interface_opts;
   GtkTreePath  *path;
   GtkTreeView  *if_cb;
   GtkTreeModel *model;
   GtkTreeIter  iter;
-  gchar *temp, *path_str, *snaplen_string, *linkname="";
+  gchar *temp, *path_str, *snaplen_string;
   GList *list;
   link_row *link = NULL;
   gboolean enabled;
 
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
+  row = g_array_index(rows, interface_row, index);
 
-  if (!device.hidden) {
-    if (device.no_addresses == 0) {
-      temp = g_strdup_printf("<b>%s</b>", device.display_name);
-    } else {
-      temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", device.display_name, device.addresses);
-    }
-    for (list=device.links; list!=NULL; list=g_list_next(list))
-    {
-      link = (link_row*)(list->data);
-      linkname = g_strdup(link->name); 
-      if (link->dlt == device.active_dlt) {
+  if (global_capture_opts.ifaces->len > 0) {
+    for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+      interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
+      if (strcmp(interface_opts.name, row.name) == 0) {
+        found = TRUE;
         break;
       }
     }
-    if (device.has_snaplen) {
-      snaplen_string = g_strdup_printf("%d", device.snaplen);
-    } else {
-      snaplen_string = g_strdup("default");
+    if (found) {
+      global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
+      g_free(interface_opts.cfilter);
+      interface_opts.linktype = row.active_dlt;
+      interface_opts.promisc_mode = row.pmode;
+      interface_opts.has_snaplen = row.has_snaplen;
+      interface_opts.snaplen = row.snaplen;
+      interface_opts.cfilter = g_strdup(row.cfilter);
+#ifdef HAVE_PCAP_CREATE
+      interface_opts.monitor_mode = row.monitor_mode_enabled;
+#else
+      interface_opts.monitor_mode = FALSE;
+#endif
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+      interface_opts.buffer_size = row.buffer;
+#endif
+      g_array_insert_val(global_capture_opts.ifaces, i, interface_opts);
     }
-    if (cap_open_w) {
-      if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
-      path_str = g_strdup_printf("%d", index);
-      path = gtk_tree_path_new_from_string(path_str);
-      model = gtk_tree_view_get_model(if_cb);
-      gtk_tree_model_get(model, &iter, CAPTURE, &enabled, -1);
-      if (enabled == FALSE) {
-        device.selected = TRUE;
-        global_capture_opts.num_selected++;
-        global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
-        g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
-      }
-  #if defined(HAVE_PCAP_CREATE)
-      gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname,  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, MONITOR, device.monitor_mode_supported?(device.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, device.cfilter, -1);
-  #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
-      gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, linkname,  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, FILTER, device.cfilter, -1);
-  #else
-      gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, linkname,  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, device.cfilter, -1);
-  #endif
-      if (global_capture_opts.num_selected > 0) {
-        gtk_widget_set_sensitive(ok_bt, TRUE);
-      } else {
-        gtk_widget_set_sensitive(ok_bt, FALSE);
-      }
-      gtk_tree_path_free (path);
+  }
+  if (!found || global_capture_opts.ifaces->len == 0) {
+    interface_opts.name = g_strdup(row.name);
+    interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
+    interface_opts.linktype = row.active_dlt;
+    interface_opts.promisc_mode = row.pmode;
+    interface_opts.has_snaplen = row.has_snaplen;
+    interface_opts.snaplen = row.snaplen;
+    interface_opts.cfilter = g_strdup(row.cfilter);
+#ifdef HAVE_PCAP_CREATE
+    interface_opts.monitor_mode = row.monitor_mode_enabled;
+#else
+    interface_opts.monitor_mode = FALSE;
+#endif
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+    interface_opts.buffer_size = row.buffer;
+#endif
+#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 (row.no_addresses == 0) {
+    temp = g_strdup_printf("<b>%s</b>", row.display_name);
+  } else {
+    temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", row.display_name, row.addresses);
+  }
+  for (list=row.links; list!=NULL; list=g_list_next(list))
+  {
+    link = (link_row*)(list->data);
+    if (link->dlt == row.active_dlt) {
+      break;
     }
-    if (interfaces_dialog_window_present()) {
-      update_selected_interface(g_strdup(device.name));
+  }
+  if (row.has_snaplen) {
+    snaplen_string = g_strdup_printf("%d", row.snaplen);
+  } else {
+    snaplen_string = g_strdup("default");
+  }
+  if (cap_open_w) {
+    if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
+    path_str = g_strdup_printf("%d", marked_row);
+    path = gtk_tree_path_new_from_string(path_str);
+    model = gtk_tree_view_get_model(if_cb);
+    gtk_tree_model_get_iter (model, &iter, path);
+    gtk_tree_model_get(model, &iter, CAPTURE, &enabled, -1);
+    if (enabled == FALSE) {
+      num_selected++;
     }
-    if (get_welcome_window() != NULL) {
-      change_interface_selection(g_strdup(device.name), device.selected);
+
+#if defined(HAVE_PCAP_CREATE)
+    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, MONITOR, row.monitor_mode_supported?(row.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, row.cfilter, -1);
+#elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
+    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp,LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, FILTER, row.cfilter, -1);
+#else
+    gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp,LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, row.cfilter, -1);
+#endif
+    if (num_selected > 0) {
+      gtk_widget_set_sensitive(ok_bt, TRUE);
+    } else {
+      gtk_widget_set_sensitive(ok_bt, FALSE);
     }
+    gtk_tree_path_free (path);
+  }
+  if (interfaces_dialog_window_present()) {
+    update_selected_interface(g_strdup(row.name), TRUE);
+  }
+  if (get_welcome_window() != NULL) {
+    change_interface_selection(g_strdup(row.name), TRUE);
   }
 }
 
-
-void
-update_all_rows(void) 
-{
-    GtkTreeView *view;
-  
-    view = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
-    create_and_fill_model(GTK_TREE_VIEW(view));
-}
-
-
 static void
 save_options_cb(GtkWidget *win _U_, gpointer user_data _U_)
 {
@@ -1730,13 +1846,13 @@ save_options_cb(GtkWidget *win _U_, gpointer user_data _U_)
   GtkWidget *buffer_size_sb;
 #endif
 
-  interface_t device;
+  interface_row row;
   gpointer  ptr;
   int       dlt;
   const gchar *filter_text;
-  
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
-  global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
+
+  row = g_array_index(rows, interface_row, marked_row);
+  rows = g_array_remove_index(rows, marked_row);
   snap_cb    = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY);
   snap_sb    = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY);
 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
@@ -1750,36 +1866,37 @@ save_options_cb(GtkWidget *win _U_, gpointer user_data _U_)
 
   linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
 
-  if (device.links != NULL && !ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
+  if (ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
     g_assert_not_reached();  /* Programming error: somehow nothing is active */
   }
-  if ((dlt = GPOINTER_TO_INT(ptr)) == -1 && device.links != NULL) {
+  if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
   }
-  device.active_dlt = dlt;
+  row.active_dlt = dlt;
 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-  device.buffer = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb));
-#endif
-  device.pmode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
-  device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
-  if (device.has_snaplen) {
-    device.snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
-    if (device.snaplen < 1)
-      device.snaplen = WTAP_MAX_PACKET_SIZE;
-    else if (device.snaplen < MIN_PACKET_SIZE)
-      device.snaplen = MIN_PACKET_SIZE;
+  row.buffer = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb));
+#endif
+  row.pmode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
+  row.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
+  if (row.has_snaplen) {
+    row.snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
+    if (row.snaplen < 1)
+      row.snaplen = WTAP_MAX_PACKET_SIZE;
+    else if (row.snaplen < MIN_PACKET_SIZE)
+      row.snaplen = MIN_PACKET_SIZE;
   } else {
-    device.snaplen = WTAP_MAX_PACKET_SIZE;
+    row.snaplen = WTAP_MAX_PACKET_SIZE;
   }
+
   filter_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(filter_cm));
-  if (device.cfilter)
-    g_free(device.cfilter);
+  if (row.cfilter)
+    g_free(row.cfilter);
   g_assert(filter_text != NULL);
-  device.cfilter = g_strdup(filter_text);
+  row.cfilter = g_strdup(filter_text);
 #ifdef HAVE_PCAP_CREATE
-  device.monitor_mode_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb));
+  row.monitor_mode_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb));
 #endif
-  g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
+  g_array_insert_val(rows, marked_row, row);
   window_destroy(opt_edit_w);
   update_options_table(marked_row);
 }
@@ -1788,10 +1905,10 @@ static void
 adjust_snap_sensitivity(GtkWidget *tb _U_, gpointer parent_w _U_)
 {
   GtkWidget *snap_cb, *snap_sb;
-  interface_t device;
+  interface_row row;
 
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
-  global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
+  row = g_array_index(rows, interface_row, marked_row);
+  rows = g_array_remove_index(rows, marked_row);
 
   snap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY);
   snap_sb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY);
@@ -1800,13 +1917,13 @@ adjust_snap_sensitivity(GtkWidget *tb _U_, gpointer parent_w _U_)
      to" checkbox is on. */
   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
-  device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
-  g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
+  row.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
+  g_array_insert_val(rows, marked_row, row);
 }
 
 void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column _U_, gpointer userdata)
 {
-  GtkWidget     *caller, *window, *swindow=NULL, *if_view,
+  GtkWidget     *caller, *window, *swindow=NULL,
                 *main_vb, *if_hb, *if_lb, *if_lb_name,
                 *main_hb, *left_vb,
 #if defined (HAVE_AIRPCAP) || defined (HAVE_PCAP_REMOTE) || defined (HAVE_PCAP_CREATE)
@@ -1839,60 +1956,61 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
  #ifdef HAVE_AIRPCAP
   GtkWidget     *advanced_bt;
 #endif
-  interface_t   device;
+  interface_row row;
+  displayed_interface d_interface;
   GtkTreeModel  *model;
   GtkTreeIter   iter;
   link_row      *temp;
   gboolean      found = FALSE;
   gint          num_supported_link_types;
   guint         i;
-  gchar         *tok, *name;
-  GtkCellRenderer *renderer;
-  GtkListStore    *store;
+  gchar         *tok;
 
   window = (GtkWidget *)userdata;
   caller = gtk_widget_get_toplevel(GTK_WIDGET(window));
-  opt_edit_w = g_object_get_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY);
+  opt_edit_w = (GtkWidget *)g_object_get_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY);
   if (opt_edit_w != NULL) {
     reactivate_window(opt_edit_w);
     return;
   }
 
-  device.name = NULL;
-  device.display_name = NULL;
-  device.no_addresses = 0;
-  device.addresses = NULL;
-  device.links = NULL;
-  device.active_dlt = -1;
-  device.pmode = FALSE;
+  row.name = NULL;
+  row.display_name = NULL;
+  row.no_addresses = 0;
+  row.addresses = NULL;
+  row.links = NULL;
+  row.active_dlt = -1;
+  row.pmode = FALSE;
 #ifdef HAVE_PCAP_CREATE
-  device.monitor_mode_enabled = FALSE;
-  device.monitor_mode_supported = FALSE;
+  row.monitor_mode_enabled = FALSE;
+  row.monitor_mode_supported = FALSE;
 #endif
-  device.has_snaplen = FALSE;
-  device.snaplen = 65535;
-  device.cfilter = NULL;
+  row.has_snaplen = FALSE;
+  row.snaplen = 65535;
+  row.cfilter = NULL;
 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-  device.buffer = 1;
+  row.buffer = 1;
 #endif
 
   model = gtk_tree_view_get_model(view);
   gtk_tree_model_get_iter (model, &iter, path);
-  
-  if (window == get_welcome_window()) {
-    gtk_tree_model_get(model, &iter, IFACE_NAME, &name, -1);
-  } else if (window == cap_open_w) {
-    gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &name, -1);
-  }
-  
-  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(device.name, name) == 0) {
-      marked_interface = i;
-      break;
+  marked_row = atoi(gtk_tree_path_to_string(path));
+
+  if (cap_open_w) {
+    row = g_array_index(rows, interface_row, marked_row);
+  } else if (get_welcome_window() != NULL) {
+    d_interface = get_interface_data(marked_row);
+    if (!rows || rows->len == 0) {
+      make_and_fill_rows();
+    }
+    for (i = 0; i < rows->len; i++) {
+     row = g_array_index(rows, interface_row, i);
+     if (strcmp(row.name, (char*)d_interface.name)==0) {
+       marked_row = i;
+       break;
+     }
     }
   }
-  marked_row = atoi(gtk_tree_path_to_string(path));
   opt_edit_w = dlg_window_new("Edit Interface Settings");
   g_object_set_data(G_OBJECT(opt_edit_w), E_OPT_EDIT_CALLER_PTR_KEY, caller);
   g_object_set_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY, opt_edit_w);
@@ -1916,7 +2034,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   if_lb = gtk_label_new("Interface:  ");
   gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 3);
 
-  if_lb_name = gtk_label_new(device.display_name);
+  if_lb_name = gtk_label_new(row.display_name);
   gtk_box_pack_start(GTK_BOX(if_hb), if_lb_name, FALSE, FALSE, 3);
 
   /* IP addresses row */
@@ -1931,29 +2049,22 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   if_ip_lb = gtk_label_new("IP address:");
   gtk_misc_set_alignment(GTK_MISC(if_ip_lb), 0, 0); /* Left justified */
   gtk_box_pack_start(GTK_BOX(if_vb_left), if_ip_lb, FALSE, FALSE, 0);
-  if (device.no_addresses > 0) {
-    gchar *temp_addresses = g_strdup(device.addresses);
+
+  if (row.no_addresses > 0) {
+    GtkWidget *if_ip_list = gtk_vbox_new(FALSE, 0);
+    gchar *temp_addresses = g_strdup(row.addresses);
     gtk_box_pack_start(GTK_BOX(capture_vb), if_ip_hb, TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, TRUE, TRUE, 3);
+    gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, TRUE, TRUE, 0);
     swindow = gtk_scrolled_window_new (NULL, NULL);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_NONE);
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_widget_set_size_request(GTK_WIDGET(swindow),-1, 50);
-    if_view = gtk_tree_view_new ();
-    g_object_set(G_OBJECT(if_view), "headers-visible", FALSE, NULL);
-    renderer = gtk_cell_renderer_text_new();
-    column = gtk_tree_view_column_new_with_attributes ("",
-                    GTK_CELL_RENDERER(renderer),
-                    "text", 0,
-                    NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
-    store = gtk_list_store_new(1, G_TYPE_STRING);
+    gtk_widget_set_size_request(GTK_WIDGET(swindow), -1, 50);
     for (tok = strtok (temp_addresses, "\n"); tok; tok = strtok(NULL, "\n")) {
-      gtk_list_store_append (store, &iter);
-      gtk_list_store_set (store, &iter, 0, tok, -1);
+      if_ip_name = gtk_label_new(tok);
+      gtk_misc_set_alignment(GTK_MISC(if_ip_name), 0, 0); /* Left justified */
+      gtk_box_pack_start(GTK_BOX(if_ip_list), if_ip_name, FALSE, FALSE, 3);
     }
-    gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store));
-    gtk_container_add (GTK_CONTAINER (swindow), if_view);
+    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(swindow), if_ip_list);
     gtk_box_pack_start(GTK_BOX(if_vb_right), swindow, TRUE, TRUE, 0);
     g_free(temp_addresses);
   } else {
@@ -2013,7 +2124,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_combo_box, FALSE, FALSE, 0);
   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY, linktype_combo_box);
   num_supported_link_types = 0;
-  for (list=device.links; list!=NULL; list=g_list_next(list))
+  for (list=row.links; list!=NULL; list=g_list_next(list))
   {
     temp = (link_row*)(list->data);
     ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box),
@@ -2021,7 +2132,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
                                                   GINT_TO_POINTER(temp->dlt)  /* Flag as "not supported" */
                                                   );
     num_supported_link_types++;
-    if (temp->dlt == device.active_dlt) {
+    if (temp->dlt == row.active_dlt) {
       ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box), num_supported_link_types - 1);
       found = TRUE;
     }
@@ -2037,7 +2148,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   promisc_cb = gtk_check_button_new_with_mnemonic(
       "Capture packets in _promiscuous mode");
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb),
-                               device.pmode);
+                               row.pmode);
   gtk_widget_set_tooltip_text(promisc_cb,
     "Usually a network adapter will only capture the traffic sent to its own network address. "
     "If you want to capture all traffic that the network adapter can \"see\", mark this option. "
@@ -2048,8 +2159,8 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
 #ifdef HAVE_PCAP_CREATE
   /* Monitor mode row */
   monitor_cb = gtk_check_button_new_with_mnemonic( "Capture packets in monitor mode");
-  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor_cb), device.monitor_mode_enabled);
-  gtk_widget_set_sensitive(monitor_cb, device.monitor_mode_supported);
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor_cb), row.monitor_mode_enabled);
+  gtk_widget_set_sensitive(monitor_cb, row.monitor_mode_supported);
   g_signal_connect(monitor_cb, "toggled", G_CALLBACK(capture_prep_monitor_changed_cb), NULL);
 
   gtk_widget_set_tooltip_text(monitor_cb,
@@ -2075,14 +2186,14 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
 
   snap_cb = gtk_check_button_new_with_mnemonic("_Limit each packet to");
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(snap_cb),
-                               device.has_snaplen);
+                               row.has_snaplen);
   g_signal_connect(snap_cb, "toggled", G_CALLBACK(adjust_snap_sensitivity), NULL);
   gtk_widget_set_tooltip_text(snap_cb,
     "Limit the maximum number of bytes to be captured from each packet. This size includes the "
     "link-layer header and all subsequent headers. ");
   gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
 
-  snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) device.snaplen,
+  snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) row.snaplen,
     MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
   snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
@@ -2094,7 +2205,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   snap_lb = gtk_label_new("bytes");
   gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5f);
   gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
-  gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), device.has_snaplen);
+  gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), row.has_snaplen);
 
   /* Filter row */
   filter_hb = gtk_hbox_new(FALSE, 3);
@@ -2127,8 +2238,8 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   if (global_capture_opts.default_options.cfilter && (strlen(global_capture_opts.default_options.cfilter) > 0)) {
     gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), global_capture_opts.default_options.cfilter);
   }
-  if (device.cfilter && (strlen(device.cfilter) > 0)) {
-    gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), device.cfilter);
+  if (row.cfilter && (strlen(row.cfilter) > 0)) {
+    gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), row.cfilter);
     gtk_combo_box_set_active(GTK_COMBO_BOX(filter_cm), 0);
   }
 
@@ -2155,10 +2266,10 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   buffer_size_lb = gtk_label_new("Buffer size:");
   gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_lb, FALSE, FALSE, 0);
 
-  buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) device.buffer,
+  buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) row.buffer,
     1, 65535, 1.0, 10.0, 0.0);
   buffer_size_sb = gtk_spin_button_new (buffer_size_adj, 0, 0);
-  gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) device.buffer);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) row.buffer);
   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (buffer_size_sb), TRUE);
   gtk_widget_set_size_request(buffer_size_sb, 80, -1);
   gtk_widget_set_tooltip_text(buffer_size_sb,
@@ -2182,7 +2293,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   /* Both the callback and the data are global */
   g_signal_connect(remote_bt, "clicked", G_CALLBACK(options_remote_cb), NULL);
   g_object_set_data(G_OBJECT(opt_edit_w), E_OPT_REMOTE_BT_KEY, remote_bt);
-  if (strncmp (device.name, "rpcap://", 8) == 0)  {
+  if (strncmp (row.name, "rpcap://", 8) == 0)  {
     gtk_widget_set_sensitive(remote_bt, TRUE);
   } else {
     gtk_widget_set_sensitive(remote_bt, FALSE);
@@ -2197,7 +2308,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   /* Both the callback and the data are global */
   g_signal_connect(advanced_bt,"clicked", G_CALLBACK(options_airpcap_advanced_cb), airpcap_tb);
   g_object_set_data(G_OBJECT(top_level),AIRPCAP_OPTIONS_ADVANCED_KEY, advanced_bt);
-  airpcap_if_selected = get_airpcap_if_from_name(airpcap_if_list, device.name);
+  airpcap_if_selected = get_airpcap_if_from_name(airpcap_if_list, row.name);
   if (airpcap_if_selected != NULL) {
     /* It is an airpcap interface */
     gtk_widget_set_sensitive(advanced_bt, TRUE);
@@ -2213,7 +2324,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
 
-  ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
+  ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
   g_signal_connect(ok_bt, "clicked", G_CALLBACK(save_options_cb), NULL);
   gtk_widget_set_tooltip_text(ok_bt,
     "Accept interface settings.");
@@ -2227,6 +2338,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum
   g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_CAPTURE_OPTIONS_DIALOG);
   gtk_widget_grab_default(ok_bt);
   dlg_set_activate(filter_te, ok_bt);
+  gtk_widget_grab_focus(filter_te);
   g_signal_connect(opt_edit_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
   g_signal_connect(opt_edit_w, "destroy", G_CALLBACK(options_edit_destroy_cb), NULL);
   gtk_widget_show_all(opt_edit_w);
@@ -2242,87 +2354,191 @@ static void toggle_callback(GtkCellRendererToggle *cell _U_,
   GtkTreeView  *if_cb;
   GtkTreeModel *model;
   GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
-  gboolean enabled;
+  gboolean enabled, found = FALSE;
   GtkWidget *pcap_ng_cb;
-  interface_t device;
-  gchar *name;
-  gint index = -1;
+  interface_options interface_opts;
+  interface_row row;
+  int index = atoi(path_str);
   guint i;
 
   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
   model = gtk_tree_view_get_model(if_cb);
   gtk_tree_model_get_iter (model, &iter, path);
-  gtk_tree_model_get (model, &iter, CAPTURE, &enabled, IFACE_HIDDEN_NAME, &name, -1);
-  /* Look for the right interface. The number of interfaces shown might be less 
-   * than the real number. Therefore the path index does not correspond 
-   * necessarily to the position in the list */
-  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(device.name, name) == 0) {
-      index = i;
-      break;
-    }
+  gtk_tree_model_get (model, &iter, CAPTURE, &enabled, -1);
+  row = g_array_index(rows, interface_row, index);
+  if (enabled == FALSE)
+    num_selected++;
+  else
+    num_selected--;
+  enabled ^= 1;
+  pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY);
+  if (num_selected >= 2) {
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE);
+    gtk_widget_set_sensitive(pcap_ng_cb, FALSE);
+  } else {
+    gtk_widget_set_sensitive(pcap_ng_cb, TRUE);
   }
-  if (!device.locked) {
-    if (enabled == FALSE) {
-      device.selected = TRUE;
-      global_capture_opts.num_selected++;
-    } else {
-      device.selected = FALSE;
-      global_capture_opts.num_selected--;
+  if (num_selected > 0) {
+    gtk_widget_set_sensitive(ok_bt, TRUE);
+  } else {
+    gtk_widget_set_sensitive(ok_bt, FALSE);
+  }
+  /* do something with the new enabled value, and set the new
+     enabled value in your treemodel */
+  gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enabled, -1);
+
+  if (global_capture_opts.ifaces->len > 0) {
+    for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+      interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
+      if (strcmp(interface_opts.name, row.name) == 0) {
+        found = TRUE;
+        break;
+      }
     }
-    device.locked = TRUE;
-  }
-  if (index != -1) {
-    global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, index);
-    g_array_insert_val(global_capture_opts.all_ifaces, index, device);
-    pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY);
-    if (global_capture_opts.num_selected >= 2) {
-      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE);
-      gtk_widget_set_sensitive(pcap_ng_cb, FALSE);
-    } else {
-      gtk_widget_set_sensitive(pcap_ng_cb, TRUE);
+    if (found) {
+      global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
+      g_free(interface_opts.cfilter);
+      if (enabled) {
+        interface_opts.linktype = row.active_dlt;
+        interface_opts.promisc_mode = row.pmode;
+        interface_opts.has_snaplen = row.has_snaplen;
+        interface_opts.snaplen = row.snaplen;
+        interface_opts.cfilter = g_strdup(row.cfilter);
+#ifdef HAVE_PCAP_CREATE
+        interface_opts.monitor_mode = row.monitor_mode_enabled;
+#else
+        interface_opts.monitor_mode = FALSE;
+#endif
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+        interface_opts.buffer_size = row.buffer;
+#endif
+#ifdef HAVE_PCAP_REMOTE
+        interface_opts.src_type = row.remote_opts.src_type;
+        if (interface_opts.src_type == CAPTURE_IFREMOTE) {
+          interface_opts.remote_host = g_strdup(row.remote_opts.remote_host_opts.remote_host);
+          interface_opts.remote_port = g_strdup(row.remote_opts.remote_host_opts.remote_port);
+          interface_opts.auth_type = row.remote_opts.remote_host_opts.auth_type;
+          interface_opts.auth_username = g_strdup(row.remote_opts.remote_host_opts.auth_username);
+          interface_opts.auth_password = g_strdup(row.remote_opts.remote_host_opts.auth_password);
+          interface_opts.datatx_udp = row.remote_opts.remote_host_opts.datatx_udp;
+          interface_opts.nocap_rpcap = row.remote_opts.remote_host_opts.nocap_rpcap;
+          interface_opts.nocap_local = row.remote_opts.remote_host_opts.nocap_local;
+#ifdef HAVE_PCAP_SETSAMPLING
+          interface_opts.sampling_method = row.remote_opts.sampling_method;
+          interface_opts.sampling_param  = row.remote_opts.sampling_param;
+#endif
+        } else {
+          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;
+#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
+        }
+#endif
+        g_array_insert_val(global_capture_opts.ifaces, i, interface_opts);
+      } else { /* not enabled */
+        if (interfaces_dialog_window_present()) {
+          update_selected_interface(g_strdup(interface_opts.name), FALSE);
+        }
+        if (get_welcome_window() != NULL) {
+          change_interface_selection(g_strdup(interface_opts.name), FALSE);
+        }
+      }
     }
-    if (global_capture_opts.num_selected > 0) {
-      gtk_widget_set_sensitive(ok_bt, TRUE);
+  }
+  if (!found && enabled) {
+    interface_opts.name = g_strdup(row.name);
+    interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
+    interface_opts.linktype = row.active_dlt;
+    interface_opts.promisc_mode = row.pmode;
+    interface_opts.has_snaplen = row.has_snaplen;
+    interface_opts.snaplen = row.snaplen;
+    interface_opts.cfilter = g_strdup(row.cfilter);
+#ifdef HAVE_PCAP_CREATE
+    interface_opts.monitor_mode = row.monitor_mode_enabled;
+#else
+    interface_opts.monitor_mode = FALSE;
+#endif
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+    interface_opts.buffer_size = row.buffer;
+#endif
+#ifdef HAVE_PCAP_REMOTE
+    interface_opts.src_type = row.remote_opts.src_type;
+    if (interface_opts.src_type == CAPTURE_IFREMOTE) {
+      interface_opts.remote_host = g_strdup(row.remote_opts.remote_host_opts.remote_host);
+      interface_opts.remote_port = g_strdup(row.remote_opts.remote_host_opts.remote_port);
+      interface_opts.auth_type = row.remote_opts.remote_host_opts.auth_type;
+      interface_opts.auth_username = g_strdup(row.remote_opts.remote_host_opts.auth_username);
+      interface_opts.auth_password = g_strdup(row.remote_opts.remote_host_opts.auth_password);
+      interface_opts.datatx_udp = row.remote_opts.remote_host_opts.datatx_udp;
+      interface_opts.nocap_rpcap = row.remote_opts.remote_host_opts.nocap_rpcap;
+      interface_opts.nocap_local = row.remote_opts.remote_host_opts.nocap_local;
+#ifdef HAVE_PCAP_SETSAMPLING
+      interface_opts.sampling_method = row.remote_opts.sampling_method;
+      interface_opts.sampling_param  = row.remote_opts.sampling_param;
+#endif
     } else {
-      gtk_widget_set_sensitive(ok_bt, FALSE);
+      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;
+#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
     }
-  /* do something with the new enabled value, and set the new
-     enabled value in your treemodel */
-    gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, -1);
+#endif
+    g_array_append_val(global_capture_opts.ifaces, interface_opts);
     if (interfaces_dialog_window_present()) {
-      update_selected_interface(g_strdup(device.name));
+      update_selected_interface(g_strdup(interface_opts.name), TRUE);
     }
     if (get_welcome_window() != NULL) {
-      change_interface_selection(g_strdup(device.name), device.selected);
+      change_interface_selection(g_strdup(interface_opts.name), TRUE);
     }
   }
-  device.locked = FALSE;
-  global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, index);
-  g_array_insert_val(global_capture_opts.all_ifaces, index, device);
   gtk_tree_path_free (path);
 }
 
-void enable_selected_interface(gchar *name, gboolean selected)
+void enable_selected_interface(gchar *name, gboolean enable)
 {
+  guint i;
+  interface_row row;
   GtkTreeIter  iter;
   GtkTreeView  *if_cb;
   GtkTreeModel *model;
-  gchar *name_str;
+  gchar *path_str;
+  gboolean enabled;
 
-  if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
-  model = gtk_tree_view_get_model(if_cb);
-  gtk_tree_model_get_iter_first(model, &iter);
-  do {
-    gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &name_str, -1);
-    if (strcmp(name, name_str) == 0) {
-    gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, selected, -1);
-    break;
+  for (i = 0; i < rows->len; i++) {
+    row = g_array_index(rows, interface_row, i);
+    if (strcmp(name, row.name) == 0) {
+      if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
+      model = gtk_tree_view_get_model(if_cb);
+      path_str = g_strdup_printf("%d", i);
+      gtk_tree_model_get_iter_from_string(model, &iter, path_str);
+      gtk_tree_model_get (model, &iter, CAPTURE, &enabled, -1);
+      if ((enabled == TRUE) && (enable == FALSE)) {
+        num_selected--;
+      }
+      if ((enabled == FALSE) && (enable == TRUE)) {
+        num_selected++;
+      }
+      gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enable, -1);
+      break;
     }
   }
-  while (gtk_tree_model_iter_next(model, &iter));
-  if (global_capture_opts.num_selected > 0) {
+  if (num_selected > 0) {
     gtk_widget_set_sensitive(ok_bt, TRUE);
   } else {
     gtk_widget_set_sensitive(ok_bt, FALSE);
@@ -2347,17 +2563,17 @@ static void capture_all_cb(GtkToggleButton *button, gpointer d _U_)
     do {
       gtk_tree_model_get (model, &iter, CAPTURE, &capture_set, -1);
       if (!capture_set && enabled) {
-        global_capture_opts.num_selected++;
+        num_selected++;
       } else if (capture_set && !enabled) {
-        global_capture_opts.num_selected--;
+        num_selected--;
       }
       gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enabled, -1);
     } while (gtk_tree_model_iter_next(model, &iter));
   }
-  if (global_capture_opts.num_selected >= 2) {
+  if (num_selected >= 2) {
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE);
     gtk_widget_set_sensitive(pcap_ng_cb, FALSE);
-  } else if (global_capture_opts.num_selected <= 1) {
+  } else if (num_selected <= 1) {
     gtk_widget_set_sensitive(pcap_ng_cb, TRUE);
   }
   if (interfaces_dialog_window_present()) {
@@ -2366,7 +2582,7 @@ static void capture_all_cb(GtkToggleButton *button, gpointer d _U_)
   if (get_welcome_window() != NULL) {
     change_selection_for_all(enabled);
   }
-  if (global_capture_opts.num_selected > 0) {
+  if (num_selected > 0) {
     gtk_widget_set_sensitive(ok_bt, TRUE);
   } else {
     gtk_widget_set_sensitive(ok_bt, FALSE);
@@ -2380,7 +2596,7 @@ static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_)
   GtkTreeView  *if_cb;
   GtkTreeModel *model;
   gboolean enabled = FALSE;
-  interface_t device;
+  interface_row row;
   interface_options interface_opts;
   guint i;
 
@@ -2395,11 +2611,11 @@ static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_)
     } while (gtk_tree_model_iter_next(model, &iter));
   }
 
-  for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-    device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-    global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
-    device.pmode = (enabled?TRUE:FALSE);
-    g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+  for (i = 0; i < rows->len; i++) {
+    row = g_array_index(rows, interface_row, i);
+    rows = g_array_remove_index(rows, i);
+    row.pmode = (enabled?TRUE:FALSE);
+    g_array_insert_val(rows, i, row);
   }
 
   for (i = 0; i < global_capture_opts.ifaces->len; i++) {
@@ -2414,24 +2630,24 @@ static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_)
 void show_remote_dialog(GtkWidget *w)
 {
 
-  g_free(global_remote_opts.remote_host_opts.remote_host);
-  g_free(global_remote_opts.remote_host_opts.remote_port);
-  g_free(global_remote_opts.remote_host_opts.auth_username);
-  g_free(global_remote_opts.remote_host_opts.auth_password);
-  global_remote_opts.src_type = CAPTURE_IFREMOTE;
-  global_remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
-  global_remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
-  global_remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
-  global_remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
-  global_remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
-  global_remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
-  global_remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
-  global_remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
+    g_free(global_remote_opts.remote_host_opts.remote_host);
+    g_free(global_remote_opts.remote_host_opts.remote_port);
+    g_free(global_remote_opts.remote_host_opts.auth_username);
+    g_free(global_remote_opts.remote_host_opts.auth_password);
+    global_remote_opts.src_type = CAPTURE_IFREMOTE;
+    global_remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
+    global_remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
+    global_remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
+    global_remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
+    global_remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
+    global_remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
+    global_remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
+    global_remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
 #ifdef HAVE_PCAP_SETSAMPLING
-  global_remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
-  global_remote_opts.sampling_param = global_capture_opts.default_options.sampling_param;
+    global_remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
+    global_remote_opts.sampling_param = global_capture_opts.default_options.sampling_param;
 #endif
-  capture_remote_cb(GTK_WIDGET(w), FALSE);
+    capture_remote_cb(GTK_WIDGET(w), FALSE);
 }
 #endif
 
@@ -2495,8 +2711,6 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
                 *help_bt;
 #ifdef HAVE_AIRPCAP
   GtkWidget     *decryption_cb;
-  int           err;
-  gchar         *err_str;
 #endif
 #ifdef HAVE_PCAP_REMOTE
   GtkWidget     *iftype_cbx;
@@ -2505,7 +2719,10 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   GtkAdjustment *ringbuffer_nbf_adj,
                 *stop_packets_adj, *stop_filesize_adj, *stop_duration_adj, *stop_files_adj,
                 *ring_filesize_adj, *file_duration_adj;
+  GList           *if_list;
   int              row;
+  int              err;
+  gchar            *err_str;
   guint32          value;
   gchar            *cap_title;
   GtkWidget        *view;
@@ -2525,6 +2742,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
     return;
   }
 
+  num_selected = 0;
   /* use user-defined title if preference is set */
 
   cap_title = create_user_window_title("Wireshark: Capture Options");
@@ -2533,6 +2751,14 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   cap_open_w = dlg_window_new(cap_title);
   g_free(cap_title);
 
+  if_list = capture_interface_list(&err, &err_str);
+
+  if (if_list == NULL &&
+      (err == CANT_GET_INTERFACE_LIST || err == DONT_HAVE_PCAP)) {
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
+    g_free(err_str);
+  }
+  if_list = g_list_sort (if_list, if_list_comparator_alph);
 #ifdef HAVE_AIRPCAP
   /* update airpcap interface list */
 
@@ -2583,13 +2809,6 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   g_object_set (GTK_TREE_VIEW(view), "has-tooltip", TRUE, NULL);
   g_signal_connect (GTK_TREE_VIEW(view), "query-tooltip", G_CALLBACK (query_tooltip_tree_view_cb), NULL);
 
-  renderer = gtk_cell_renderer_text_new();
-  column = gtk_tree_view_column_new_with_attributes ("",
-                                               GTK_CELL_RENDERER(renderer),
-                                               "text", IFACE_HIDDEN_NAME,
-                                               NULL);
-  gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
-  gtk_tree_view_column_set_visible(column, FALSE);
   renderer = gtk_cell_renderer_text_new ();
   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view), -1, "Interface", renderer, "markup", INTERFACE, NULL);
   column = gtk_tree_view_get_column(GTK_TREE_VIEW (view), INTERFACE);
@@ -2640,6 +2859,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   gtk_container_add (GTK_CONTAINER (swindow), view);
   gtk_box_pack_start(GTK_BOX(capture_vb), swindow, TRUE, TRUE, 0);
 
+  free_interface_list(if_list);
   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY, view);
 
   main_hb = gtk_hbox_new(FALSE, 5);
@@ -3008,7 +3228,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_START);
   g_signal_connect(ok_bt, "clicked", G_CALLBACK(capture_start_cb), NULL);
   gtk_widget_set_tooltip_text(ok_bt, "Start the capture process.");
-  if (global_capture_opts.num_selected > 0) {
+  if (num_selected > 0) {
     gtk_widget_set_sensitive(ok_bt, TRUE);
   } else {
     gtk_widget_set_sensitive(ok_bt, FALSE);
@@ -3089,7 +3309,7 @@ capture_start_confirmed(void)
   guint i;
 
   /* did the user ever select a capture interface before? */
-  if(global_capture_opts.num_selected == 0 && prefs.capture_device == NULL) {
+  if(global_capture_opts.ifaces->len == 0 && prefs.capture_device == NULL) {
     simple_dialog(ESD_TYPE_CONFIRMATION,
                   ESD_BTN_OK,
                   "%sNo capture interface selected!%s\n\n"
@@ -3141,6 +3361,10 @@ void
 capture_start_cb(GtkWidget *w _U_, gpointer d _U_)
 {
   gpointer  dialog;
+  gchar *if_name;
+  cap_settings_t *cap_settings_p = NULL;
+  interface_options interface_opts;
+  guint i;
 
 #ifdef HAVE_AIRPCAP
   airpcap_if_active = airpcap_if_selected;
@@ -3165,10 +3389,60 @@ capture_start_cb(GtkWidget *w _U_, gpointer d _U_)
     if (!success)
       return;   /* error in options dialog */
   }
-  if (global_capture_opts.num_selected == 0) {
-    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+
+  if (global_capture_opts.ifaces->len == 0) {
+    if (prefs.capture_device == NULL) {
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
         "You didn't specify an interface on which to capture packets.");
-    return;
+      return;
+    }
+    interface_opts.name = g_strdup(get_if_name(prefs.capture_device));
+    interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
+#ifdef HAVE_PCAP_CREATE
+    interface_opts.monitor_mode = prefs_capture_device_monitor_mode(interface_opts.name);
+#else
+    interface_opts.monitor_mode = FALSE;
+#endif
+    interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name);
+    interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
+    interface_opts.snaplen = global_capture_opts.default_options.snaplen;
+    interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen;
+    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
+#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_insert_val(global_capture_opts.ifaces, 0, interface_opts);
+  }
+
+  if (cap_settings_history != NULL) {
+    for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+      interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
+      if_name = g_strdup(interface_opts.name);
+      cap_settings_p = (cap_settings_t *)g_hash_table_lookup(cap_settings_history, if_name);
+      if (cap_settings_p == NULL) {
+        cap_settings_p = g_new(cap_settings_t,1);
+        g_hash_table_insert(cap_settings_history, if_name, cap_settings_p);
+      } else {
+        g_free(if_name);
+      }
+      cap_settings_p->monitor_mode = interface_opts.monitor_mode;
+      cap_settings_p->linktype = interface_opts.linktype;
+    }
   }
 
   if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
@@ -3191,18 +3465,18 @@ select_link_type_cb(GtkWidget *linktype_combo_box, gpointer data _U_)
 {
   gpointer  ptr;
   int       dlt;
-  interface_t device;
+  interface_row row;
 
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
-  global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
+  row = g_array_index(rows, interface_row, marked_row);
+  rows = g_array_remove_index(rows, marked_row);
   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
     g_assert_not_reached();  /* Programming error: somehow nothing is active */
   }
   if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
   }
-  device.active_dlt = dlt;
-  g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
+  row.active_dlt = dlt;
+  g_array_insert_val(rows, marked_row, row);
   capture_filter_check_syntax_cb(linktype_combo_box, data);
 }
 
@@ -3260,7 +3534,7 @@ capture_dlg_prep(gpointer parent_w) {
   n_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY);
   t_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY);
 
-  if (global_capture_opts.num_selected == 0) {
+  if (global_capture_opts.ifaces->len == 0) {
     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
       "You didn't specify an interface on which to capture packets.");
     return FALSE;
@@ -3404,51 +3678,263 @@ capture_dlg_prep(gpointer parent_w) {
   return TRUE;
 }
 
+static void
+make_and_fill_rows(void)
+{
+  GList *if_entry, *if_list;
+  if_info_t *if_info;
+  char *if_string=NULL;
+  gchar *descr;
+  if_capabilities_t *caps=NULL;
+  gint linktype_count;
+  cap_settings_t cap_settings;
+  GSList *curr_addr;
+  int ips = 0, err;
+  guint i;
+  if_addr_t *addr;
+  GList *lt_entry;
+  link_row *link = NULL;
+  data_link_info_t *data_link_info;
+  gchar *str, *err_str = NULL, *err_str_norfmon;
+  interface_row row;
+  interface_options interface_opts;
+  gboolean found = FALSE;
+  GString *ip_str;
+
+  rows = g_array_new(TRUE, TRUE, sizeof(interface_row));
+  /* Scan through the list and build a list of strings to display. */
+  if_list = capture_interface_list(&err, &err_str);
+  if_list = g_list_sort (if_list, if_list_comparator_alph);
+  if (if_list == NULL &&
+      (err == CANT_GET_INTERFACE_LIST || err == DONT_HAVE_PCAP)) {
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
+    g_free(err_str);
+    return;
+  } else if (err_str) {
+    g_free(err_str);
+  }
+  for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
+    if_info = (if_info_t *)if_entry->data;
+    ip_str = g_string_new("");
+    str = NULL;
+    ips = 0;
+    row.name = g_strdup(if_info->name);
+    /* Is this interface hidden and, if so, should we include it anyway? */
+    if (!prefs_is_capture_device_hidden(if_info->name)) {
+      /* It's not hidden, or it is but we should include it in the list. */
+      /* Do we have a user-supplied description? */
+      descr = capture_dev_user_descr_find(if_info->name);
+      if (descr != NULL) {
+        /* Yes, we have a user-supplied description; use it. */
+        if_string = g_strdup_printf("%s: %s", descr, if_info->name);
+        g_free(descr);
+      } else {
+        /* No, we don't have a user-supplied description; did we get
+           one from the OS or libpcap? */
+        if (if_info->description != NULL) {
+          /* Yes - use it. */
+          if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
+        } else {
+          /* No. */
+          if_string = g_strdup(if_info->name);
+        }
+      }
+      if (if_info->loopback) {
+        row.display_name = g_strdup_printf("%s (loopback)", if_string);
+      } else {
+        row.display_name = g_strdup(if_string);
+      }
+      found = FALSE;
+      for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+        interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
+        if (!interface_opts.name || strcmp(interface_opts.name, (char*)row.name)!=0) {
+          continue;
+        } else {
+          found = TRUE;
+          break;
+        }
+      }
+      if (found) {
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+        row.buffer = interface_opts.buffer_size;
+#endif
+        row.pmode = interface_opts.promisc_mode;
+        row.has_snaplen = interface_opts.has_snaplen;
+        row.snaplen = interface_opts.snaplen;
+        row.cfilter = g_strdup(interface_opts.cfilter);
+      } else {
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+        row.buffer = global_capture_opts.default_options.buffer_size;
+#endif
+        row.pmode = global_capture_opts.default_options.promisc_mode;
+        row.has_snaplen = global_capture_opts.default_options.has_snaplen;
+        row.snaplen = global_capture_opts.default_options.snaplen;
+        row.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
+      }
+      cap_settings = capture_get_cap_settings(if_info->name);
+      caps = capture_get_if_capabilities(if_info->name,
+                                         cap_settings.monitor_mode,
+                                         &err_str);
+      if (caps == NULL) {
+        /* Error attempting to get interface capabilities. */
+        if (cap_settings.monitor_mode) {
+          /*
+           * Perhaps this is the libpcap bug on Linux where
+           * attempting to set monitor mode with the Wireless
+           * Extensions ioctls doesn't work correctly.
+           *
+           * Try fetching the capabilities without monitor mode;
+           * if that succeeds, report the monitor-mode problem,
+           * and use the no-monitor-mode capabilities.  If that
+           * fails, report that failure.  In either case, force
+           * monitor mode off.
+           */
+          cap_settings.monitor_mode = FALSE;
+          caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode,
+                                             &err_str_norfmon);
+          if (caps == NULL) {
+            /* Epic fail. */
+            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str_norfmon);
+            g_free(err_str_norfmon);
+            g_free(err_str);
+          } else {
+            /*
+             * OK, it's probably that bug.  Suggest using airmon-ng,
+             * just in case the adapter has a mac80211 driver and
+             * libpcap was built without libnl so that it can't
+             * use the mac80211 features to create a monitor-mode
+             * device.
+             */
+            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                          "%s\n\n"
+                          "Try using airmon-ng, as suggested by CaptureSetup/WLAN in the Wireshark Wiki.",
+                          err_str);
+            g_free(err_str);
+          }
+        } else {
+          simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
+          g_free(err_str);
+        }
+      }
+      for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
+        if (ips != 0) {
+          g_string_append(ip_str, "\n");
+        }
+        addr = (if_addr_t *)curr_addr->data;
+        switch (addr->ifat_type) {
+          case IF_AT_IPv4:
+            g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
+            break;
+          case IF_AT_IPv6:
+            g_string_append(ip_str,  ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
+            break;
+          default:
+            /* In case we add non-IP addresses */
+            break;
+        }
+      }
+      linktype_count = 0;
+      row.links = NULL;
+      if (caps != NULL) {
+#ifdef HAVE_PCAP_CREATE
+        row.monitor_mode_enabled = cap_settings.monitor_mode;
+        row.monitor_mode_supported = caps->can_set_rfmon;
+#endif
+        for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
+          data_link_info = (data_link_info_t *)lt_entry->data;
+          if (data_link_info->description != NULL) {
+            str = g_strdup_printf("%s", data_link_info->description);
+          } else {
+            str = g_strdup_printf("%s (not supported)", data_link_info->name);
+          }
+          if (linktype_count == 0) {
+            row.active_dlt = data_link_info->dlt;
+          }
+          link = (link_row *)g_malloc(sizeof(link_row));
+          link->dlt = data_link_info->dlt;
+          link->name = g_strdup(str);
+          row.links = g_list_append(row.links, link);
+          linktype_count++;
+        }
+      } else {
+        cap_settings.monitor_mode = FALSE;
+#ifdef HAVE_PCAP_CREATE
+        row.monitor_mode_enabled = FALSE;
+        row.monitor_mode_supported = FALSE;
+#endif
+        row.active_dlt = -1;
+      }
+      row.addresses = g_strdup(ip_str->str);
+      row.no_addresses = ips;
+      g_array_append_val(rows, row);
+      if (caps != NULL) {
+        free_if_capabilities(caps);
+      }
+    }
+    g_string_free(ip_str, TRUE);
+  }
+}
+
 GtkTreeModel *create_and_fill_model(GtkTreeView *view)
 {
   GtkListStore *store;
   GtkTreeIter iter;
   GList *list;
-  char *temp="", *snaplen_string, *linkname="";
-  guint i;
+  char *temp=NULL, *snaplen_string;
+  guint i, j;
   link_row *link = NULL;
-  interface_t device;
+  interface_row row;
+  interface_options interface_opts;
+  gboolean found = FALSE;
 
 #if defined(HAVE_PCAP_CREATE)
-  store = gtk_list_store_new (9, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
+  store = gtk_list_store_new (8, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
 #elif defined(_WIN32) && !defined (HAVE_PCAP_CREATE)
-  store = gtk_list_store_new (8, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
+  store = gtk_list_store_new (7, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
 #else
-  store = gtk_list_store_new (7, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+  store = gtk_list_store_new (6, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 #endif
 
-  for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-    device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-    if (!device.hidden) {
-      if (device.no_addresses == 0) {
-        temp = g_strdup_printf("<b>%s</b>", device.display_name);
+  if (!rows || rows->len == 0) {
+    make_and_fill_rows();
+  }
+  if (rows && rows->len > 0) {
+    for (i = 0; i < rows->len; i++) {
+      row = g_array_index(rows, interface_row, i);
+      found = FALSE;
+      for (j = 0; j < global_capture_opts.ifaces->len; j++) {
+        interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
+        if (!interface_opts.name || strcmp(interface_opts.name, (char*)row.name)!=0) {
+          continue;
+        } else {
+          found = TRUE;
+          num_selected++;
+          break;
+        }
+      }
+      if (row.no_addresses == 0) {
+        temp = g_strdup_printf("<b>%s</b>", row.display_name);
       } else {
-        temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", device.display_name, device.addresses);
+        temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", row.display_name, row.addresses);
       }
-      for (list = device.links; list != NULL; list = g_list_next(list)) {
+      for (list = row.links; list != NULL; list = g_list_next(list)) {
         link = (link_row*)(list->data);
-        linkname = g_strdup(link->name);
-        if (link->dlt == device.active_dlt) {
-        break;
+        if (link->dlt == row.active_dlt) {
+          break;
         }
       }
-      if (device.has_snaplen) {
-        snaplen_string = g_strdup_printf("%d", device.snaplen);
+      if (row.has_snaplen) {
+        snaplen_string = g_strdup_printf("%d", row.snaplen);
       } else {
         snaplen_string = g_strdup("default");
       }
       gtk_list_store_append (store, &iter);
 #if defined(HAVE_PCAP_CREATE)
-      gtk_list_store_set (store, &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname,  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, MONITOR, device.monitor_mode_supported?(device.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, device.cfilter, -1);
+      gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, MONITOR, row.monitor_mode_supported?(row.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, row.cfilter, -1);
 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
-      gtk_list_store_set (store, &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname,  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, FILTER, device.cfilter, -1);
+      gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, FILTER, row.cfilter, -1);
 #else
-      gtk_list_store_set (store, &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname,  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, device.cfilter, -1);
+      gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, row.cfilter, -1);
 #endif
     }
   }
@@ -3535,13 +4021,13 @@ gboolean query_tooltip_tree_view_cb (GtkWidget  *widget,
 void activate_monitor (GtkTreeViewColumn *tree_column _U_, GtkCellRenderer *renderer,
                               GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data _U_)
 {
-  interface_t device;
+  interface_row row;
   GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter);
   int index = atoi(gtk_tree_path_to_string(path));
 
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, index);
+  row = g_array_index(rows, interface_row, index);
 
-  if (device.monitor_mode_supported==TRUE) {
+  if (row.monitor_mode_supported==TRUE) {
     g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
   } else {
     g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
@@ -3597,37 +4083,83 @@ static void
 capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_)
 {
   GList *lt_entry;
-  gchar *if_string="";
+  gchar *if_string=NULL;
   cap_settings_t cap_settings;
+  gchar *err_str, *err_str_norfmon;
   if_capabilities_t *caps=NULL;
   gint linktype_count = 0, i;
   data_link_info_t *data_link_info;
-  interface_t device;
+  interface_row row;
   link_row *link;
   GtkWidget *linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
   GtkWidget *linktype_lb = (GtkWidget *)g_object_get_data(G_OBJECT(linktype_combo_box), E_CAP_LT_CBX_LABEL_KEY);
 
-  device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
-  global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
+  row = g_array_index(rows, interface_row, marked_row);
+  rows = g_array_remove_index(rows, marked_row);
 
 
-  if_string = g_strdup(device.name);
+  if_string = g_strdup(row.name);
   cap_settings = capture_get_cap_settings(if_string);
   cap_settings.monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor));
-  caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, NULL);
+  caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode,
+                                     &err_str);
+  if (caps == NULL) {
+    /* Error attempting to get interface capabilities. */
+    if (cap_settings.monitor_mode) {
+      /*
+       * Perhaps this is the libpcap bug on Linux where
+       * attempting to set monitor mode with the Wireless
+       * Extensions ioctls doesn't work correctly.
+       *
+       * Try fetching the capabilities without monitor mode;
+       * if that succeeds, report the monitor-mode problem,
+       * and use the no-monitor-mode capabilities.  If that
+       * fails, report that failure.  In either case, force
+       * monitor mode off.
+       */
+      cap_settings.monitor_mode = FALSE;
+      /* Set the monitor-mode checkbox to the new forced value */
+      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor),
+                                   cap_settings.monitor_mode);
+      caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode,
+                                         &err_str_norfmon);
+      if (caps == NULL) {
+        /* Epic fail. */
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str_norfmon);
+        g_free(err_str_norfmon);
+        g_free(err_str);
+      } else {
+        /*
+         * OK, it's probably that bug.  Suggest using airmon-ng,
+         * just in case the adapter has a mac80211 driver and
+         * libpcap was built without libnl so that it can't
+         * use the mac80211 features to create a monitor-mode
+         * device.
+         */
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                      "%s\n\n"
+                      "Try using airmon-ng, as suggested by CaptureSetup/WLAN in the Wireshark Wiki.",
+                      err_str);
+        g_free(err_str);
+      }
+    } else {
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
+      g_free(err_str);
+    }
+  }
 
   if (caps != NULL) {
     g_signal_handlers_disconnect_by_func(linktype_combo_box, G_CALLBACK(select_link_type_cb), NULL );
     ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box));
-    for (i = (gint)g_list_length(device.links)-1; i >= 0; i--) {
-      GList* rem = g_list_nth(device.links, i);
-      device.links = g_list_remove_link(device.links, rem);
+    for (i = (gint)g_list_length(row.links)-1; i >= 0; i--) {
+      GList* rem = g_list_nth(row.links, i);
+      row.links = g_list_remove_link(row.links, rem);
       g_list_free_1(rem);
     }
-    device.active_dlt = -1;
+    row.active_dlt = -1;
     linktype_count = 0;
-    device.monitor_mode_supported = caps->can_set_rfmon;
-    device.monitor_mode_enabled = cap_settings.monitor_mode;
+    row.monitor_mode_supported = caps->can_set_rfmon;
+    row.monitor_mode_enabled = cap_settings.monitor_mode;
     for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
       link = (link_row *)g_malloc(sizeof(link_row));
       data_link_info = (data_link_info_t *)lt_entry->data;
@@ -3637,7 +4169,7 @@ capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_)
                                              GINT_TO_POINTER(data_link_info->dlt));
         link->dlt = data_link_info->dlt;
         if (linktype_count == 0) {
-          device.active_dlt = data_link_info->dlt;
+          row.active_dlt = data_link_info->dlt;
         }
         link->name = g_strdup(data_link_info->description);
       } else {
@@ -3653,7 +4185,7 @@ capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_)
         link->name = g_strdup(str);
         g_free(str);
       }
-      device.links = g_list_append(device.links, link);
+      row.links = g_list_append(row.links, link);
       linktype_count++;
     }
     free_if_capabilities(caps);
@@ -3661,13 +4193,13 @@ capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_)
     /* We don't know whether this supports monitor mode or not;
     don't ask for monitor mode. */
     cap_settings.monitor_mode = FALSE;
-    device.monitor_mode_enabled = FALSE;
-    device.monitor_mode_supported = FALSE;
+    row.monitor_mode_enabled = FALSE;
+    row.monitor_mode_supported = FALSE;
   }
   gtk_widget_set_sensitive(linktype_lb, linktype_count >= 2);
   gtk_widget_set_sensitive(linktype_combo_box, linktype_count >= 2);
   ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box),0);
-  g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
+  g_array_insert_val(rows, marked_row, row);
 }
 #endif
 
index 602be8a8e303c15e98fe6c0f850033f411fc013f..70478a3cfdc46266be61ecfcb20f73e0a9ed6178 100644 (file)
  *  @ingroup dialog_group
  */
 #include "capture_opts.h"
-#include <gtk/gtk.h>
+
+#ifdef HAVE_PCAP_REMOTE
+struct remote_host {
+    gchar *remote_host;          /**< Host name or network address for remote capturing */
+    gchar *remote_port;          /**< TCP port of remote RPCAP server */
+    gint auth_type;              /**< Authentication type */
+    gchar *auth_username;        /**< Remote authentication parameters */
+    gchar *auth_password;        /**< Remote authentication parameters */
+    gboolean datatx_udp;
+    gboolean nocap_rpcap;
+    gboolean nocap_local;
+};
+
+typedef struct remote_options_tag {
+    capture_source src_type;
+    struct remote_host remote_host_opts;
+#ifdef HAVE_PCAP_SETSAMPLING
+    capture_sampling sampling_method;
+    int sampling_param;
+#endif
+} remote_options;
+#endif /* HAVE_PCAP_REMOTE */
+
+typedef struct row_options_tag {
+    gchar *name;
+    gchar *display_name;
+    gchar *addresses;
+    gint no_addresses;
+    gchar *cfilter;
+    GList *links;
+    gint active_dlt;
+    gboolean pmode;
+#ifdef HAVE_PCAP_CREATE
+    gboolean monitor_mode_enabled;
+    gboolean monitor_mode_supported;
+#endif
+    gboolean has_snaplen;
+    guint snaplen;
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+    gint buffer;
+#endif
+#ifdef HAVE_PCAP_REMOTE
+    remote_options remote_opts;
+#endif
+} interface_row;
+
+typedef struct link_row_tag {
+    gchar *name;
+    gint dlt;
+} link_row;
 
 enum
 {
     CAPTURE = 0,
-    IFACE_HIDDEN_NAME, 
     INTERFACE,
     LINK,
     PMODE,
@@ -95,7 +143,6 @@ void capture_start_confirmed(void);
 void
 capture_air_cb(GtkWidget *widget, gpointer data);
 
-#if 0
 /*
  * We remember the capture settings for each interface when a capture
  * is started on it; the next time we select that interface we start
@@ -116,7 +163,6 @@ typedef struct {
  */
 cap_settings_t
 capture_get_cap_settings (gchar *if_name);
-#endif
 
 GtkTreeModel*
 create_and_fill_model (GtkTreeView *view);
@@ -137,12 +183,9 @@ gboolean
 dlg_window_present(void);
 
 void
-enable_selected_interface(gchar *name, gboolean selected);
+enable_selected_interface(gchar *name, gboolean enable);
 
 void
 options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column _U_, gpointer userdata);
 
-void
-update_all_rows(void);
-
 #endif /* capture_dlg.h */
index f6bf71c4548cf97a44558c457862177b171d6cff..e67b57b79e83087825302a1f00d90560dcaaab47 100644 (file)
@@ -51,7 +51,6 @@
 
 #ifdef _WIN32
 #include "ui/gtk/capture_if_details_dlg_win32.h"
-#include "../../capture-wpcap.h"
 #endif
 
 #include "ui/gtk/stock_icons.h"
@@ -66,7 +65,6 @@
 #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"
 
  */
 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 GArray    *gtk_list;
+static guint     currently_selected = 0;
 
 static if_stat_cache_t   *sc;
 
@@ -129,7 +129,6 @@ 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;
@@ -139,62 +138,125 @@ typedef struct if_dlg_data_s {
 #ifdef _WIN32
     GtkWidget   *details_bt;
 #endif
+    guint32     last_packets;
+    gchar       *device;
+    if_info_t   if_info;
+    gboolean    selected;
 } if_dlg_data_t;
 
 static gboolean gbl_capture_in_progress = FALSE;
 
 void
-update_selected_interface(gchar *name)
+update_selected_interface(gchar *name, gboolean activate)
 {
-  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(gtk_list, if_dlg_data_t, i);
-    if (strcmp(name, device.name) == 0) {
-      gtk_toggle_button_set_active((GtkToggleButton *)data.choose_bt, device.selected);
+  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);
+      }
       break;
     }
   }
 }
 
 static void
-store_selected(GtkWidget *choose_bt, gpointer name)
+store_selected(GtkWidget *choose_bt, gpointer if_data)
 {
-  interface_t device;
-  guint i;
+  if_dlg_data_t *if_dlg_data = (if_dlg_data_t *)if_data, *temp;
+  GList *curr;
+  unsigned int ifs, i;
   gboolean found;
-  for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-    device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+  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(name, device.if_info.name) == 0) {
-      found = TRUE;
-      if (!device.locked) {
-        device.selected ^= 1;
-        if (device.selected) {
-          global_capture_opts.num_selected++;
-        } else {
-          global_capture_opts.num_selected--;
+    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;
+          }
         }
-        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 (!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);
         }
         if (gtk_widget_is_focus(choose_bt) && dlg_window_present()) {
-          enable_selected_interface(device.name, device.selected);
+          enable_selected_interface(interface_opts.name, TRUE);
         }
-        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 && (global_capture_opts.num_selected > 0));
+    gtk_widget_set_sensitive(capture_bt, !gbl_capture_in_progress && (currently_selected > 0));
   }
 }
 
@@ -206,18 +268,19 @@ capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data)
 capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data _U_)
 #endif
 {
-  if_dlg_data_t data;
-  guint ifs;
-
-  for (ifs = 0; ifs < gtk_list->len; ifs++) {
-    data = g_array_index(gtk_list, if_dlg_data_t, ifs);
-    gtk_widget_set_sensitive(data.choose_bt, FALSE);
-    gtk_list = g_array_remove_index(gtk_list, ifs);
-    g_array_insert_val(gtk_list, ifs, data);
+  if_dlg_data_t *temp;
+  GList *curr;
+  int ifs;
 #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;
+  if_dlg_data_t *if_dlg_data = if_data;
+
+  airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, if_dlg_data->if_info.name);
+  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? */
@@ -263,14 +326,11 @@ capture_details_cb(GtkWidget *details_bt _U_, gpointer if_data)
 
 /* update a single interface */
 static void
-update_if(gchar *name, if_stat_cache_t *sc)
+update_if(if_dlg_data_t *if_dlg_data, if_stat_cache_t *sc)
 {
   struct pcap_stat stats;
   gchar *str;
-  guint diff, ifs;
-  interface_t  device;
-  if_dlg_data_t data;
-  gboolean  found = FALSE;
+  guint diff;
 
 
   /*
@@ -281,40 +341,23 @@ update_if(gchar *name, 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) {
-    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(gtk_list, if_dlg_data_t, ifs);
-        if (!device.hidden && strcmp(name, device.name) == 0) {
-          found = TRUE;
-          break;
-        }
-    }
-    if (found) {
-      if (capture_stats(sc, name, &stats)) {
-        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);
-      gtk_list = g_array_remove_index(gtk_list, ifs);
-      g_array_insert_val(gtk_list, ifs, data);
+    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");
     }
   }
 }
@@ -323,20 +366,19 @@ update_if(gchar *name, if_stat_cache_t *sc)
 static gboolean
 update_all(gpointer data)
 {
-  interface_t device;
-  guint ifs;
-  if_stat_cache_t *sc = data;
+    GList *curr;
+    int ifs;
+    if_stat_cache_t *sc = (if_stat_cache_t *)data;
 
-  if (!cap_if_w) {
-    return FALSE;
-  }
+    if (!cap_if_w) {
+        return FALSE;
+    }
 
-  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);
-  }
+    for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) {
+        update_if((if_dlg_data_t *)curr->data, sc);
+    }
 
-  return TRUE;
+    return TRUE;
 }
 
 /* a live capture has started or stopped */
@@ -346,7 +388,7 @@ 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 && (global_capture_opts.num_selected > 0));
+    gtk_widget_set_sensitive(capture_bt, !capture_in_progress && (currently_selected > 0));
   }
 }
 
@@ -355,17 +397,26 @@ 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_)
 {
-  g_source_remove(timer_id);
+    GList *curr;
+    int ifs;
 
-  free_interface_list(if_list);
+    g_source_remove(timer_id);
+
+    for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) {
+        g_free(curr->data);
+    }
 
-  /* Note that we no longer have a "Capture Options" dialog box. */
-  cap_if_w = NULL;
+    if_data_list = NULL;
 
-  capture_stat_stop(sc);
+    free_interface_list(if_list);
+
+    /* Note that we no longer have a "Capture Options" dialog box. */
+    cap_if_w = NULL;
+
+    capture_stat_stop(sc);
 
 #ifdef HAVE_AIRPCAP
-  airpcap_set_toolbar_stop_capture(airpcap_if_active);
+    airpcap_set_toolbar_stop_capture(airpcap_if_active);
 #endif
 }
 
@@ -389,38 +440,127 @@ gint if_list_comparator_alph (const void *first_arg, const void *second_arg){
  * Used to retrieve the interface icon.
  * This is hideously platform-dependent.
  */
-GtkWidget * capture_get_if_icon(interface_t *device)
+GtkWidget * capture_get_if_icon(const if_info_t* if_info)
 {
+#if defined(__linux__)
+  ws_statb64 statb;
+  char *wireless_path;
+#endif
+
 #ifdef HAVE_PCAP_REMOTE
-  if (!device->local) {
+  if (if_info->description && strstr(if_info->description, "on remote node") != NULL ) {
     return pixbuf_to_widget(remote_sat_pb_data);
   }
 #endif
-  switch (device->type) {
-#ifdef _WIN32
-  case IF_DIALUP:
+#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 ) ) {
     return xpm_to_widget(modem_16_xpm);
-#endif
-  case IF_WIRELESS: 
+  }
+
+  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);
-#ifdef HAVE_AIRPCAP
-  case IF_AIRPCAP:
-    return xpm_to_widget(capture_airpcap_16_xpm);
-#endif
-  case IF_BLUETOOTH:
+  }
+
+  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);
-  case IF_USB:
+  }
+#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) {
+    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) {
+    return pixbuf_to_widget(network_bluetooth_pb_data);
+  }
+
+  /*
+   * USB devices.
+   */
+  if ( strstr(if_info->name,"usbmon") != NULL ) {
     return pixbuf_to_widget(network_usb_pb_data);
-  case IF_VIRTUAL:
+  }
+#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) {
+    return xpm_to_widget(network_virtual_16_xpm);
+  }
+
+  if ( if_info->description && strstr(if_info->description, "VMware") != NULL ) {
     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");
   }
+
   return pixbuf_to_widget(network_wired_pb_data);
 }
 
@@ -552,40 +692,17 @@ static void
 capture_if_stop_cb(GtkWidget *w _U_, gpointer d _U_)
 {
   guint ifs;
-  if_dlg_data_t data;
+  GList *curr;
+  if_dlg_data_t *if_data;
 
-  for (ifs = 0; ifs < gtk_list->len; ifs++) {
-    data = g_array_index(gtk_list, if_dlg_data_t, ifs);
-    gtk_widget_set_sensitive(data.choose_bt, TRUE);
-    gtk_list = g_array_remove_index(gtk_list, ifs);
-    g_array_insert_val(gtk_list, ifs, 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);
   }
   capture_stop_cb(NULL, NULL);
 }
 
-static void
-make_gtk_array(void)
-{
-  interface_t   device;
-  if_dlg_data_t data;
-  guint         i;
-
-  gtk_list = g_array_new(FALSE, FALSE, sizeof(if_dlg_data_t));
-
-  for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-     device = g_array_index(global_capture_opts.all_ifaces, interface_t, 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
-     g_array_append_val(gtk_list, data);
-  }
-}
 
 /* start getting capture stats from all interfaces */
 void
@@ -595,53 +712,75 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_)
                     *main_sw,
                     *bbox,
                     *close_bt,
-                    *help_bt;
+                    *help_bt,
+                    *icon;
 
 #ifdef HAVE_AIRPCAP
   GtkWidget         *decryption_cb;
 #endif
 
-  GtkWidget         *if_tb, *icon;
+  GtkWidget         *if_tb;
   GtkWidget         *if_lb;
   GtkWidget         *eb;
+  int               err;
+  gchar             *err_str;
   GtkRequisition    requisition;
   int               row, height;
-  guint             ifs;
-  interface_t       device;
+  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;
-  if_dlg_data_t     data;
+  int               preselected = 0, i;
+  interface_options interface_opts;
+  gboolean      found = FALSE;
 
   if (cap_if_w != NULL) {
     /* There's already a "Capture Interfaces" dialog box; reactivate it. */
     reactivate_window(cap_if_w);
     return;
   }
-  
-  if (global_capture_opts.all_ifaces->len == 0) {
-    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                  "There are no interfaces on which a capture can be done.");
-    return;
-  }
-#ifdef _WIN32
-  /* Is WPcap loaded? */
-  if (!has_wpcap) {
-    char *detailed_err;
 
-    detailed_err = cant_load_winpcap_err("Wireshark");
-    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", detailed_err);
-    g_free(detailed_err);
+  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;
   }
-#endif
 
 #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;
 
   decryption_cb = g_object_get_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY);
   update_decryption_mode_list(decryption_cb);
 
+  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 no airpcap interface is present, gray everything */
   if (airpcap_if_active == NULL) {
     if (airpcap_if_list == NULL) {
@@ -657,7 +796,6 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_)
   airpcap_set_toolbar_start_capture(airpcap_if_active);
 #endif
 
-  make_gtk_array();
   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);
 
@@ -705,111 +843,144 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_)
 
   height += 30;
   /* Start gathering statistics (using dumpcap) */
-  sc = capture_stat_start(&global_capture_opts);
+  sc = capture_stat_start(if_list);
 
   /* List the interfaces */
-  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(gtk_list, if_dlg_data_t, ifs);
+  currently_selected = 0;
+  for (ifs = 0; (curr = g_list_nth(if_list, ifs)); ifs++) {
     g_string_assign(if_tool_str, "");
+    if_info = (if_info_t *)curr->data;
+
     /* Continue if capture device is hidden */
-    if (device.hidden) {
+    if (prefs_is_capture_device_hidden(if_info->name)) {
       continue;
     }
-    data.choose_bt = gtk_check_button_new();
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.choose_bt, 0, 1, row, row+1);
+
+    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);
     if (gbl_capture_in_progress) {
-      gtk_widget_set_sensitive(data.choose_bt, FALSE);
+      gtk_widget_set_sensitive(if_dlg_data->choose_bt, FALSE);
     } else {
-      gtk_widget_set_sensitive(data.choose_bt, TRUE);
+      gtk_widget_set_sensitive(if_dlg_data->choose_bt, TRUE);
     }
-    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_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_table_attach_defaults(GTK_TABLE(if_tb), icon, 1, 2, row, row+1);
 
       /* device name */
-    data.device_lb = gtk_label_new(device.name);
+    if_dlg_data->device_lb = gtk_label_new(if_info->name);
+    if_dlg_data->device = if_info->name;
 #ifndef _WIN32
-    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);
+    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);
 #endif
     g_string_append(if_tool_str, "Device: ");
-    g_string_append(if_tool_str, device.name);
+    g_string_append(if_tool_str, if_info->name);
     g_string_append(if_tool_str, "\n");
 
     /* description */
-    user_descr = capture_dev_user_descr_find(device.name);
+    user_descr = capture_dev_user_descr_find(if_info->name);
     if (user_descr) {
-      data.descr_lb = gtk_label_new(user_descr);
+      if_dlg_data->descr_lb = gtk_label_new(user_descr);
       g_free (user_descr);
     } else {
-      if (device.if_info.description)
-        data.descr_lb = gtk_label_new(device.if_info.description);
+      if (if_info->description)
+        if_dlg_data->descr_lb = gtk_label_new(if_info->description);
       else
-        data.descr_lb = gtk_label_new("");
+        if_dlg_data->descr_lb = gtk_label_new("");
     }
-    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) {
+    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) {
       g_string_append(if_tool_str, "Description: ");
-      g_string_append(if_tool_str, device.if_info.description);
+      g_string_append(if_tool_str, 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: ");
-    data.ip_lb = gtk_label_new("");
-    addr_str = set_ip_addr_label (device.if_info.addrs, data.ip_lb, 0);
+    if_dlg_data->ip_lb = gtk_label_new("");
+    addr_str = set_ip_addr_label (if_info->addrs, if_dlg_data->ip_lb, 0);
     if (addr_str) {
-      gtk_widget_set_sensitive(data.ip_lb, TRUE);
+      gtk_widget_set_sensitive(if_dlg_data->ip_lb, TRUE);
       g_string_append(if_tool_str, addr_str);
     } else {
-      gtk_widget_set_sensitive(data.ip_lb, FALSE);
+      gtk_widget_set_sensitive(if_dlg_data->ip_lb, FALSE);
       g_string_append(if_tool_str, "none");
     }
     eb = gtk_event_box_new ();
-    gtk_container_add(GTK_CONTAINER(eb), data.ip_lb);
+    gtk_container_add(GTK_CONTAINER(eb), if_dlg_data->ip_lb);
     gtk_table_attach_defaults(GTK_TABLE(if_tb), eb, 5, 6, row, row+1);
-    if (get_ip_addr_count(device.if_info.addrs) > 1) {
+    if (get_ip_addr_count(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, data.ip_lb);
+      g_object_set_data(G_OBJECT(eb), CAPTURE_IF_IP_ADDR_LABEL, if_dlg_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), device.if_info.addrs);
+      g_signal_connect(eb, "button-press-event", G_CALLBACK(ip_label_press_cb), if_info->addrs);
     }
     g_string_append(if_tool_str, "\n");
 
     /* packets */
-    data.curr_lb = gtk_label_new("-");
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.curr_lb, 6, 7, row, row+1);
+    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);
 
     /* packets/s */
-    data.last_lb = gtk_label_new("-");
-    gtk_table_attach_defaults(GTK_TABLE(if_tb), data.last_lb, 7, 8, row, row+1);
+    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);
 
     /* details button */
 #ifdef _WIN32
-    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);
+    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);
     } else {
-      gtk_widget_set_sensitive(data.details_bt, FALSE);
+      gtk_widget_set_sensitive(if_dlg_data->details_bt, FALSE);
     }
 #endif
-    gtk_list = g_array_remove_index(gtk_list, ifs);
-    g_array_insert_val(gtk_list, ifs, data);
-    
+
+    if_data_list = g_list_append(if_data_list, if_dlg_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(data.choose_bt), &requisition, NULL);
+      gtk_widget_get_preferred_size(GTK_WIDGET(if_dlg_data->choose_bt), &requisition, NULL);
       height += requisition.height;
-    } 
+    }
   }
 
   g_string_free(if_tool_str, TRUE);
@@ -827,9 +998,9 @@ 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), device.name);
+  g_signal_connect(options_bt, "clicked", G_CALLBACK(capture_prepare_cb), if_dlg_data);
   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), device.name);
+  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;
@@ -860,15 +1031,17 @@ void refresh_if_window(void)
   capture_if_cb(NULL, NULL);
 }
 
-void select_all_interfaces(gboolean enable _U_)
+void select_all_interfaces(gboolean enable)
 {
+  if_dlg_data_t *temp;
   guint ifs;
-  interface_t device;
+  GList *curr;
 
-  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);
-  }
+  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);
+ }
 }
 
 void destroy_if_window(void)
index a100b4c52a463d89b1f5cba401590544185767ce..3c2f2359d0a1555661e1bed910155cf24d5b549f 100644 (file)
@@ -48,10 +48,10 @@ capture_if_cb(GtkWidget *widget, gpointer data);
  * Used to retrieve the interface icon
  */
 GtkWidget *
-capture_get_if_icon(interface_t *device);
+capture_get_if_icon(const if_info_t* if_info);
 
 void
-update_selected_interface(gchar *name);
+update_selected_interface(gchar *name, gboolean activate);
 
 gboolean
 interfaces_dialog_window_present(void);
@@ -65,9 +65,6 @@ select_all_interfaces(gboolean enable);
 void
 destroy_if_window(void);
 
-gint 
-if_list_comparator_alph (const void *first_arg, const void *second_arg);
-
 #endif /* HAVE_LIBPCAP */
 
 #endif /* capture_if_dlg.h */
index acc3ba42c439132d47b3b9d918adafbb47d05882..4fc410154e58c66ede313319d21900cbcef44362 100644 (file)
 #include "../capture_ifinfo.h"
 #include "../capture.h"
 #include "../capture_sync.h"
-extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg);
 #endif
 
 #ifdef _WIN32
@@ -516,16 +515,16 @@ selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
 static gboolean
 is_address_column (gint column)
 {
-    if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
-         (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
-         (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
-         (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
-        strlen(cfile.cinfo.col_expr.col_expr_val[column]))
-    {
-        return TRUE;
-    }
+  if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
+       (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
+       (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
+       (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
+      strlen(cfile.cinfo.col_expr.col_expr_val[column]))
+  {
+    return TRUE;
+  }
 
-    return FALSE;
+  return FALSE;
 }
 
 GList *
@@ -551,17 +550,17 @@ get_ip_address_list_from_packet_list_row(gpointer data)
         epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
         epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
 
-        /* First check selected column */
-        if (is_address_column (column)) {
-            addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
+       /* First check selected column */
+       if (is_address_column (column)) {
+         addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
         }
 
-        for (col = 0; col < cfile.cinfo.num_cols; col++) {
-            /* Then check all columns except the selected */
-            if ((col != column) && (is_address_column (col))) {
-                addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
-            }
-        }
+       for (col = 0; col < cfile.cinfo.num_cols; col++) {
+         /* Then check all columns except the selected */
+         if ((col != column) && (is_address_column (col))) {
+           addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
+         }
+       }
 
         epan_dissect_cleanup(&edt);
     }
@@ -694,23 +693,23 @@ copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E acti
 /* mark as reference time frame */
 void
 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
-    if (row == -1)
-        return;
-    if (set) {
-        frame->flags.ref_time=1;
-        cfile.ref_time_count++;
-    } else {
-        frame->flags.ref_time=0;
-        cfile.ref_time_count--;
-    }
-    cf_reftime_packets(&cfile);
-    if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
-        new_packet_list_freeze();
-        cfile.displayed_count--;
-        new_packet_list_recreate_visible_rows();
-        new_packet_list_thaw();
-    }
-    new_packet_list_queue_draw();
+  if (row == -1)
+    return;
+  if (set) {
+    frame->flags.ref_time=1;
+       cfile.ref_time_count++;
+  } else {
+    frame->flags.ref_time=0;
+    cfile.ref_time_count--;
+  }
+  cf_reftime_packets(&cfile);
+  if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
+    new_packet_list_freeze();
+    cfile.displayed_count--;
+    new_packet_list_recreate_visible_rows();
+    new_packet_list_thaw();
+  }
+  new_packet_list_queue_draw();
 }
 
 
@@ -720,8 +719,8 @@ static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_
     case(ESD_BTN_YES):
         timestamp_set_type(TS_RELATIVE);
         recent.gui_time_format  = TS_RELATIVE;
-        cf_timestamp_auto_precision(&cfile);
-        new_packet_list_queue_draw();
+               cf_timestamp_auto_precision(&cfile);
+               new_packet_list_queue_draw();
         break;
     case(ESD_BTN_NO):
         break;
@@ -731,7 +730,7 @@ static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_
 
     if (cfile.current_frame) {
       set_frame_reftime(!cfile.current_frame->flags.ref_time,
-      cfile.current_frame, cfile.current_row);
+                       cfile.current_frame, cfile.current_row);
     }
 }
 
@@ -739,31 +738,31 @@ static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_
 void
 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
 {
-    static GtkWidget *reftime_dialog = NULL;
-
-    switch(action){
-    case REFTIME_TOGGLE:
-        if (cfile.current_frame) {
-            if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
-                reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
-                    "%sSwitch to the appropriate Time Display Format?%s\n\n"
-                    "Time References don't work well with the currently selected Time Display Format.\n\n"
-                    "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
-                    simple_dialog_primary_start(), simple_dialog_primary_end());
-                simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
-            } else {
-                set_frame_reftime(!cfile.current_frame->flags.ref_time,
-                                  cfile.current_frame, cfile.current_row);
-            }
+  static GtkWidget *reftime_dialog = NULL;
+
+  switch(action){
+  case REFTIME_TOGGLE:
+    if (cfile.current_frame) {
+        if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
+            reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
+                "%sSwitch to the appropriate Time Display Format?%s\n\n"
+                "Time References don't work well with the currently selected Time Display Format.\n\n"
+                "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
+                simple_dialog_primary_start(), simple_dialog_primary_end());
+            simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
+        } else {
+            set_frame_reftime(!cfile.current_frame->flags.ref_time,
+                              cfile.current_frame, cfile.current_row);
         }
-        break;
-    case REFTIME_FIND_NEXT:
-        cf_find_packet_time_reference(&cfile, SD_FORWARD);
-        break;
-    case REFTIME_FIND_PREV:
-        cf_find_packet_time_reference(&cfile, SD_BACKWARD);
-        break;
     }
+    break;
+  case REFTIME_FIND_NEXT:
+    cf_find_packet_time_reference(&cfile, SD_FORWARD);
+    break;
+  case REFTIME_FIND_PREV:
+    cf_find_packet_time_reference(&cfile, SD_BACKWARD);
+    break;
+  }
 }
 
 void
@@ -876,47 +875,47 @@ tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
 }
 
 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
-    if (cfile.edt->tree)
-        collapse_all_tree(cfile.edt->tree, tree_view_gbl);
+  if (cfile.edt->tree)
+    collapse_all_tree(cfile.edt->tree, tree_view_gbl);
 }
 
 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
-    if (cfile.edt->tree)
-        expand_all_tree(cfile.edt->tree, tree_view_gbl);
+  if (cfile.edt->tree)
+    expand_all_tree(cfile.edt->tree, tree_view_gbl);
 }
 
 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
 {
-    if (cfile.finfo_selected) {
-        column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
-                                cfile.finfo_selected->hfinfo->abbrev,0);
-        /* Recreate the packet list according to new preferences */
-        new_packet_list_recreate ();
-        if (!prefs.gui_use_pref_save) {
-            prefs_main_write();
-        }
-        cfile.cinfo.columns_changed = FALSE; /* Reset value */
+  if (cfile.finfo_selected) {
+    column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
+                            cfile.finfo_selected->hfinfo->abbrev,0);
+    /* Recreate the packet list according to new preferences */
+    new_packet_list_recreate ();
+    if (!prefs.gui_use_pref_save) {
+      prefs_main_write();
     }
+    cfile.cinfo.columns_changed = FALSE; /* Reset value */
+  }
 }
 
 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
-    GtkTreePath  *path;
+  GtkTreePath  *path;
 
-    path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
-    if(path) {
-        /* the mouse position is at an entry, expand that one */
-        gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
-        gtk_tree_path_free(path);
-    }
+  path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
+  if(path) {
+    /* the mouse position is at an entry, expand that one */
+    gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
+    gtk_tree_path_free(path);
+  }
 }
 
 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
-    if (cfile.edt->tree) {
-        guint32 tmp = gbl_resolv_flags;
-        gbl_resolv_flags = RESOLV_ALL;
-        proto_tree_draw(cfile.edt->tree, tree_view_gbl);
-        gbl_resolv_flags = tmp;
-    }
+  if (cfile.edt->tree) {
+    guint32 tmp = gbl_resolv_flags;
+    gbl_resolv_flags = RESOLV_ALL;
+    proto_tree_draw(cfile.edt->tree, tree_view_gbl);
+    gbl_resolv_flags = tmp;
+  }
 }
 
 static void
@@ -930,100 +929,100 @@ main_set_for_capture_file(gboolean have_capture_file_in)
 gboolean
 main_do_quit(void)
 {
-    /* get the current geometry, before writing it to disk */
-    main_save_window_geometry(top_level);
-
-    /* write user's recent file to disk
-     * It is no problem to write this file, even if we do not quit */
-    write_profile_recent();
-    write_recent();
-
-    /* XXX - should we check whether the capture file is an
-       unsaved temporary file for a live capture and, if so,
-       pop up a "do you want to exit without saving the capture
-       file?" dialog, and then just return, leaving said dialog
-       box to forcibly quit if the user clicks "OK"?
-
-       If so, note that this should be done in a subroutine that
-       returns TRUE if we do so, and FALSE otherwise, and if it
-       returns TRUE we should return TRUE without nuking anything.
-
-       Note that, if we do that, we might also want to check if
-       an "Update list of packets in real time" capture is in
-       progress and, if so, ask whether they want to terminate
-       the capture and discard it, and return TRUE, before nuking
-       any child capture, if they say they don't want to do so. */
+       /* get the current geometry, before writing it to disk */
+       main_save_window_geometry(top_level);
 
-#ifdef HAVE_LIBPCAP
-    /* Nuke any child capture in progress. */
-    capture_kill_child(&global_capture_opts);
-#endif
+       /* write user's recent file to disk
+        * It is no problem to write this file, even if we do not quit */
+       write_profile_recent();
+       write_recent();
 
-    /* Are we in the middle of reading a capture? */
-    if (cfile.state == FILE_READ_IN_PROGRESS) {
-        /* Yes, so we can't just close the file and quit, as
-           that may yank the rug out from under the read in
-           progress; instead, just set the state to
-           "FILE_READ_ABORTED" and return - the code doing the read
-           will check for that and, if it sees that, will clean
-           up and quit. */
-        cfile.state = FILE_READ_ABORTED;
-
-        /* Say that the window should *not* be deleted;
-           that'll be done by the code that cleans up. */
-        return TRUE;
-    } else {
-        /* Close any capture file we have open; on some OSes, you
-           can't unlink a temporary capture file if you have it
-           open.
-           "cf_close()" will unlink it after closing it if
-           it's a temporary file.
-
-           We do this here, rather than after the main loop returns,
-           as, after the main loop returns, the main window may have
-           been destroyed (if this is called due to a "destroy"
-           even on the main window rather than due to the user
-           selecting a menu item), and there may be a crash
-           or other problem when "cf_close()" tries to
-           clean up stuff in the main window.
-
-           XXX - is there a better place to put this?
-           Or should we have a routine that *just* closes the
-           capture file, and doesn't do anything with the UI,
-           which we'd call here, and another routine that
-           calls that routine and also cleans up the UI, which
-           we'd call elsewhere? */
-        cf_close(&cfile);
-
-        /* Exit by leaving the main loop, so that any quit functions
-           we registered get called. */
-        gtk_main_quit();
-
-        /* Say that the window should be deleted. */
-        return FALSE;
-    }
+       /* XXX - should we check whether the capture file is an
+          unsaved temporary file for a live capture and, if so,
+          pop up a "do you want to exit without saving the capture
+          file?" dialog, and then just return, leaving said dialog
+          box to forcibly quit if the user clicks "OK"?
+
+          If so, note that this should be done in a subroutine that
+          returns TRUE if we do so, and FALSE otherwise, and if it
+          returns TRUE we should return TRUE without nuking anything.
+
+          Note that, if we do that, we might also want to check if
+          an "Update list of packets in real time" capture is in
+          progress and, if so, ask whether they want to terminate
+          the capture and discard it, and return TRUE, before nuking
+          any child capture, if they say they don't want to do so. */
+
+#ifdef HAVE_LIBPCAP
+       /* Nuke any child capture in progress. */
+       capture_kill_child(&global_capture_opts);
+#endif
+
+       /* Are we in the middle of reading a capture? */
+       if (cfile.state == FILE_READ_IN_PROGRESS) {
+               /* Yes, so we can't just close the file and quit, as
+                  that may yank the rug out from under the read in
+                  progress; instead, just set the state to
+                  "FILE_READ_ABORTED" and return - the code doing the read
+                  will check for that and, if it sees that, will clean
+                  up and quit. */
+               cfile.state = FILE_READ_ABORTED;
+
+               /* Say that the window should *not* be deleted;
+                  that'll be done by the code that cleans up. */
+               return TRUE;
+       } else {
+               /* Close any capture file we have open; on some OSes, you
+                  can't unlink a temporary capture file if you have it
+                  open.
+                  "cf_close()" will unlink it after closing it if
+                  it's a temporary file.
+
+                  We do this here, rather than after the main loop returns,
+                  as, after the main loop returns, the main window may have
+                  been destroyed (if this is called due to a "destroy"
+                  even on the main window rather than due to the user
+                  selecting a menu item), and there may be a crash
+                  or other problem when "cf_close()" tries to
+                  clean up stuff in the main window.
+
+                  XXX - is there a better place to put this?
+                  Or should we have a routine that *just* closes the
+                  capture file, and doesn't do anything with the UI,
+                  which we'd call here, and another routine that
+                  calls that routine and also cleans up the UI, which
+                  we'd call elsewhere? */
+               cf_close(&cfile);
+
+               /* Exit by leaving the main loop, so that any quit functions
+                  we registered get called. */
+               gtk_main_quit();
+
+               /* Say that the window should be deleted. */
+               return FALSE;
+       }
 }
 
 static gboolean
 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
 {
-    gpointer dialog;
-
-    if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
-        gtk_window_present(GTK_WINDOW(top_level));
-        /* user didn't saved his current file, ask him */
-        dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
-                    ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
-                    "%sSave capture file before program quit?%s\n\n"
-                    "If you quit the program without saving, your capture data will be discarded.",
-                    simple_dialog_primary_start(), simple_dialog_primary_end());
-        simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
-        return TRUE;
-    } else {
-        /* unchanged file, just exit */
-        /* "main_do_quit()" indicates whether the main window should be deleted. */
-        return main_do_quit();
-    }
+  gpointer dialog;
+
+  if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
+    gtk_window_present(GTK_WINDOW(top_level));
+    /* user didn't saved his current file, ask him */
+    dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
+                ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
+                "%sSave capture file before program quit?%s\n\n"
+                "If you quit the program without saving, your capture data will be discarded.",
+                simple_dialog_primary_start(), simple_dialog_primary_end());
+    simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
+    return TRUE;
+  } else {
+    /* unchanged file, just exit */
+    /* "main_do_quit()" indicates whether the main window should be deleted. */
+    return main_do_quit();
+  }
 }
 
 
@@ -1117,18 +1116,18 @@ file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
 {
   gpointer dialog;
 
-    if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
+  if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
        /* user didn't saved his current file, ask him */
-        dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
-                      ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
-                       "%sSave capture file before program quit?%s\n\n"
-                       "If you quit the program without saving, your capture data will be discarded.",
-                       simple_dialog_primary_start(), simple_dialog_primary_end());
-        simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
-    } else {
-        /* unchanged file, just exit */
-        main_do_quit();
-    }
+       dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
+                  ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
+                   "%sSave capture file before program quit?%s\n\n"
+                   "If you quit the program without saving, your capture data will be discarded.",
+                   simple_dialog_primary_start(), simple_dialog_primary_end());
+       simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
+  } else {
+    /* unchanged file, just exit */
+    main_do_quit();
+  }
 }
 
 static void
@@ -1318,8 +1317,8 @@ cmdarg_err_cont(const char *fmt, ...)
 static gboolean
 tap_update_cb(gpointer data _U_)
 {
-    draw_tap_listeners(FALSE);
-    return TRUE;
+       draw_tap_listeners(FALSE);
+       return TRUE;
 }
 
 /* Restart the tap update display timer with new configured interval */
@@ -1332,18 +1331,18 @@ void reset_tap_update_timer(void)
 void
 protect_thread_critical_region(void)
 {
-    /* Threading support for TAP:s removed
-     * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
-     * See the commit for removed code:
-     * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
-     */
+       /* Threading support for TAP:s removed
+        * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
+        * See the commit for removed code:
+        * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
+        */
 }
 void
 unprotect_thread_critical_region(void)
 {
-    /* Threading support for TAP:s removed
-     * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
-     */
+       /* Threading support for TAP:s removed
+        * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
+        */
 
 }
 
@@ -1358,9 +1357,9 @@ resolv_update_cb(gpointer data _U_)
   /* Anything new show up? */
   if (host_name_lookup_process(NULL)) {
     if (gtk_widget_get_window(pkt_scrollw))
-      gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
+       gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
     if (gtk_widget_get_window(tv_scrollw))
-      gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
+       gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
   }
 
   /* Always check. Even if we don't do async lookups we could still get
@@ -1403,9 +1402,6 @@ npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
 static void
 main_cf_cb_file_closing(capture_file *cf)
 {
-#ifdef HAVE_LIBPCAP
-    int i;
-#endif
 
     /* if we have more than 10000 packets, show a splash screen while closing */
     /* XXX - don't know a better way to decide whether to show or not,
@@ -1424,14 +1420,6 @@ main_cf_cb_file_closing(capture_file *cf)
     destroy_packet_wins();
     file_save_as_destroy();
 
-#ifdef HAVE_LIBPCAP
-    if (global_capture_opts.ifaces && global_capture_opts.ifaces->len > 0) {
-        for (i = (int)global_capture_opts.ifaces->len-1; i >= 0; i--) {
-            global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
-        }
-    } 
-#endif
-    
     /* Restore the standard title bar message. */
     set_main_window_name("The Wireshark Network Analyzer");
 
@@ -1478,7 +1466,7 @@ main_cf_cb_file_read_finished(capture_file *cf)
         add_menu_recent_capture_file(cf->filename);
 
         /* Remember folder for next Open dialog and save it in recent */
-        dir_path = get_dirname(g_strdup(cf->filename));
+       dir_path = get_dirname(g_strdup(cf->filename));
         set_last_open_dir(dir_path);
         g_free(dir_path);
     }
@@ -2047,7 +2035,6 @@ main(int argc, char *argv[])
   char                *gdp_path, *dp_path;
   int                  err;
 #ifdef HAVE_LIBPCAP
-  int                  error;
   gboolean             start_capture = FALSE;
   gboolean             list_link_layer_types = FALSE;
   GList               *if_list;
@@ -2365,28 +2352,28 @@ main(int argc, char *argv[])
   /* We might want to have component specific log levels later ... */
 
   log_flags =
-            G_LOG_LEVEL_ERROR|
-            G_LOG_LEVEL_CRITICAL|
-            G_LOG_LEVEL_WARNING|
-            G_LOG_LEVEL_MESSAGE|
-            G_LOG_LEVEL_INFO|
-            G_LOG_LEVEL_DEBUG|
-            G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
+                   G_LOG_LEVEL_ERROR|
+                   G_LOG_LEVEL_CRITICAL|
+                   G_LOG_LEVEL_WARNING|
+                   G_LOG_LEVEL_MESSAGE|
+                   G_LOG_LEVEL_INFO|
+                   G_LOG_LEVEL_DEBUG|
+                   G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
 
   g_log_set_handler(NULL,
-            log_flags,
-            console_log_handler, NULL /* user_data */);
+                   log_flags,
+                   console_log_handler, NULL /* user_data */);
   g_log_set_handler(LOG_DOMAIN_MAIN,
-            log_flags,
-            console_log_handler, NULL /* user_data */);
+                   log_flags,
+                   console_log_handler, NULL /* user_data */);
 
 #ifdef HAVE_LIBPCAP
   g_log_set_handler(LOG_DOMAIN_CAPTURE,
-            log_flags,
-            console_log_handler, NULL /* user_data */);
+                   log_flags,
+                   console_log_handler, NULL /* user_data */);
   g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
-            log_flags,
-            console_log_handler, NULL /* user_data */);
+                   log_flags,
+                   console_log_handler, NULL /* user_data */);
 
   /* Set the initial values in the capture options. This might be overwritten
      by preference settings and then again by the command line parameters. */
@@ -2420,7 +2407,7 @@ main(int argc, char *argv[])
      dissectors, and we must do it before we read the preferences, in
      case any dissectors register preferences. */
   epan_init(register_all_protocols,register_all_protocol_handoffs,
-            splash_update, (gpointer) splash_win,
+           splash_update, (gpointer) splash_win,
             failure_alert_box,open_failure_alert_box,read_failure_alert_box,
             write_failure_alert_box);
 
@@ -2430,8 +2417,8 @@ main(int argc, char *argv[])
      as the "-z" argument can specify a registered tap. */
 
   /* we register the plugin taps before the other taps because
-     stats_tree taps plugins will be registered as tap listeners
-     by stats_tree_stat.c and need to registered before that */
+         stats_tree taps plugins will be registered as tap listeners
+         by stats_tree_stat.c and need to registered before that */
 
 #ifdef HAVE_PLUGINS
   register_all_plugin_tap_listeners();
@@ -2460,11 +2447,6 @@ main(int argc, char *argv[])
   /* Fill in capture options with values from the preferences */
   prefs_to_capture_opts();
 
-#ifdef HAVE_LIBPCAP
-  if (global_capture_opts.all_ifaces->len == 0) {
-    scan_local_interfaces(&global_capture_opts, &error);
-  }
-#endif
   /* Now get our args */
   while ((opt = getopt(argc, argv, optstring)) != -1) {
     switch (opt) {
@@ -2475,6 +2457,7 @@ main(int argc, char *argv[])
       case 'f':        /* capture filter */
       case 'k':        /* Start capture immediately */
       case 'H':        /* Hide capture info dialog box */
+      case 'i':        /* Use interface xxx */
       case 'p':        /* Don't capture in promiscuous mode */
 #ifdef HAVE_PCAP_CREATE
       case 'I':        /* Capture in monitor mode, if available */
@@ -2504,25 +2487,13 @@ main(int argc, char *argv[])
         break;
 #endif
 
-#ifdef HAVE_LIBPCAP
-      case 'i':       /* Use interface xxx */
-        status = capture_opts_select_iface(&global_capture_opts, optarg);
-        if (status != 0) {
-            exit(status);
-        }
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
-        
       /*** all non capture option specific ***/
       case 'C':
         /* Configuration profile settings were already processed just ignore them this time*/
-        break;
+       break;
       case 'd':
-        dfilter = optarg;
-        break;
+       dfilter = optarg;
+       break;
       case 'j':        /* Search backwards for a matching packet from filter in option J */
         jump_backwards = TRUE;
         break;
@@ -2561,7 +2532,7 @@ main(int argc, char *argv[])
         badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
         if (badopt != '\0') {
           cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
-            badopt);
+                       badopt);
           exit(1);
         }
         break;
@@ -2586,7 +2557,7 @@ main(int argc, char *argv[])
             case PREFS_SET_NO_SUCH_PREF:
             case PREFS_SET_OBSOLETE:
               cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
-                optarg);
+                   optarg);
               exit(1);
               break;
             default:
@@ -2595,7 +2566,7 @@ main(int argc, char *argv[])
           break;
         case PREFS_SET_OBSOLETE:
           cmdarg_err("-o flag \"%s\" specifies obsolete preference",
-            optarg);
+                       optarg);
           exit(1);
           break;
         default:
@@ -2606,9 +2577,9 @@ main(int argc, char *argv[])
         /* Path settings were already processed just ignore them this time*/
         break;
       case 'r':        /* Read capture file xxx */
-        /* We may set "last_open_dir" to "cf_name", and if we change
-        "last_open_dir" later, we free the old value, so we have to
-        set "cf_name" to something that's been allocated. */
+       /* We may set "last_open_dir" to "cf_name", and if we change
+          "last_open_dir" later, we free the old value, so we have to
+          set "cf_name" to something that's been allocated. */
         cf_name = g_strdup(optarg);
         break;
       case 'R':        /* Read file filter */
@@ -2659,11 +2630,11 @@ main(int argc, char *argv[])
            part of a tap filter.  Instead, we just add the argument
            to a list of stat arguments. */
         if (!process_stat_cmd_arg(optarg)) {
-          cmdarg_err("Invalid -z argument.");
-          cmdarg_err_cont("  -z argument must be one of :");
-          list_stat_cmd_args();
-          exit(1);
-        }
+         cmdarg_err("Invalid -z argument.");
+         cmdarg_err_cont("  -z argument must be one of :");
+         list_stat_cmd_args();
+         exit(1);
+       }
         break;
       default:
       case '?':        /* Bad flag - print usage message */
@@ -2750,18 +2721,23 @@ main(int argc, char *argv[])
        sense? */
     if (global_capture_opts.multi_files_on) {
       /* Ring buffer works only under certain conditions:
-      a) ring buffer does not work with temporary files;
-      b) real_time_mode and multi_files_on are mutually exclusive -
-         real_time_mode takes precedence;
-      c) it makes no sense to enable the ring buffer if the maximum
-         file size is set to "infinite". */
+        a) ring buffer does not work with temporary files;
+        b) real_time_mode and multi_files_on are mutually exclusive -
+           real_time_mode takes precedence;
+        c) it makes no sense to enable the ring buffer if the maximum
+           file size is set to "infinite". */
       if (global_capture_opts.save_file == NULL) {
-        cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
-        global_capture_opts.multi_files_on = FALSE;
+       cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
+       global_capture_opts.multi_files_on = FALSE;
       }
+/*      if (global_capture_opts.real_time_mode) {
+       cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
+       global_capture_opts.multi_files_on = FALSE;
+      }*/
       if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
-        cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
-        /* XXX - this must be redesigned as the conditions changed */
+       cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
+/* XXX - this must be redesigned as the conditions changed */
+/*     global_capture_opts.multi_files_on = FALSE;*/
       }
     }
   }
@@ -2778,32 +2754,23 @@ main(int argc, char *argv[])
     /* Get the list of link-layer types for the capture devices. */
     if_capabilities_t *caps;
     guint i;
-    interface_t device;
-    for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+    interface_options interface_opts;
 
-      device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-      if (device.selected) {
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-        caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
-#else
-        caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
-#endif
-        if (caps == NULL) {
-          cmdarg_err("%s", err_str);
-          g_free(err_str);
-          exit(2);
-        }
-        if (caps->data_link_types == NULL) {
-          cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
-          exit(2);
-        }
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-        capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
-#else
-        capture_opts_print_if_capabilities(caps, device.name, FALSE);
-#endif
-        free_if_capabilities(caps);
+    for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+
+      interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
+      caps = capture_get_if_capabilities(interface_opts.name, interface_opts.monitor_mode, &err_str);
+      if (caps == NULL) {
+        cmdarg_err("%s", err_str);
+        g_free(err_str);
+        exit(2);
       }
+      if (caps->data_link_types == NULL) {
+        cmdarg_err("The capture device \"%s\" has no data link types.", interface_opts.name);
+        exit(2);
+      }
+      capture_opts_print_if_capabilities(caps, interface_opts.name, interface_opts.monitor_mode);
+      free_if_capabilities(caps);
     }
     exit(0);
   }
@@ -2818,20 +2785,53 @@ main(int argc, char *argv[])
   prefs_apply_all();
 
 #ifdef HAVE_LIBPCAP
-  if ((global_capture_opts.num_selected == 0) &&
+  if ((global_capture_opts.ifaces->len == 0) &&
       (prefs.capture_device != NULL)) {
-    guint i;
-    interface_t device;
-    for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-      device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-      if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
-        device.selected = TRUE;
-        global_capture_opts.num_selected++;
-        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);
-        break;
+    GList *curr, *combo_list;
+    gboolean found = FALSE;
+
+    if_list = capture_interface_list(&err, NULL);
+    if (g_list_length(if_list) > 0) {
+      combo_list = build_capture_combo_list(if_list, FALSE);
+      free_interface_list(if_list);
+      for (curr = combo_list; curr; curr = g_list_next(curr)) {
+        if (strcmp(curr->data, prefs.capture_device) == 0) {
+          found = TRUE;
+          break;
+        }
       }
     }
+    if (found) {
+      interface_options interface_opts;
+
+      interface_opts.name = g_strdup(get_if_name(prefs.capture_device));
+      interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
+      interface_opts.monitor_mode = prefs_capture_device_monitor_mode(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.snaplen = global_capture_opts.default_options.snaplen;
+      interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen;
+      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
+#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_insert_val(global_capture_opts.ifaces, 0, interface_opts);
+    }
   }
 #endif
 
@@ -2873,8 +2873,8 @@ main(int argc, char *argv[])
   recent_read_dynamic(&rf_path, &rf_open_errno);
   if (rf_path != NULL && rf_open_errno != 0) {
     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
-          "Could not open recent file\n\"%s\": %s.",
-          rf_path, g_strerror(rf_open_errno));
+                 "Could not open recent file\n\"%s\": %s.",
+                 rf_path, g_strerror(rf_open_errno));
   }
 
   color_filters_enable(recent.packet_list_colorize);
@@ -2996,15 +2996,15 @@ main(int argc, char *argv[])
           break;
         }
 
-        /* If the filename is not the absolute path, prepend the current dir. This happens
-           when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
-        if (!g_path_is_absolute(cf_name)) {
-          char *old_cf_name = cf_name;
-          char *pwd = g_get_current_dir();
-          cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
-          g_free(old_cf_name);
-          g_free(pwd);
-        }
+       /* If the filename is not the absolute path, prepend the current dir. This happens
+          when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
+       if (!g_path_is_absolute(cf_name)) {
+         char *old_cf_name = cf_name;
+         char *pwd = g_get_current_dir();
+         cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
+         g_free(old_cf_name);
+         g_free(pwd);
+       }
 
         /* Save the name of the containing directory specified in the
            path name, if any; we can write over cf_name, which is a
@@ -3019,7 +3019,7 @@ main(int argc, char *argv[])
           dfilter_free(rfcode);
         cfile.rfcode = NULL;
         show_main_window(FALSE);
-        /* Don't call check_and_warn_user_startup(): we did it above */
+       /* Don't call check_and_warn_user_startup(): we did it above */
         set_menus_for_capture_in_progress(FALSE);
         set_capture_if_dialog_for_capture_in_progress(FALSE);
       }
@@ -3039,10 +3039,10 @@ main(int argc, char *argv[])
       check_and_warn_user_startup(cf_name);
       if (capture_start(&global_capture_opts)) {
         /* The capture started.  Open stat windows; we do so after creating
-           the main window, to avoid GTK warnings, and after successfully
-           opening the capture file, so we know we have something to compute
-           stats on, and after registering all dissectors, so that MATE will
-           have registered its field array and we can have a tap filter with
+          the main window, to avoid GTK warnings, and after successfully
+          opening the capture file, so we know we have something to compute
+          stats on, and after registering all dissectors, so that MATE will
+          have registered its field array and we can have a tap filter with
            one of MATE's late-registered fields as part of the filter. */
         start_requested_stats();
       }
@@ -3121,9 +3121,9 @@ main(int argc, char *argv[])
 
 int _stdcall
 WinMain (struct HINSTANCE__ *hInstance,
-         struct HINSTANCE__ *hPrevInstance,
-         char               *lpszCmdLine,
-         int                 nCmdShow)
+        struct HINSTANCE__ *hPrevInstance,
+        char               *lpszCmdLine,
+        int                 nCmdShow)
 {
   INITCOMMONCONTROLSEX comm_ctrl;
 
@@ -3224,7 +3224,7 @@ destroy_console(void)
 
 static void
 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
-                    const char *message, gpointer user_data _U_)
+                   const char *message, gpointer user_data _U_)
 {
   time_t curr;
   struct tm *today;
@@ -3548,6 +3548,7 @@ main_widgets_show_or_hide(void)
     if (!have_capture_file) {
         if(welcome_pane) {
             gtk_widget_show(welcome_pane);
+            select_ifaces();
         }
     } else {
         gtk_widget_hide(welcome_pane);
@@ -3580,11 +3581,11 @@ static gboolean
 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
 {
     if (event->keyval == GDK_F8) {
-        new_packet_list_next();
-        return TRUE;
+       new_packet_list_next();
+       return TRUE;
     } else if (event->keyval == GDK_F7) {
-        new_packet_list_prev();
-        return TRUE;
+       new_packet_list_prev();
+       return TRUE;
     } else if (event->state & NO_SHIFT_MOD_MASK) {
         return FALSE; /* Skip control, alt, and other modifiers */
     /*
@@ -3594,12 +3595,12 @@ top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_dat
      * for values < 127.
      */
     } else if (isascii(event->keyval) && isprint(event->keyval)) {
-        /* Forward the keypress on to the display filter entry */
-        if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
-            gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
+       /* Forward the keypress on to the display filter entry */
+       if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
+           gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
             gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
-        }
-        return FALSE;
+       }
+       return FALSE;
     }
     return FALSE;
 }
@@ -3738,115 +3739,115 @@ prefs_to_capture_opts(void)
 
 static void copy_global_profile (const gchar *profile_name)
 {
-    char  *pf_dir_path, *pf_dir_path2, *pf_filename;
+   char  *pf_dir_path, *pf_dir_path2, *pf_filename;
 
-    if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
-        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-            "Can't create directory\n\"%s\":\n%s.",
-            pf_dir_path, g_strerror(errno));
+   if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
+     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                  "Can't create directory\n\"%s\":\n%s.",
+                  pf_dir_path, g_strerror(errno));
 
-        g_free(pf_dir_path);
-    }
+     g_free(pf_dir_path);
+   }
 
-    if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
-            &pf_dir_path, &pf_dir_path2) == -1) {
-        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-            "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
-            pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
+   if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
+                                &pf_dir_path, &pf_dir_path2) == -1) {
+     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                  "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
+                  pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
 
-        g_free(pf_filename);
-        g_free(pf_dir_path);
-        g_free(pf_dir_path2);
-    }
+     g_free(pf_filename);
+     g_free(pf_dir_path);
+     g_free(pf_dir_path2);
+   }
 }
 
 /* Change configuration profile */
 void change_configuration_profile (const gchar *profile_name)
 {
-    char  *gdp_path, *dp_path;
-    char  *rf_path;
-    int    rf_open_errno;
-
-    /* First check if profile exists */
-    if (!profile_exists(profile_name, FALSE)) {
-        if (profile_exists(profile_name, TRUE)) {
-           /* Copy from global profile */
-            copy_global_profile (profile_name);
-        } else {
-            /* No personal and no global profile exists */
-            return;
-        }
-    }
-
-    /* Then check if changing to another profile */
-    if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
-        return;
-    }
-
-    /* Get the current geometry, before writing it to disk */
-    main_save_window_geometry(top_level);
-
-    if (profile_exists(get_profile_name(), FALSE)) {
-        /* Write recent file for profile we are leaving, if it still exists */
-        write_profile_recent();
-    }
-
-    /* Set profile name and update the status bar */
-    set_profile_name (profile_name);
-    profile_bar_update ();
-    filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
+   char  *gdp_path, *dp_path;
+   char  *rf_path;
+   int    rf_open_errno;
+
+   /* First check if profile exists */
+   if (!profile_exists(profile_name, FALSE)) {
+     if (profile_exists(profile_name, TRUE)) {
+       /* Copy from global profile */
+       copy_global_profile (profile_name);
+     } else {
+       /* No personal and no global profile exists */
+       return;
+     }
+   }
+
+   /* Then check if changing to another profile */
+   if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
+     return;
+   }
+
+   /* Get the current geometry, before writing it to disk */
+   main_save_window_geometry(top_level);
+
+   if (profile_exists(get_profile_name(), FALSE)) {
+     /* Write recent file for profile we are leaving, if it still exists */
+     write_profile_recent();
+   }
+
+   /* Set profile name and update the status bar */
+   set_profile_name (profile_name);
+   profile_bar_update ();
+   filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
+
+   /* Reset current preferences and apply the new */
+   prefs_reset();
+   menu_prefs_reset();
+
+   (void) read_configuration_files (&gdp_path, &dp_path);
+
+   recent_read_profile_static(&rf_path, &rf_open_errno);
+   if (rf_path != NULL && rf_open_errno != 0) {
+     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                 "Could not open common recent file\n\"%s\": %s.",
+                 rf_path, g_strerror(rf_open_errno));
+   }
+   if (recent.gui_fileopen_remembered_dir &&
+       test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
+     set_last_open_dir(recent.gui_fileopen_remembered_dir);
+   }
+   timestamp_set_type (recent.gui_time_format);
+   timestamp_set_seconds_type (recent.gui_seconds_format);
+   color_filters_enable(recent.packet_list_colorize);
 
-    /* Reset current preferences and apply the new */
-    prefs_reset();
-    menu_prefs_reset();
+   prefs_to_capture_opts();
+   prefs_apply_all();
+   macros_post_update();
 
-    (void) read_configuration_files (&gdp_path, &dp_path);
+   /* Update window view and redraw the toolbar */
+   update_main_window_title();
+   filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
+   toolbar_redraw_all();
 
-    recent_read_profile_static(&rf_path, &rf_open_errno);
-    if (rf_path != NULL && rf_open_errno != 0) {
-        simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
-            "Could not open common recent file\n\"%s\": %s.",
-            rf_path, g_strerror(rf_open_errno));
-    }
-    if (recent.gui_fileopen_remembered_dir &&
-        test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
-        set_last_open_dir(recent.gui_fileopen_remembered_dir);
-    }
-    timestamp_set_type (recent.gui_time_format);
-    timestamp_set_seconds_type (recent.gui_seconds_format);
-    color_filters_enable(recent.packet_list_colorize);
-
-    prefs_to_capture_opts();
-    prefs_apply_all();
-    macros_post_update();
-
-    /* Update window view and redraw the toolbar */
-    update_main_window_title();
-    filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
-    toolbar_redraw_all();
-
-    /* Enable all protocols and disable from the disabled list */
-    proto_enable_all();
-    if (gdp_path == NULL && dp_path == NULL) {
-        set_disabled_protos_list();
-    }
+   /* Enable all protocols and disable from the disabled list */
+   proto_enable_all();
+   if (gdp_path == NULL && dp_path == NULL) {
+     set_disabled_protos_list();
+   }
 
-    /* Reload color filters */
-    color_filters_reload();
+   /* Reload color filters */
+   color_filters_reload();
 
-    /* Reload list of interfaces on welcome page */
-    welcome_if_panel_reload();
+   /* Reload list of interfaces on welcome page */
+   welcome_if_panel_reload();
 
-    /* Recreate the packet list according to new preferences */
-    new_packet_list_recreate ();
-    cfile.cinfo.columns_changed = FALSE; /* Reset value */
-    user_font_apply();
+   /* Recreate the packet list according to new preferences */
+   new_packet_list_recreate ();
+   cfile.cinfo.columns_changed = FALSE; /* Reset value */
+   user_font_apply();
 
-    /* Update menus with new recent values */
-    menu_recent_read_finished();
+   /* Update menus with new recent values */
+   menu_recent_read_finished();
 
-    /* Reload pane geometry, must be done after recreating the list */
-    main_pane_load_window_geometry();
+   /* Reload pane geometry, must be done after recreating the list */
+   main_pane_load_window_geometry();
 }
 
 /** redissect packets and update UI */
@@ -3855,313 +3856,3 @@ void redissect_packets(void)
     cf_redissect_packets(&cfile);
     status_expert_update();
 }
-
-#ifdef HAVE_LIBPCAP
-guint get_interface_type(gchar *name, gchar *description)
-{
-#if defined(__linux__)
-    ws_statb64 statb;
-    char *wireless_path;
-#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 (description && (strstr(description,"generic dialup") != NULL ||
-            strstr(description,"PPP/SLIP") != NULL )) {
-        return IF_DIALUP;
-    } else if (description && (strstr(description,"Wireless") != NULL ||
-            strstr(description,"802.11") != NULL)) {
-        return IF_WIRELESS;
-    } else if (description && strstr(description,"AirPcap") != NULL ||
-            strstr(name,"airpcap")) {
-        return IF_AIRPCAP;
-    } else if (description && strstr(description, "Bluetooth") != NULL ) {
-        return IF_BLUETOOTH;
-    }
-#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(name, "en1") == 0) {
-        return IF_WIRELESS;
-    }
-    /*
-     * 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", name);
-    if (wireless_path != NULL) {
-        if (ws_stat64(wireless_path, &statb) == 0) {
-            g_free(wireless_path);
-            return IF_WIRELESS;
-        }
-    }
-    /*
-     * Bluetooth devices.
-     *
-     * XXX - this is for raw Bluetooth capture; what about IP-over-Bluetooth
-     * devices?
-     */
-    if ( strstr(name,"bluetooth") != NULL) {
-        return IF_BLUETOOTH;
-    }
-
-    /*
-     * USB devices.
-     */
-    if ( strstr(name,"usbmon") != NULL ) {
-        return IF_USB;
-    }
-#endif
-    /*
-     * 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(name, "vmnet", 5) == 0) {
-        return IF_VIRTUAL;
-    }
-
-    if ( g_ascii_strncasecmp(name, "vmxnet", 6) == 0) {
-        return IF_VIRTUAL;
-    }
-
-    if (description && strstr(description, "VMware") != NULL ) {
-        return IF_VIRTUAL;
-    }
-
-    return IF_WIRED;
-}
-
-void
-scan_local_interfaces(capture_options* capture_opts, int *error)
-{
-    GList             *if_entry, *lt_entry, *if_list;
-    if_info_t         *if_info, *temp;
-    char              *if_string="";
-    gchar             *descr, *str, *err_str = NULL;
-    if_capabilities_t *caps=NULL;
-    gint              linktype_count;
-    cap_settings_t    cap_settings;
-    GSList            *curr_addr;
-    int               ips = 0, i, err;
-    guint             count = 0;
-    if_addr_t         *addr, *temp_addr;
-    link_row          *link = NULL;
-    data_link_info_t  *data_link_info;
-    interface_t       device;
-    GString           *ip_str;
-
-    if (capture_opts->all_ifaces->len > 0) {
-        for (i = (int)capture_opts->all_ifaces->len-1; i >= 0; i--) {
-            device = g_array_index(capture_opts->all_ifaces, interface_t, i);
-            if (device.local) {
-                capture_opts->all_ifaces = g_array_remove_index(capture_opts->all_ifaces, i);
-            }
-        }
-    }
-    /* Scan through the list and build a list of strings to display. */
-    if_list = capture_interface_list(&err, &err_str);
-    *error = err;
-    count = 0;
-    for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
-        if_info = if_entry->data;
-        ip_str = g_string_new("");
-        str = "";
-        ips = 0;
-        device.name = g_strdup(if_info->name);
-        device.hidden = FALSE;
-        device.locked = FALSE;
-        temp = g_malloc0(sizeof(if_info_t));
-        temp->name = g_strdup(if_info->name);
-        temp->description = g_strdup(if_info->description);
-        temp->loopback = if_info->loopback;
-        /* Is this interface hidden and, if so, should we include it anyway? */
-
-        /* Do we have a user-supplied description? */
-        descr = capture_dev_user_descr_find(if_info->name);
-        if (descr != NULL) {
-            /* Yes, we have a user-supplied description; use it. */
-            if_string = g_strdup_printf("%s: %s", descr, if_info->name);
-            g_free(descr);
-        } else {
-            /* No, we don't have a user-supplied description; did we get
-            one from the OS or libpcap? */
-            if (if_info->description != NULL) {
-                /* Yes - use it. */
-                if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
-            } else {
-                /* No. */
-                if_string = g_strdup(if_info->name);
-            }
-        }
-        if (if_info->loopback) {
-            device.display_name = g_strdup_printf("%s (loopback)", if_string);
-        } else {
-            device.display_name = g_strdup(if_string);
-        }
-        device.selected = FALSE;
-        if (prefs_is_capture_device_hidden(if_info->name)) {
-            device.hidden = TRUE;
-        } 
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-        device.buffer = capture_opts->default_options.buffer_size;
-#endif
-        device.pmode = capture_opts->default_options.promisc_mode;
-        device.has_snaplen = capture_opts->default_options.has_snaplen;
-        device.snaplen = capture_opts->default_options.snaplen;
-        device.type = get_interface_type(if_info->name, if_info->description);
-        device.cfilter = g_strdup(capture_opts->default_options.cfilter);
-        cap_settings = capture_get_cap_settings(if_info->name);
-        caps = capture_get_if_capabilities(if_info->name, cap_settings.monitor_mode, NULL);
-        for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
-            temp_addr = g_malloc0(sizeof(if_addr_t));
-            if (ips != 0) {
-                g_string_append(ip_str, "\n");
-            }
-            addr = (if_addr_t *)curr_addr->data;
-            if (addr) {
-                temp_addr->ifat_type = addr->ifat_type;
-                switch (addr->ifat_type) {
-                    case IF_AT_IPv4:
-                        temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
-                        g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
-                        break;
-                    case IF_AT_IPv6:
-                        memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
-                        g_string_append(ip_str,  ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
-                        break;
-                    default:
-                        /* In case we add non-IP addresses */
-                        break;
-                }
-            } else {
-                g_free(temp_addr);
-                temp_addr = NULL;
-            }
-            if (temp_addr) {
-                temp->addrs = g_slist_append(temp->addrs, temp_addr);
-            }
-        }
-#ifdef HAVE_PCAP_REMOTE
-        device.remote_opts.src_type = CAPTURE_IFLOCAL;
-#endif
-        linktype_count = 0;
-        device.links = NULL;
-        if (caps != NULL) {
-#ifdef HAVE_PCAP_CREATE
-            device.monitor_mode_enabled = cap_settings.monitor_mode;
-            device.monitor_mode_supported = caps->can_set_rfmon;
-#endif 
-            for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
-                data_link_info = lt_entry->data;
-                if (data_link_info->description != NULL) {
-                    str = g_strdup_printf("%s", data_link_info->description);
-                } else {
-                    str = g_strdup_printf("%s (not supported)", data_link_info->name);
-                }
-                if (linktype_count == 0) {
-                    device.active_dlt = data_link_info->dlt;
-                }
-                link = (link_row *)g_malloc(sizeof(link_row));
-                link->dlt = data_link_info->dlt;
-                link->name = g_strdup(str);
-                device.links = g_list_append(device.links, link);
-                linktype_count++;
-            }
-        } else {
-            cap_settings.monitor_mode = FALSE;
-#ifdef HAVE_PCAP_CREATE
-            device.monitor_mode_enabled = FALSE;
-            device.monitor_mode_supported = FALSE;
-#endif
-            device.active_dlt = -1;
-        }
-        device.addresses = g_strdup(ip_str->str);
-        device.no_addresses = ips;
-        device.local = TRUE;
-        device.if_info = *temp;
-        device.last_packets = 0;
-
-        if (capture_opts->all_ifaces->len <= count) {
-            g_array_append_val(capture_opts->all_ifaces, device);
-            count = capture_opts->all_ifaces->len;
-        } else {
-            g_array_insert_val(capture_opts->all_ifaces, count, device);
-        }
-        if (caps != NULL) {
-            free_if_capabilities(caps);
-        }
-            
-        g_string_free(ip_str, TRUE);
-        count++;
-    }
-    free_interface_list(if_list);
-}
-
-void hide_interface(gchar* new_hide)
-{
-    gchar       *tok;
-    guint       i;
-    interface_t device;
-    gboolean    found = FALSE;
-    GList       *hidden_devices = NULL, *entry;
-    if (new_hide != NULL) {
-        for (tok = strtok (new_hide, ","); tok; tok = strtok(NULL, ",")) {
-            hidden_devices = g_list_append(hidden_devices, tok);
-        }
-    }
-    for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-        device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-        found = FALSE;
-        for (entry = hidden_devices; entry != NULL; entry = g_list_next(entry)) {
-            if (strcmp(entry->data, device.name)==0) {
-                device.hidden = TRUE;
-                if (device.selected) {
-                    device.selected = FALSE;
-                    global_capture_opts.num_selected--;
-                }
-                found = TRUE;
-                break;
-            }
-        } 
-        if (!found) {
-            device.hidden = 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);
-    }
-}
-#endif
index e86d1c0f0fbd1ee63fd42bebdeb59b562da10cda..47a6599b06fcbd70a28298d435be0c10d9f31707 100644 (file)
@@ -26,7 +26,6 @@
 #define __MAIN_H__
 
 #include "globals.h"
-#include "capture_opts.h"
 
 /** @defgroup main_window_group Main window
  * The main window has the following submodules:
@@ -333,10 +332,10 @@ extern gboolean main_filter_packets(capture_file *cf, const gchar *dftext,
 #ifdef _WIN32
 /** Win32 only: Create a console. Beware: cannot be closed again. */
 extern void create_console(void);
+#endif
 
 /** Restart the tap update display timer with new configured interval */
 extern void reset_tap_update_timer(void);
-#endif
 
 /** Fill in capture options with values from the preferences */
 extern void prefs_to_capture_opts(void);
@@ -352,7 +351,4 @@ extern GList *get_ip_address_list_from_packet_list_row(gpointer data);
 
 extern GtkWidget *pkt_scrollw;
 
-void hide_interface(gchar* new_hide);
-
-
 #endif /* __MAIN_H__ */
index 166e1b9cb6e03442dbf7926dfae7ff741d2e3645..1983a874b845e973708ebd763345d458bf324712 100644 (file)
@@ -86,6 +86,8 @@
 #endif
 
 /* XXX */
+extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg);
+
 static GtkWidget *welcome_hb = NULL;
 static GtkWidget *header_lb = NULL;
 /* Foreground colors are set using Pango markup */
@@ -106,8 +108,10 @@ static GdkColor topic_item_entered_bg = { 0, 0xd3d3, 0xd8d8, 0xdada };
 #endif
 static GtkWidget *welcome_file_panel_vb = NULL;
 #ifdef HAVE_LIBPCAP
+static GtkWidget *welcome_if_panel_vb = NULL;
 static GtkWidget *if_view = NULL;
 static GtkWidget *swindow;
+static GArray *interfaces = NULL;
 #endif
 
 static GSList *status_messages = NULL;
@@ -210,9 +214,9 @@ static gboolean
 welcome_item_enter_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_)
 {
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_entered_bg);
+       gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_entered_bg);
 #else
-    gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_entered_bg);
+       gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_entered_bg);
 #endif
     return FALSE;
 }
@@ -223,7 +227,7 @@ static gboolean
 welcome_item_leave_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_)
 {
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg);
+       gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg);
 #else
     gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg);
 #endif
@@ -250,12 +254,12 @@ welcome_button(const gchar *stock_item,
     eb = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(eb), item_hb);
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg);
+       gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg);
 #else
     gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg);
 #endif
     if(tooltip != NULL) {
-        gtk_widget_set_tooltip_text(eb, tooltip);
+               gtk_widget_set_tooltip_text(eb, tooltip);
     }
 
     g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), NULL);
@@ -348,7 +352,7 @@ welcome_header_new(void)
     eb = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(eb), item_vb);
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_header_bar_bg);
+       gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_header_bar_bg);
 #else
     gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &header_bar_bg);
 #endif
@@ -356,7 +360,7 @@ welcome_header_new(void)
     gtk_box_pack_start(GTK_BOX(item_vb), item_hb, FALSE, FALSE, 10);
 
     /*icon = xpm_to_widget_from_parent(top_level, wssplash_xpm);*/
-    icon = xpm_to_widget(wssplash_xpm);
+       icon = xpm_to_widget(wssplash_xpm);
     gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 10);
 
     header_lb = gtk_label_new(NULL);
@@ -422,7 +426,7 @@ welcome_topic_header_new(const char *header)
     eb = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(eb), w);
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_header_bg);
+       gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_header_bg);
 #else
     gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_header_bg);
 #endif
@@ -453,7 +457,7 @@ welcome_topic_new(const char *header, GtkWidget **to_fill)
     topic_eb = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(topic_eb), topic_vb);
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(topic_eb, GTK_STATE_NORMAL, &rgba_topic_content_bg);
+       gtk_widget_override_background_color(topic_eb, GTK_STATE_NORMAL, &rgba_topic_content_bg);
 #else
     gtk_widget_modify_bg(topic_eb, GTK_STATE_NORMAL, &topic_content_bg);
 #endif
@@ -568,16 +572,16 @@ static void welcome_filename_destroy_cb(GtkWidget *w _U_, gpointer data) {
 
     g_mutex_lock(recent_mtx);
     if (ri_stat->timer) {
-        g_source_remove(ri_stat->timer);
-        ri_stat->timer = 0;
+       g_source_remove(ri_stat->timer);
+       ri_stat->timer = 0;
     }
 
     g_object_unref(ri_stat->menu_item);
 
     if (ri_stat->stat_done) {
-        g_free(ri_stat->filename);
-        g_string_free(ri_stat->str, TRUE);
-        g_free(ri_stat);
+       g_free(ri_stat->filename);
+       g_string_free(ri_stat->str, TRUE);
+       g_free(ri_stat);
     } else {
         ri_stat->label = NULL;
     }
@@ -705,22 +709,22 @@ static gboolean select_current_ifaces(GtkTreeModel  *model,
 {
     guint i;
     gchar *if_name;
-    interface_t device;
+    gboolean found = FALSE;
 
     GtkTreeSelection *selection = (GtkTreeSelection *)userdata;
-    device.name = NULL;
     gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1);
-    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(device.name, if_name) == 0) {
-            if (device.selected && !gtk_tree_selection_path_is_selected(selection, path)) {
-                gtk_tree_selection_select_iter(selection, iter);
-            } else {
-                gtk_tree_selection_unselect_iter(selection, iter);
+    for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+        if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) {
+            if (!gtk_tree_selection_path_is_selected(selection, path)) {
+              gtk_tree_selection_select_iter(selection, iter);
             }
+            found = TRUE;
             break;
         }
     }
+    if (!found) {
+        gtk_tree_selection_unselect_iter(selection, iter);
+    }
     return FALSE;
 }
 
@@ -732,69 +736,127 @@ gboolean on_selection_changed(GtkTreeSelection *selection _U_,
 {
     GtkTreeIter  iter;
     gchar *if_name;
-    guint i;
-    interface_t device;
-    
+    interface_options interface_opts;
+    guint i, j;
+    cap_settings_t    cap_settings;
+    gboolean found = FALSE;
+    displayed_interface d_interface;
+
+    d_interface.name = NULL;
+    d_interface.descr = NULL;
     gtk_tree_model_get_iter (model, &iter, path);
     gtk_tree_model_get (model, &iter, IFACE_NAME, &if_name, -1);
-    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(device.name, if_name) == 0) {
-            if (!device.locked) {
+    if (global_capture_opts.ifaces->len > 0) {
+        for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+            if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) {
+                found = TRUE;
                 if (path_currently_selected) {
-                    if (device.selected) {
-                        device.selected = FALSE;
-                        device.locked = TRUE;
-                        global_capture_opts.num_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(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && interfaces_dialog_window_present()) {
+                        update_selected_interface(g_strdup(interface_opts.name), FALSE);
                     }
-                } else {
-                    if (!device.selected) {
-                        device.selected = TRUE;
-                        device.locked = TRUE;
-                        global_capture_opts.num_selected++;
+                    if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && 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;
                 }
-                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 (!found && !path_currently_selected) {
+        for (j = 0; j < interfaces->len; j++) {
+            d_interface = g_array_index(interfaces, displayed_interface, j);
+            if (strcmp(d_interface.name, if_name) == 0) {
+                interface_opts.name = g_strdup(d_interface.name);
+                interface_opts.descr = g_strdup(d_interface.descr);
+                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
+                if (d_interface.remote_opts.src_type == CAPTURE_IFREMOTE) {
+                    interface_opts.src_type = d_interface.remote_opts.src_type;
+                    interface_opts.remote_host = g_strdup(d_interface.remote_opts.remote_host_opts.remote_host);
+                    interface_opts.remote_port = g_strdup(d_interface.remote_opts.remote_host_opts.remote_port);
+                    interface_opts.auth_type = d_interface.remote_opts.remote_host_opts.auth_type;
+                    interface_opts.auth_username = g_strdup(d_interface.remote_opts.remote_host_opts.auth_username);
+                    interface_opts.auth_password = g_strdup(d_interface.remote_opts.remote_host_opts.auth_password);
+                    interface_opts.datatx_udp = d_interface.remote_opts.remote_host_opts.datatx_udp;
+                    interface_opts.nocap_rpcap = d_interface.remote_opts.remote_host_opts.nocap_rpcap;
+                    interface_opts.nocap_local = d_interface.remote_opts.remote_host_opts.nocap_local;
+#ifdef HAVE_PCAP_SETSAMPLING
+                    interface_opts.sampling_method = d_interface.remote_opts.sampling_method;
+                    interface_opts.sampling_param  = d_interface.remote_opts.sampling_param;
+#endif
+                } else {
+                    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;
+#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
+                }
+#endif
 
-                if (dlg_window_present()) {
-                    enable_selected_interface(g_strdup(if_name), device.selected);
+                g_array_append_val(global_capture_opts.ifaces, interface_opts);
+                if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && interfaces_dialog_window_present()) {
+                    update_selected_interface(g_strdup(interface_opts.name), TRUE);
                 }
-                if (interfaces_dialog_window_present()) {
-                    update_selected_interface(g_strdup(if_name));
+                if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && dlg_window_present()) {
+                    enable_selected_interface(interface_opts.name, TRUE);
                 }
-                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);
+                break;
             }
-            break;
         }
     }
     return TRUE;
 }
 
 static gboolean activate_ifaces(GtkTreeModel  *model,
-                                GtkTreePath   *path _U_,
-                                GtkTreeIter   *iter,
-                                gpointer       userdata)
+                                  GtkTreePath   *path _U_,
+                                  GtkTreeIter   *iter,
+                                  gpointer       userdata)
 {
-    gchar *if_name;
-    GtkWidget *view;
-    GtkTreeSelection *selection;
-    selected_name_t  *entry = (selected_name_t *)userdata;
-
-    view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
-    gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1);
-    if (strcmp(if_name, entry->name) == 0) {
-        if (entry->activate) {
-            gtk_tree_selection_select_iter(selection, iter);
-        } else {
-            gtk_tree_selection_unselect_iter(selection, iter);
-        }
-        return TRUE;
+  gchar *if_name;
+  GtkWidget *view;
+  GtkTreeSelection *selection;
+  selected_name_t  *entry = (selected_name_t *)userdata;
+
+  view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
+  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+  gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1);
+  if (strcmp(if_name, entry->name) == 0) {
+    if (entry->activate) {
+      gtk_tree_selection_select_iter(selection, iter);
+    } else {
+      gtk_tree_selection_unselect_iter(selection, iter);
     }
-    return FALSE;
+    return TRUE;
+  }
+  return FALSE;
 }
 
 void change_interface_selection(gchar* name, gboolean activate)
@@ -812,11 +874,13 @@ void change_interface_selection(gchar* name, gboolean activate)
 
 void change_selection_for_all(gboolean enable)
 {
-    guint i;
+  guint i;
 
-    for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-        change_interface_selection(g_array_index(global_capture_opts.all_ifaces, interface_t, i).name, enable);
+  if (interfaces) {
+    for (i = 0; i < interfaces->len; i++) {
+      change_interface_selection(g_array_index(interfaces, displayed_interface, i).name, enable);
     }
+  }
 }
 #endif
 
@@ -828,7 +892,7 @@ select_ifaces(void)
     GtkTreeModel     *model;
     GtkTreeSelection *entry;
 
-    if (global_capture_opts.num_selected > 0 && swindow) {
+    if (global_capture_opts.ifaces->len > 0 && swindow) {
         view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
         model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
         entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
@@ -840,24 +904,40 @@ select_ifaces(void)
 
 #ifdef HAVE_PCAP_REMOTE
 void
-add_interface_to_list(guint index)
+add_interface_to_list(gchar *name, gchar *descr, remote_options *remote_opts)
 {
     GtkWidget *view, *icon;
     GtkTreeModel *model;
     GtkTreeIter iter;
     gint size;
     gchar *lines;
-    interface_t device;
-
-    device = g_array_index(global_capture_opts.all_ifaces, interface_t, index);
+    displayed_interface d_interface;
+
+    d_interface.name = g_strdup(name);
+    d_interface.descr = g_strdup(descr);
+    d_interface.remote_opts.src_type = remote_opts->src_type;
+    d_interface.remote_opts.remote_host_opts.remote_host = g_strdup(remote_opts->remote_host_opts.remote_host);
+    d_interface.remote_opts.remote_host_opts.remote_port = g_strdup(remote_opts->remote_host_opts.remote_port);
+    d_interface.remote_opts.remote_host_opts.auth_type = remote_opts->remote_host_opts.auth_type;
+    d_interface.remote_opts.remote_host_opts.auth_username = g_strdup(remote_opts->remote_host_opts.auth_username);
+    d_interface.remote_opts.remote_host_opts.auth_password = g_strdup(remote_opts->remote_host_opts.auth_password);
+    d_interface.remote_opts.remote_host_opts.datatx_udp = remote_opts->remote_host_opts.datatx_udp;
+    d_interface.remote_opts.remote_host_opts.nocap_rpcap = remote_opts->remote_host_opts.nocap_rpcap;
+    d_interface.remote_opts.remote_host_opts.nocap_local = remote_opts->remote_host_opts.nocap_local;
+#ifdef HAVE_PCAP_SETSAMPLING
+    d_interface.remote_opts.sampling_method = remote_opts->sampling_method;
+    d_interface.remote_opts.sampling_param = remote_opts->sampling_param;
+#endif
     icon = pixbuf_to_widget(remote_sat_pb_data);
+    d_interface.icon = icon;
     view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
     model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
     size = gtk_tree_model_iter_n_children(model, NULL);
     lines = g_strdup_printf("%d", size-1);
+    g_array_append_val(interfaces, d_interface);
     if (gtk_tree_model_get_iter_from_string(model, &iter, lines)) {
         gtk_list_store_append (GTK_LIST_STORE(model), &iter);
-        gtk_list_store_set(GTK_LIST_STORE(model), &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, device.display_name, IFACE_NAME, device.name, -1);
+        gtk_list_store_set(GTK_LIST_STORE(model), &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, descr, IFACE_NAME, name, -1);
     }
 }
 #endif
@@ -867,41 +947,92 @@ void
 welcome_if_tree_load(void)
 {
 #ifdef HAVE_LIBPCAP
+    if_info_t           *if_info;
+    GList               *if_list;
+    int                 err;
     guint               i;
+    gchar               *err_str = NULL;
+    GList               *curr;
+    gchar               *user_descr;
     GtkListStore        *store = NULL;
     GtkTreeIter         iter;
-    GtkWidget           *view;
+    GtkWidget           *icon, *view;
     GtkTreeSelection    *entry;
-    interface_t         device;
-    gboolean            changed = FALSE;
-    int                        error;
+    displayed_interface d_interface;
 
     view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
     entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
     gtk_tree_selection_unselect_all(entry);
     store = gtk_list_store_new(NUMCOLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
 
-     gtk_list_store_clear(store);
-     gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store));
     /* LOAD THE INTERFACES */
-    if (global_capture_opts.all_ifaces->len == 0) {
-      scan_local_interfaces(&global_capture_opts, &error);
+    if (interfaces && interfaces->len > 0) {
+        for (i = 0; i < interfaces->len; i++) {
+            d_interface = g_array_index(interfaces, displayed_interface, i);
+            gtk_list_store_append (store, &iter);
+            gtk_list_store_set (store, &iter, ICON, d_interface.icon, IFACE_DESCR, d_interface.descr, IFACE_NAME, d_interface.name, -1);
+        }
     } else {
-        for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-            device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-            if (!device.hidden) {
+        interfaces = g_array_new(TRUE, TRUE, sizeof(displayed_interface));
+        if_list = capture_interface_list(&err, &err_str);
+        if_list = g_list_sort (if_list, if_list_comparator_alph);
+        if (if_list == NULL &&
+            (err == CANT_GET_INTERFACE_LIST || err == DONT_HAVE_PCAP)) {
+            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
+            g_free(err_str);
+            return;
+        } else if (err_str) {
+            g_free(err_str);
+        }
+        if (g_list_length(if_list) > 0) {
+            /* List the interfaces */
+            for (curr = g_list_first(if_list); curr; curr = g_list_next(curr)) {
+                if_info = curr->data;
+                /* Continue if capture device is hidden */
+                if (prefs_is_capture_device_hidden(if_info->name)) {
+                    continue;
+                }
                 gtk_list_store_append (store, &iter);
-                gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(capture_get_if_icon(&device))), IFACE_DESCR, device.display_name, IFACE_NAME, device.name, -1);
-                if (device.selected) {
-                    gtk_tree_selection_select_iter(entry, &iter);
+                d_interface.name = g_strdup(if_info->name);
+#ifdef HAVE_PCAP_REMOTE
+                d_interface.remote_opts.src_type = CAPTURE_IFLOCAL;
+#endif
+#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
+                d_interface.icon = icon;
+                user_descr = capture_dev_user_descr_find(if_info->name);
+                if (user_descr) {
+#ifndef _WIN32
+                    gchar *comment = user_descr;
+                    user_descr = g_strdup_printf("%s (%s)", comment, if_info->name);
+                    g_free (comment);
+#endif
+                    gtk_list_store_set(store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, user_descr, IFACE_NAME, if_info->name, -1);
+                    d_interface.descr = g_strdup(user_descr);
+                    g_free (user_descr);
+                } else if (if_info->description) {
+                    gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, if_info->description, IFACE_NAME, if_info->name, -1);
+                    d_interface.descr = g_strdup(if_info->description);
+                } else {
+                    gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, if_info->name, IFACE_NAME, if_info->name, -1);
+                    d_interface.descr = g_strdup(if_info->name);
                 }
-            } 
+                g_array_append_val(interfaces, d_interface);
+            }
         }
-        changed = TRUE;
-    }
-    gtk_tree_selection_set_select_function(entry, on_selection_changed, (gpointer)&changed, NULL);
-    if (gtk_widget_is_focus(view) && dlg_window_present()) {
-        update_all_rows();
+        free_interface_list(if_list);
+        gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store));
+        if (global_capture_opts.ifaces->len > 0) {
+            gtk_tree_model_foreach(GTK_TREE_MODEL(store), select_current_ifaces, (gpointer) entry);
+            gtk_widget_grab_focus(view);
+        }
+        gtk_tree_selection_set_select_function(entry, on_selection_changed, NULL, NULL);
     }
 #endif  /* HAVE_LIBPCAP */
 }
@@ -912,9 +1043,23 @@ void
 welcome_if_panel_reload(void)
 {
 #ifdef HAVE_LIBPCAP
-    if (welcome_hb) {
+    GtkWidget *child_box;
+    GList* child_list;
+    GList* child_list_item;
+
+    if(welcome_if_panel_vb) {
+        child_box = scroll_box_dynamic_reset(welcome_if_panel_vb);
+        child_list = gtk_container_get_children(GTK_CONTAINER(child_box));
+        child_list_item = child_list;
+
+        while(child_list_item) {
+            gtk_container_remove(GTK_CONTAINER(child_box), child_list_item->data);
+            child_list_item = g_list_next(child_list_item);
+        }
+
+        g_list_free(child_list);
         welcome_if_tree_load();
-        gtk_widget_show_all(welcome_hb);
+        gtk_widget_show_all(welcome_if_panel_vb);
     }
 #endif  /* HAVE_LIBPCAP */
 }
@@ -923,32 +1068,27 @@ welcome_if_panel_reload(void)
 static void capture_if_start(GtkWidget *w _U_, gpointer data _U_)
 {
 #ifdef HAVE_AIRPCAP
-    interface_t device;
-    guint i;
+  interface_options interface_opts;
 #endif
-    if (global_capture_opts.num_selected == 0) {
-        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-            "You didn't specify an interface on which to capture packets.");
-        return;
-    }
 
-    /* XXX - remove this? */
-    if (global_capture_opts.save_file) {
-        g_free(global_capture_opts.save_file);
-        global_capture_opts.save_file = NULL;
-    }
-#ifdef HAVE_AIRPCAP  /* TODO: don't let it depend on interface_opts */
-    for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
-        device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-        airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, device.name);
-        airpcap_if_selected = airpcap_if_active;
-        if (airpcap_if_selected) {
-            break;
-        }
-    }
-    airpcap_set_toolbar_start_capture(airpcap_if_active);
+  if (global_capture_opts.ifaces->len == 0) {
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+      "You didn't specify an interface on which to capture packets.");
+    return;
+  }
+
+  /* XXX - remove this? */
+  if (global_capture_opts.save_file) {
+      g_free(global_capture_opts.save_file);
+      global_capture_opts.save_file = NULL;
+  }
+#ifdef HAVE_AIRPCAP
+  interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, 0);
+  airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, interface_opts.name);
+  airpcap_if_selected = airpcap_if_active;
+  airpcap_set_toolbar_start_capture(airpcap_if_active);
 #endif
-    capture_start_cb(NULL, NULL);
+  capture_start_cb(NULL, NULL);
 }
 #endif
 
@@ -957,7 +1097,7 @@ static void capture_if_start(GtkWidget *w _U_, gpointer data _U_)
 static gboolean
 activate_link_cb(GtkLabel *label _U_, gchar *uri, gpointer user_data _U_)
 {
-    return browser_open_url(uri);
+       return browser_open_url(uri);
 }
 #endif
 #endif
@@ -976,8 +1116,7 @@ welcome_new(void)
     GtkWidget *topic_vb;
     GtkWidget *topic_to_fill;
     GtkWidget *file_child_box;
-    gchar     *label_text;
-    int       error;
+    gchar *label_text;
 #ifdef _WIN32
     LONG reg_ret;
     DWORD chimney_enabled = 0;
@@ -987,6 +1126,9 @@ welcome_new(void)
     GtkTreeSelection *selection;
     GtkCellRenderer *renderer;
     GtkTreeViewColumn *column;
+    GList     *if_list;
+    int err;
+    gchar *err_str = NULL;
 #endif
 
     /* prepare colors */
@@ -1011,7 +1153,7 @@ welcome_new(void)
     topic_item_idle_bg = topic_content_bg;
 #endif
 #if 0
-    /* Allocating collor isn't necessary? */
+       /* Allocating collor isn't necessary? */
     /* topic item entered color */
     get_color(&topic_item_entered_bg);
 #endif
@@ -1022,9 +1164,9 @@ welcome_new(void)
     welcome_eb = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(welcome_eb), welcome_vb);
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(welcome_eb, GTK_STATE_NORMAL, &rgba_welcome_bg);
+       gtk_widget_override_background_color(welcome_eb, GTK_STATE_NORMAL, &rgba_welcome_bg);
 #else
-    gtk_widget_modify_bg(welcome_eb, GTK_STATE_NORMAL, &welcome_bg);
+       gtk_widget_modify_bg(welcome_eb, GTK_STATE_NORMAL, &welcome_bg);
 #endif
     /* header */
     header = welcome_header_new();
@@ -1039,7 +1181,7 @@ welcome_new(void)
     /* column capture */
     column_vb = gtk_vbox_new(FALSE, 10);
 #if GTK_CHECK_VERSION(3,0,0)
-    gtk_widget_override_background_color(column_vb, GTK_STATE_NORMAL, &rgba_welcome_bg);
+       gtk_widget_override_background_color(column_vb, GTK_STATE_NORMAL, &rgba_welcome_bg);
 #else
     gtk_widget_modify_bg(column_vb, GTK_STATE_NORMAL, &welcome_bg);
 #endif
@@ -1050,10 +1192,8 @@ welcome_new(void)
     gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
 
 #ifdef HAVE_LIBPCAP
-    if (global_capture_opts.all_ifaces->len == 0) {
-        scan_local_interfaces(&global_capture_opts, &error);
-    }
-    if (global_capture_opts.all_ifaces->len > 0) {
+    if_list = capture_interface_list(&err, &err_str);
+    if (g_list_length(if_list) > 0) {
         item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_INTERFACES,
             "Interface List",
             "Live list of the capture interfaces\n(counts incoming packets)",
@@ -1070,13 +1210,17 @@ welcome_new(void)
         g_object_set(G_OBJECT(if_view), "headers-visible", FALSE, NULL);
         g_signal_connect(if_view, "row-activated", G_CALLBACK(options_interface_cb), (gpointer)welcome_hb);
         g_object_set_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES, if_view);
-        column = gtk_tree_view_column_new();
         renderer = gtk_cell_renderer_pixbuf_new();
-        gtk_tree_view_column_pack_start(column, renderer, FALSE);
-        gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", ICON, NULL);
+        column = gtk_tree_view_column_new_with_attributes ("",
+                                               GTK_CELL_RENDERER(renderer),
+                                               "pixbuf", ICON,
+                                               NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
         renderer = gtk_cell_renderer_text_new();
-        gtk_tree_view_column_pack_start(column, renderer, TRUE);
-        gtk_tree_view_column_set_attributes(column, renderer, "text", IFACE_DESCR, NULL);
+        column = gtk_tree_view_column_new_with_attributes ("",
+                                               GTK_CELL_RENDERER(renderer),
+                                               "text", IFACE_DESCR,
+                                               NULL);
         gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
         gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(if_view), 0), TRUE);
         renderer = gtk_cell_renderer_text_new();
@@ -1119,8 +1263,9 @@ welcome_new(void)
         }
 #endif /* _WIN32 */
     } else {
-       if (error != NO_INTERFACES_FOUND) {
-            if (error == CANT_GET_INTERFACE_LIST) {
+       if (if_list == NULL && err != NO_INTERFACES_FOUND) {
+            g_free(err_str);
+            if (err == CANT_GET_INTERFACE_LIST) {
                 label_text = g_strdup("No interface can be used for capturing in "
                                       "this system with the current configuration.\n"
                                       "\n"
@@ -1173,6 +1318,8 @@ welcome_new(void)
 #endif
     }
 
+    free_interface_list(if_list);
+
     /* capture help topic */
     topic_vb = welcome_topic_new("Capture Help", &topic_to_fill);
     gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
@@ -1313,7 +1460,12 @@ welcome_new(void)
 
 GtkWidget* get_welcome_window(void)
 {
-    return welcome_hb;
+  return welcome_hb;
 }
 
-
+#ifdef HAVE_LIBPCAP
+displayed_interface get_interface_data(gint index)
+{
+  return g_array_index(interfaces, displayed_interface, index);
+}
+#endif
index 296a53796d7399237e923d45f8fd86c708f0aaf1..23996e37239ac3d2562dea3689038eafaf81e365 100644 (file)
@@ -40,6 +40,15 @@ typedef struct selected_name_s {
   gboolean activate;
 } selected_name_t;
 
+typedef struct displayed_interface_s {
+       gchar *name;
+       gchar *descr;
+       GtkWidget *icon;
+#ifdef HAVE_PCAP_REMOTE
+       remote_options remote_opts;
+#endif
+} displayed_interface;
+
 GtkWidget *welcome_new(void);
 
 /* reset the list of recently used files */
@@ -51,8 +60,6 @@ void main_welcome_add_recent_capture_file(const char *widget_cf_name, GObject *m
 /* reload the list of interfaces */
 void welcome_if_panel_reload(void);
 
-void welcome_if_tree_load(void);
-
 /** Push a status message into the welcome screen header similar to
  *  statusbar_push_*_msg(). This hides everything under the header.
  *  If msg is dynamically allocated, it is up to the caller to free
@@ -78,10 +85,10 @@ void change_interface_selection(gchar* name, gboolean activate);
 
 void change_selection_for_all(gboolean enable);
 
-void update_welcome_list(void);
-
 #ifdef HAVE_PCAP_REMOTE
-void add_interface_to_list(guint index);
+void add_interface_to_list(gchar *name, gchar *descr, remote_options *remote_opts);
 #endif
 
+displayed_interface get_interface_data(gint index);
+
 #endif /* __MAIN_WELCOME_H__ */
index 9553aed30c851efc2448e0965524fb639f5d9dae..07e8dbfa447bfd88253cea3de09496a49eebdca2 100644 (file)
@@ -1424,7 +1424,6 @@ ifopts_write_new_hide(void)
                        g_free(new_hide);
                        prefs.capture_devices_hide = NULL;
                }
-               hide_interface(g_strdup(new_hide));
        }
 }
 
index 321e92830113657aba00ecb6d8d46f425d8bfbfc..d3eba4718ecc3b7765d645c76cdfb544630c5ef6 100644 (file)
@@ -124,9 +124,7 @@ stats_prefs_fetch(GtkWidget *w _U_)
 void
 stats_prefs_apply(GtkWidget *w _U_)
 {
-#if defined(_WIN32)
         reset_tap_update_timer();
-#endif
 }
 
 void