Fetch an indication of whether the interface supports capturing in
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 13 May 2010 17:37:39 +0000 (17:37 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 13 May 2010 17:37:39 +0000 (17:37 +0000)
monitor mode at the same time that we fetch its list of link-layer
types.  Support fetching that list in monitor mode, as the list may be
different in regular and monitor mode.  If the interface supports
monitor mode, when printing the list of link-layer types, indicate
whether they're fetched in monitor mode or not, as tcpdump 4.1.x does.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@32789 f5534014-38df-0310-8fa8-9805f1628bb7

12 files changed:
capture-pcap-util.c
capture_ifinfo.c
capture_ifinfo.h
capture_opts.c
capture_opts.h
capture_sync.c
capture_sync.h
dumpcap.c
gtk/capture_dlg.c
gtk/main.c
gtk/prefs_capture.c
tshark.c

index 1c7815fa4e519ee7603a53b1973a977296cd6f24..1850b10acd203f3b93d4251e61b5aa2ad9ec39ce 100644 (file)
@@ -448,10 +448,11 @@ free_linktype_cb(gpointer data, gpointer user_data _U_)
 }
 
 void
-free_pcap_linktype_list(GList *linktype_list)
+free_if_capabilities(if_capabilities_t *caps)
 {
-       g_list_foreach(linktype_list, free_linktype_cb, NULL);
-       g_list_free(linktype_list);
+       g_list_foreach(caps->data_link_types, free_linktype_cb, NULL);
+       g_list_free(caps->data_link_types);
+       g_free(caps);
 }
 
 const char *
index 53e024749f27ab11a2639b7a2d870412af844bb9..e9fc5347a0263c26e4e64e9b6e9b5dfc792100b3 100644 (file)
@@ -155,21 +155,23 @@ capture_interface_list(int *err, char **err_str)
 
 /* XXX - We parse simple text output to get our interface list.  Should
  * we use "real" data serialization instead, e.g. via XML? */
-GList *
-capture_pcap_linktype_list(const gchar *ifname, char **err_str)
+if_capabilities_t *
+capture_get_if_capabilities(const gchar *ifname, gboolean monitor_mode,
+                            char **err_str)
 {
-    GList     *linktype_list = NULL;
-    int        err, i;
-    gchar     *msg;
-    gchar    **raw_list, **lt_parts;
-    data_link_info_t *data_link_info;
+    if_capabilities_t *caps;
+    GList              *linktype_list = NULL;
+    int                 err, i;
+    gchar              *msg;
+    gchar             **raw_list, **lt_parts;
+    data_link_info_t   *data_link_info;
 
-    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List ...");
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities ...");
 
     /* Try to get our interface list */
-    err = sync_linktype_list_open(ifname, &msg);
+    err = sync_if_capabilities_open(ifname, monitor_mode, &msg);
     if (err != 0) {
-        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List failed!");
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities failed!");
         if (err_str) {
             *err_str = msg;
         } else {
@@ -186,7 +188,45 @@ capture_pcap_linktype_list(const gchar *ifname, char **err_str)
 #endif
     g_free(msg);
 
-    for (i = 0; raw_list[i] != NULL; i++) {
+    /*
+     * First line is 0 if monitor mode isn't supported, 1 if it is.
+     */
+    if (raw_list[0] == NULL || *raw_list[0] == '\0') {
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities returned no information!");
+        if (err_str) {
+            *err_str = g_strdup("Dumpcap returned no interface capability information");
+        }
+        return NULL;
+    }
+
+    /*
+     * Allocate the interface capabilities structure.
+     */
+    caps = g_malloc(sizeof *caps);
+    switch (*raw_list[0]) {
+
+    case '0':
+        caps->can_set_rfmon = FALSE;
+        break;
+
+    case '1':
+        caps->can_set_rfmon = TRUE;
+        break;
+
+    default:
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities returned bad information!");
+        if (err_str) {
+            *err_str = g_strdup_printf("Dumpcap returned \"%s\" for monitor-mode capability",
+                                       raw_list[0]);
+        }
+        g_free(caps);
+        return NULL;
+    }
+
+    /*
+     * The rest are link-layer types.
+     */
+    for (i = 1; raw_list[i] != NULL; i++) {
         /* ...and what if the interface name has a tab in it, Mr. Clever Programmer? */
         lt_parts = g_strsplit(raw_list[i], "\t", 3);
         if (lt_parts[0] == NULL || lt_parts[1] == NULL || lt_parts[2] == NULL) {
@@ -208,10 +248,14 @@ capture_pcap_linktype_list(const gchar *ifname, char **err_str)
 
     /* Check to see if we built a list */
     if (linktype_list == NULL) {
+        /* No. */
         if (err_str)
-            *err_str = NULL;
+            *err_str = g_strdup("Dumpcap returned no link-layer types");
+        g_free(caps);
+        return NULL;
     }
-    return linktype_list;
+    caps->data_link_types = linktype_list;
+    return caps;
 }
 
 #endif /* HAVE_LIBPCAP */
index 28ebb5c7010c133a683696907e21349a263fdc5d..e0cec1db7f0ebbd940a907e24dd85c733ad6c612 100644 (file)
@@ -67,8 +67,17 @@ extern GList *capture_interface_list(int *err, char **err_str);
 void free_interface_list(GList *if_list);
 
 /*
- * The list of data link types returned by "get_pcap_linktype_list()" and
- * "capture_pcap_linktype_list()" is a list of these structures.
+ * "get_if_capabilities()" and "capture_if_capabilities()" return a pointer
+ * to an allocated instance of this structure.  "free_if_capabilities()"
+ * frees the returned instance.
+ */
+typedef struct {
+       gboolean        can_set_rfmon;  /* TRUE if can be put into monitor mode */
+       GList           *data_link_types;       /* GList of data_link_info_t's */
+} if_capabilities_t;
+
+/*
+ * Information about data link types.
  */
 typedef struct {
        int     dlt;            /* e.g. DLT_EN10MB (which is 1) */
@@ -79,9 +88,11 @@ typedef struct {
 /**
  * Fetch the linktype list for the specified interface from a child process.
  */
-extern GList *capture_pcap_linktype_list(const char *devname, char **err_str);
+extern if_capabilities_t *
+capture_get_if_capabilities(const char *devname, gboolean monitor_mode,
+                            char **err_str);
 
-void free_pcap_linktype_list(GList *linktype_list);
+void free_if_capabilities(if_capabilities_t *caps);
 
 #endif /* HAVE_LIBPCAP */
 
index 96bec3c9af5e8554f9215dbf5384f9d5b72ebaec..23297b60eb7d7b083bc2e4b74a06d6d6f71d59d3 100644 (file)
@@ -81,9 +81,7 @@ capture_opts_init(capture_options *capture_opts, void *cf)
   capture_opts->snaplen                 = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
                                                                    infinite, in effect */
   capture_opts->promisc_mode            = TRUE;             /* promiscuous mode is the default */
-#ifdef HAVE_PCAP_CREATE
   capture_opts->monitor_mode            = FALSE;
-#endif
   capture_opts->linktype                = -1;               /* the default linktype */
   capture_opts->saving_to_file          = FALSE;
   capture_opts->save_file               = NULL;
@@ -549,13 +547,18 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
 }
 
 void
-capture_opts_print_link_layer_types(GList *lt_list)
+capture_opts_print_if_capabilities(if_capabilities_t *caps,
+                                   gboolean monitor_mode)
 {
     GList *lt_entry;
     data_link_info_t *data_link_info;
 
-    fprintf_stderr("Data link types (use option -y to set):\n");
-    for (lt_entry = lt_list; lt_entry != NULL;
+    if (caps->can_set_rfmon)
+        fprintf_stderr("Data link types when %sin monitor mode (use option -y to set):\n",
+                       monitor_mode ? "" : "not ");
+    else
+        fprintf_stderr("Data link types (use option -y to set):\n");
+    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;
         fprintf_stderr("  %s", data_link_info->name);
index fdf7672220bf22904c33c20194b338a5f6f5fde7..34709fce04e816f706ea9f8099a467ee93555fc2 100644 (file)
@@ -36,6 +36,7 @@
 # include <sys/types.h>            /* for gid_t */
 #endif
 
+#include "capture_ifinfo.h"
 
 /* Current state of capture engine. XXX - differentiate states */
 typedef enum {
@@ -114,9 +115,7 @@ typedef struct capture_options_tag {
     gboolean promisc_mode;          /**< Capture in promiscuous mode */
     int      linktype;              /**< Data link type to use, or -1 for
                                          "use default" */
-#ifdef HAVE_PCAP_CREATE
     gboolean monitor_mode;          /**< Capture in monitor mode, if available */
-#endif
     gboolean saving_to_file;        /**< TRUE if capture is writing to a file */
     gchar    *save_file;            /**< the capture file name */
     gboolean use_pcapng;            /**< TRUE if file format is pcapng */
@@ -175,9 +174,10 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
 extern void
 capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts);
 
-/* print list of link layer types */
+/* print interface capabilities, including link layer types */
 extern void
-capture_opts_print_link_layer_types(GList *lt_list);
+capture_opts_print_if_capabilities(if_capabilities_t *caps,
+                                   gboolean monitor_mode);
 
 /* print list of interfaces */
 extern void
index 6fe6fd1fc968996869668a7837ae6f85c8205b14..f412c4e51af9ab727a49023a1033184ca2305577 100644 (file)
@@ -889,13 +889,15 @@ sync_interface_list_open(gchar **msg) {
 }
 
 /*
- * Get an linktype list using dumpcap.  On success, *msg points to
+ * Get interface capabilities using dumpcap.  On success, *msg points to
  * a buffer containing the dumpcap output, and 0 is returned.  On failure,
  * *msg points to an error message, and -1 is returned.  In either case,
  * *msg must be freed with g_free().
  */
 int
-sync_linktype_list_open(const gchar *ifname, gchar **msg) {
+sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
+                          gchar **msg)
+{
     int argc;
     const char **argv;
 
@@ -913,10 +915,12 @@ sync_linktype_list_open(const gchar *ifname, gchar **msg) {
         return -1;
     }
 
-    /* Ask for the linktype list */
+    /* Ask for the interface capabilities */
     argv = sync_pipe_add_arg(argv, &argc, "-i");
     argv = sync_pipe_add_arg(argv, &argc, ifname);
     argv = sync_pipe_add_arg(argv, &argc, "-L");
+    if (monitor_mode)
+        argv = sync_pipe_add_arg(argv, &argc, "-I");
     argv = sync_pipe_add_arg(argv, &argc, "-M");
 
 #if 0
index 26a6b7afe452abbba83b0710c637cb5b88d77bd8..826c20d12d9b9b16359a6df40cb501db620a8742 100644 (file)
@@ -67,9 +67,10 @@ sync_pipe_kill(int fork_child);
 extern int
 sync_interface_list_open(gchar **msg);
 
-/** Get a linktype list using dumpcap */
+/** Get interface capabilities using dumpcap */
 extern int
-sync_linktype_list_open(const gchar *ifname, gchar **msg);
+sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
+                          gchar **msg);
 
 /** Start getting interface statistics using dumpcap. */
 extern int
index 669c96d56b704240d04b09a7eb113b2fb2d53544..ef865b97e73b98e0288136c8a988eb3710585490 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -502,29 +502,111 @@ create_data_link_info(int dlt)
     return data_link_info;
 }
 
-static GList *
-get_pcap_linktype_list(const char *devname, char **err_str)
+static if_capabilities_t *
+get_if_capabilities(const char *devname, gboolean monitor_mode
+#ifndef HAVE_PCAP_CREATE
+       _U_
+#endif
+, char **err_str)
 {
-    GList *linktype_list = NULL;
+    if_capabilities_t *caps;
+    char errbuf[PCAP_ERRBUF_SIZE];
     pcap_t *pch;
+#ifdef HAVE_PCAP_CREATE
+    int status;
+#endif
     int deflt;
-    char errbuf[PCAP_ERRBUF_SIZE];
 #ifdef HAVE_PCAP_LIST_DATALINKS
     int *linktypes;
     int i, nlt;
 #endif
     data_link_info_t *data_link_info;
 
+    /*
+     * Allocate the interface capabilities structure.
+     */
+    caps = g_malloc(sizeof *caps);
+
 #ifdef HAVE_PCAP_OPEN
     pch = pcap_open(devname, MIN_PACKET_SIZE, 0, 0, NULL, errbuf);
+    caps->can_set_rfmon = FALSE;
+    if (pch == NULL) {
+        if (err_str != NULL)
+            *err_str = g_strdup(errbuf);
+        g_free(caps);
+        return NULL;
+    }
+#elif defined(HAVE_PCAP_CREATE)
+    pch = pcap_create(devname, errbuf);
+    if (pch == NULL) {
+        if (err_str != NULL)
+            *err_str = g_strdup(errbuf);
+        g_free(caps);
+        return NULL;
+    }
+    status = pcap_can_set_rfmon(pch); 
+    switch (status) {
+
+    case 0:
+        caps->can_set_rfmon = FALSE;
+        break;
+
+    case 1:
+        caps->can_set_rfmon = TRUE;
+        if (monitor_mode)
+               pcap_set_rfmon(pch, 1);
+        break;
+
+    case PCAP_ERROR_NO_SUCH_DEVICE:
+        if (err_str != NULL)
+            *err_str = g_strdup_printf("There is no capture device named \"%s\"", devname);
+        pcap_close(pch);
+        g_free(caps);
+        return NULL;
+
+    case PCAP_ERROR:
+        if (err_str != NULL)
+            *err_str = g_strdup_printf("pcap_can_set_rfmon on \"%s\" failed: %s",
+                                       devname, pcap_geterr(pch));
+        pcap_close(pch);
+        g_free(caps);
+        return NULL;
+
+    default:
+        if (err_str != NULL)
+            *err_str = g_strdup_printf("pcap_can_set_rfmon on \"%s\" failed: %s",
+                                       devname, pcap_statustostr(status));
+        pcap_close(pch);
+        g_free(caps);
+        return NULL;
+    }
+
+    status = pcap_activate(pch);
+    if (status < 0) {
+        /* Error.  We ignore warnings (status > 0). */
+        if (err_str != NULL) {
+            if (status == PCAP_ERROR) {
+                *err_str = g_strdup_printf("pcap_activate on %s failed: %s",
+                                           devname, pcap_geterr(pch));
+            } else {
+                *err_str = g_strdup_printf("pcap_activate on %s failed: %s",
+                                           devname, pcap_statustostr(status));
+            }
+        }
+        pcap_close(pch);
+        g_free(caps);
+        return NULL;
+    }
 #else
     pch = pcap_open_live(devname, MIN_PACKET_SIZE, 0, 0, errbuf);
-#endif
+    caps->can_set_rfmon = FALSE;
     if (pch == NULL) {
         if (err_str != NULL)
             *err_str = g_strdup(errbuf);
-            return NULL;
+        g_free(caps);
+        return NULL;
     }
+#endif
     deflt = get_pcap_linktype(pch, devname);
 #ifdef HAVE_PCAP_LIST_DATALINKS
     nlt = pcap_list_datalinks(pch, &linktypes);
@@ -534,6 +616,7 @@ get_pcap_linktype_list(const char *devname, char **err_str)
             *err_str = NULL; /* an empty list doesn't mean an error */
         return NULL;
     }
+    caps->data_link_types = NULL;
     for (i = 0; i < nlt; i++) {
         data_link_info = create_data_link_info(linktypes[i]);
 
@@ -543,9 +626,11 @@ get_pcap_linktype_list(const char *devname, char **err_str)
          * device has as the default?
          */
         if (linktypes[i] == deflt)
-            linktype_list = g_list_prepend(linktype_list, data_link_info);
+            caps->data_link_types = g_list_prepend(caps->data_link_types,
+                                                   data_link_info);
         else
-            linktype_list = g_list_append(linktype_list, data_link_info);
+            caps->data_link_types = g_list_append(caps->data_link_types,
+                                                  data_link_info);
     }
 #ifdef HAVE_PCAP_FREE_DATALINKS
     pcap_free_datalinks(linktypes);
@@ -575,14 +660,15 @@ get_pcap_linktype_list(const char *devname, char **err_str)
 #else /* HAVE_PCAP_LIST_DATALINKS */
 
     data_link_info = create_data_link_info(deflt);
-    linktype_list = g_list_append(linktype_list, data_link_info);
+    caps->data_link_types = g_list_append(caps->data_link_types,
+                                          data_link_info);
 #endif /* HAVE_PCAP_LIST_DATALINKS */
 
     pcap_close(pch);
 
     if (err_str != NULL)
         *err_str = NULL;
-    return linktype_list;
+    return caps;
 }
 
 #define ADDRSTRLEN 46 /* Covers IPv4 & IPv6 */
@@ -652,16 +738,21 @@ print_machine_readable_interfaces(GList *if_list)
 
 /*
  * If you change the machine-readable output format of this function,
- * you MUST update capture_sync.c:sync_linktype_list_open() accordingly!
+ * you MUST update capture_ifinfo.c:capture_get_if_capabilities() accordingly!
  */
 static void
-print_machine_readable_link_layer_types(GList *lt_list)
+print_machine_readable_if_capabilities(if_capabilities_t *caps)
 {
     GList *lt_entry;
     data_link_info_t *data_link_info;
     const gchar *desc_str;
 
-    for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
+    if (caps->can_set_rfmon)
+        printf("1\n");
+    else
+        printf("0\n");
+    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)
         desc_str = data_link_info->description;
@@ -3381,25 +3472,28 @@ main(int argc, char *argv[])
     exit_main(0);
   } else if (list_link_layer_types) {
     /* Get the list of link-layer types for the capture device. */
-    GList *lt_list;
+    if_capabilities_t *caps;
     gchar *err_str;
 
-    lt_list = get_pcap_linktype_list(global_capture_opts.iface, &err_str);
-    if (lt_list == NULL) {
-      if (err_str != NULL) {
-        cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
-         "Please check to make sure you have sufficient permissions, and that\n"
-         "you have the proper interface or pipe specified.\n", global_capture_opts.iface, err_str);
-        g_free(err_str);
-      } else
-        cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+    caps = get_if_capabilities(global_capture_opts.iface,
+                               global_capture_opts.monitor_mode, &err_str);
+    if (caps == NULL) {
+      cmdarg_err("The capabilities of the capture device \"%s\" could not be obtained (%s)."
+       "Please check to make sure you have sufficient permissions, and that\n"
+       "you have the proper interface or pipe specified.\n", global_capture_opts.iface, err_str);
+      g_free(err_str);
+      exit_main(2);
+    }
+    if (caps->data_link_types == NULL) {
+      cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
       exit_main(2);
     }
     if (machine_readable)      /* tab-separated values to stdout */
-      print_machine_readable_link_layer_types(lt_list);
+      print_machine_readable_if_capabilities(caps);
     else
-      capture_opts_print_link_layer_types(lt_list);
-    free_pcap_linktype_list(lt_list);
+      capture_opts_print_if_capabilities(caps,
+                                         global_capture_opts.monitor_mode);
+    free_if_capabilities(caps);
     exit_main(0);
   } else if (print_statistics) {
     status = print_statistics_loop(machine_readable);
index a6831a88dff0315bd1a45e5ecabdc4a29c52c246..405cd173e183668e86d85ffdd8656f51b45ca8ef 100644 (file)
@@ -252,7 +252,7 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
   GList *if_list;
   GList *if_entry;
   if_info_t *if_info;
-  GList *lt_list;
+  if_capabilities_t *caps;
   int err;
   GtkWidget *lt_menu, *lt_menu_item;
   GList *lt_entry;
@@ -310,7 +310,7 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
    * does the code we use if "pcap_findalldevs()" isn't available), but
    * should contain all the local devices on which you can capture.
    */
-  lt_list = NULL;
+  caps = NULL;
   if (*if_name != '\0') {
     /*
      * Try to get the list of known interfaces.
@@ -342,7 +342,7 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
           if (iftype == CAPTURE_IFLOCAL)
             /* Not able to get link-layer for remote interfaces */
 #endif
-         lt_list = capture_pcap_linktype_list(if_name, NULL);
+         caps = capture_get_if_capabilities(if_name, FALSE, NULL);
 
          /* create string of list of IP addresses of this interface */
          for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
@@ -385,35 +385,37 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
   num_supported_link_types = 0;
   linktype_select = 0;
   linktype_count = 0;
-  for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
-    data_link_info = lt_entry->data;
-    if (data_link_info->description != NULL) {
-      lt_menu_item = gtk_menu_item_new_with_label(data_link_info->description);
-      g_object_set_data(G_OBJECT(lt_menu_item), E_CAP_LT_OM_KEY, linktype_om);
-      g_signal_connect(lt_menu_item, "activate", G_CALLBACK(select_link_type_cb),
-                     GINT_TO_POINTER(data_link_info->dlt));
-      num_supported_link_types++;
-    } else {
-      /* Not supported - tell them about it but don't let them select it. */
-      linktype_menu_label = g_strdup_printf("%s (not supported)",
-                                           data_link_info->name);
-      lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
-      g_free(linktype_menu_label);
-    }
-    if (data_link_info->dlt == linktype) {
-      /* Found a matching dlt, selecth this */
-      linktype_select = linktype_count;
+  if (caps != NULL) {
+    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) {
+        lt_menu_item = gtk_menu_item_new_with_label(data_link_info->description);
+        g_object_set_data(G_OBJECT(lt_menu_item), E_CAP_LT_OM_KEY, linktype_om);
+        g_signal_connect(lt_menu_item, "activate", G_CALLBACK(select_link_type_cb),
+                         GINT_TO_POINTER(data_link_info->dlt));
+        num_supported_link_types++;
+      } else {
+        /* Not supported - tell them about it but don't let them select it. */
+        linktype_menu_label = g_strdup_printf("%s (not supported)",
+                                              data_link_info->name);
+        lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
+        g_free(linktype_menu_label);
+      }
+      if (data_link_info->dlt == linktype) {
+        /* Found a matching dlt, selecth this */
+        linktype_select = linktype_count;
+      }
+      gtk_menu_shell_append(GTK_MENU_SHELL(lt_menu), lt_menu_item);
+      gtk_widget_show(lt_menu_item);
+      linktype_count++;
     }
-    gtk_menu_shell_append(GTK_MENU_SHELL(lt_menu), lt_menu_item);
-    gtk_widget_show(lt_menu_item);
-    linktype_count++;
+    free_if_capabilities(caps);
   }
-  if (lt_list == NULL) {
+  if (linktype_count == 0) {
     lt_menu_item = gtk_menu_item_new_with_label("(not supported)");
     gtk_menu_shell_append(GTK_MENU_SHELL(lt_menu), lt_menu_item);
     gtk_widget_show(lt_menu_item);
-  } else {
-    free_pcap_linktype_list(lt_list);
   }
   gtk_option_menu_set_menu(GTK_OPTION_MENU(linktype_om), lt_menu);
   gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
index 5d4b5bc1852d2b4adbc85d1182e4a8aeb48005da..b5c82a7c5ec8686d88f2e84302de0bfa6530a019 100644 (file)
@@ -2741,22 +2741,24 @@ main(int argc, char *argv[])
 
   if (list_link_layer_types) {
     /* Get the list of link-layer types for the capture device. */
-    GList *lt_list;
-    gchar *error_string;
-
-    lt_list = capture_pcap_linktype_list(global_capture_opts.iface, &error_string);
-    if (lt_list == NULL) {
-      if (error_string != NULL) {
-        cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
-         "Please check to make sure you have sufficient permissions, and that\n"
-         "you have the proper interface or pipe specified.\n", global_capture_opts.iface, error_string);
-        g_free(error_string);
-      } else
-        cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+    if_capabilities_t *caps;
+
+    caps = capture_get_if_capabilities(global_capture_opts.iface,
+                                       global_capture_opts.monitor_mode,
+                                       &err_str);
+    if (caps == NULL) {
+      cmdarg_err("The capabilities of the capture device \"%s\" could not be obtained (%s)."
+       "Please check to make sure you have sufficient permissions, and that\n"
+       "you have the proper interface or pipe specified.\n", global_capture_opts.iface, err_str);
+      g_free(err_str);
       exit(2);
     }
-    capture_opts_print_link_layer_types(lt_list);
-    free_pcap_linktype_list(lt_list);
+    if (caps->data_link_types == NULL) {
+      cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+      exit(2);
+    }
+    capture_opts_print_if_capabilities(caps, global_capture_opts.monitor_mode);
+    free_if_capabilities(caps);
     exit(0);
   }
 
index 17cd411a32f373256c8dcde5c146b8c7e749c74d..6debfe3ae985d5c8bb3ebc357ab38cac3a9b079c 100644 (file)
@@ -598,28 +598,32 @@ ifopts_edit_destroy_cb(GtkWidget *win, gpointer data _U_)
 static gint
 ifopts_description_to_val (const char *if_name, const char *descr) 
 {
-       GList *lt_list;
+       if_capabilities_t *caps;
        int dlt = -1;
 
-       lt_list = capture_pcap_linktype_list(if_name, NULL);
-       if (lt_list != NULL) {
-               GList  *lt_entry;
-               /* XXX: Code skips first entry because that's the default ??? */
-               for (lt_entry = g_list_next(lt_list); lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
-                       data_link_info_t *dli_p = lt_entry->data;
-                       if (dli_p->description) {
-                               if (strcmp(dli_p->description, descr) == 0) {
-                                       dlt = dli_p->dlt;
-                                       break;
-                               }
-                       } else {
-                               if (strcmp(dli_p->name, descr) == 0) {
-                                       dlt = dli_p->dlt;
-                                       break;
+       caps = capture_get_if_capabilities(if_name, FALSE, NULL);
+       if (caps != NULL) {
+               if (caps->data_link_types != NULL) {
+                       GList  *lt_entry;
+                       /* XXX: Code skips first entry because that's the default ??? */
+                       for (lt_entry = g_list_next(caps->data_link_types);
+                           lt_entry != NULL;
+                           lt_entry = g_list_next(lt_entry)) {
+                               data_link_info_t *dli_p = lt_entry->data;
+                               if (dli_p->description) {
+                                       if (strcmp(dli_p->description, descr) == 0) {
+                                               dlt = dli_p->dlt;
+                                               break;
+                                       }
+                               } else {
+                                       if (strcmp(dli_p->name, descr) == 0) {
+                                               dlt = dli_p->dlt;
+                                               break;
+                                       }
                                }
                        }
                }
-               free_pcap_linktype_list(lt_list);
+               free_if_capabilities(caps);
        }
        return dlt;
 }
@@ -631,13 +635,13 @@ static void
 ifopts_edit_ifsel_cb(GtkTreeSelection  *selection _U_,
                     gpointer            data _U_)
 {
-       GtkTreeIter       iter;
-       GtkTreeModel     *model;
-       gchar            *desc, *comment, *text;
-       gchar            *if_name, *linktype;
-       gboolean          hide;
-       GList            *lt_list;
-       gint              selected = 0;
+       GtkTreeIter         iter;
+       GtkTreeModel       *model;
+       gchar              *desc, *comment, *text;
+       gchar              *if_name, *linktype;
+       gboolean            hide;
+       if_capabilities_t *caps;
+       gint                selected = 0;
 
        /* Get list_store data for currently selected interface */
        if (!gtk_tree_selection_get_selected (if_selection, &model, &iter)){
@@ -668,21 +672,24 @@ ifopts_edit_ifsel_cb(GtkTreeSelection     *selection _U_,
        }
 
         /*  -- build and add to the ComboBox a linktype list for the current interfaces selection */
-       lt_list = capture_pcap_linktype_list(if_name, NULL);
-       if (lt_list != NULL) {
-               GList *lt_entry;
-               for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
-                       data_link_info_t *dli_p = lt_entry->data;
-                       text = (dli_p->description != NULL) ? dli_p->description : dli_p->name;
-                       if (strcmp(linktype, text) == 0) {
-                               selected = num_linktypes;
+       caps = capture_get_if_capabilities(if_name, FALSE, NULL);
+       if (caps != NULL) {
+               if (caps->data_link_types != NULL) {
+                       GList *lt_entry;
+                       for (lt_entry = caps->data_link_types; lt_entry != NULL;
+                           lt_entry = g_list_next(lt_entry)) {
+                               data_link_info_t *dli_p = lt_entry->data;
+                               text = (dli_p->description != NULL) ? dli_p->description : dli_p->name;
+                               if (strcmp(linktype, text) == 0) {
+                                       selected = num_linktypes;
+                               }
+                               gtk_combo_box_append_text(GTK_COMBO_BOX(if_linktype_cb), text);
+                               num_linktypes++;
                        }
-                       gtk_combo_box_append_text(GTK_COMBO_BOX(if_linktype_cb), text);
-                       num_linktypes++;
+                       gtk_widget_set_sensitive(if_linktype_cb, num_linktypes >= 2);
+                       gtk_combo_box_set_active(GTK_COMBO_BOX(if_linktype_cb), selected);
                }
-               gtk_widget_set_sensitive(if_linktype_cb, num_linktypes >= 2);
-               gtk_combo_box_set_active(GTK_COMBO_BOX(if_linktype_cb), selected);
-               free_pcap_linktype_list(lt_list);
+               free_if_capabilities(caps);
        }
 
        /* display the interface description from current interfaces selection */
@@ -834,7 +841,7 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info)
        gchar   *desc;
        gchar   *pr_descr;
        gchar   *text[] = { NULL, NULL, NULL, NULL };
-       GList   *lt_list;
+       if_capabilities_t *caps;
        gint     linktype;
        gboolean hide;
        GtkTreeIter  iter;
@@ -850,22 +857,25 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info)
 
        /* set default link-layer header type */
        linktype = capture_dev_user_linktype_find(if_info->name);
-       lt_list = capture_pcap_linktype_list(if_info->name, NULL);
-       if (lt_list != NULL) {
-               GList  *lt_entry;
-               for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
-                       data_link_info_t *dli_p = lt_entry->data;
-                       /* If we have no previous link-layer header type we use the first one */
-                       if (linktype == -1 || linktype == dli_p->dlt) {
-                               if (dli_p->description) {
-                                       text[2] = g_strdup(dli_p->description);
-                               } else {
-                                       text[2] = g_strdup(dli_p->name);
+       caps = capture_get_if_capabilities(if_info->name, FALSE, NULL);
+       if (caps != NULL) {
+               if (caps->data_link_types != NULL) {
+                       GList  *lt_entry;
+                       for (lt_entry = caps->data_link_types; lt_entry != NULL;
+                           lt_entry = g_list_next(lt_entry)) {
+                               data_link_info_t *dli_p = lt_entry->data;
+                               /* If we have no previous link-layer header type we use the first one */
+                               if (linktype == -1 || linktype == dli_p->dlt) {
+                                       if (dli_p->description) {
+                                               text[2] = g_strdup(dli_p->description);
+                                       } else {
+                                               text[2] = g_strdup(dli_p->name);
+                                       }
+                                       break;
                                }
-                               break;
                        }
                }
-               free_pcap_linktype_list(lt_list);
+               free_if_capabilities(caps);
        }
        /* if we have no link-layer */
        if (text[2] == NULL)
index 60dce5050a6c777a36285aa45aee45d74c4e3b60..46d211377de0aec6fa66f4dd6769686262487c63 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -1640,22 +1640,25 @@ main(int argc, char *argv[])
     /* if requested, list the link layer types and exit */
     if (list_link_layer_types) {
         /* Get the list of link-layer types for the capture device. */
-        GList *lt_list;
-        gchar *error_string;
-
-        lt_list = capture_pcap_linktype_list(global_capture_opts.iface, &error_string);
-        if (lt_list == NULL) {
-            if (error_string != NULL) {
-                cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
-                 "Please check to make sure you have sufficient permissions, and that\n"
-                 "you have the proper interface or pipe specified.\n", global_capture_opts.iface, error_string);
-                g_free(error_string);
-            } else
-                cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+        if_capabilities_t *caps;
+
+        caps = capture_get_if_capabilities(global_capture_opts.iface,
+                                           global_capture_opts.monitor_mode,
+                                           &err_str);
+        if (caps == NULL) {
+            cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
+             "Please check to make sure you have sufficient permissions, and that\n"
+             "you have the proper interface or pipe specified.\n", global_capture_opts.iface, 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.", global_capture_opts.iface);
             exit(2);
         }
-        capture_opts_print_link_layer_types(lt_list);
-        free_pcap_linktype_list(lt_list);
+        capture_opts_print_if_capabilities(caps,
+                                           global_capture_opts.monitor_mode);
+        free_if_capabilities(caps);
         exit(0);
     }