summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2010-05-13 17:37:39 +0000
committerGuy Harris <guy@alum.mit.edu>2010-05-13 17:37:39 +0000
commit1c18115bd3e8a0b1a56ab8effcf5843240bde0c6 (patch)
tree29698446c6b8deeebed235c4337365c42d7d3f4a
parent951485bf355f1e9269bf62803190931618d7a047 (diff)
downloadwireshark-1c18115bd3e8a0b1a56ab8effcf5843240bde0c6.tar.gz
Fetch an indication of whether the interface supports capturing in
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. svn path=/trunk/; revision=32789
-rw-r--r--capture-pcap-util.c7
-rw-r--r--capture_ifinfo.c70
-rw-r--r--capture_ifinfo.h19
-rw-r--r--capture_opts.c13
-rw-r--r--capture_opts.h8
-rw-r--r--capture_sync.c10
-rw-r--r--capture_sync.h5
-rw-r--r--dumpcap.c146
-rw-r--r--gtk/capture_dlg.c56
-rw-r--r--gtk/main.c30
-rw-r--r--gtk/prefs_capture.c112
-rw-r--r--tshark.c31
12 files changed, 341 insertions, 166 deletions
diff --git a/capture-pcap-util.c b/capture-pcap-util.c
index 1c7815fa4e..1850b10acd 100644
--- a/capture-pcap-util.c
+++ b/capture-pcap-util.c
@@ -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 *
diff --git a/capture_ifinfo.c b/capture_ifinfo.c
index 53e024749f..e9fc5347a0 100644
--- a/capture_ifinfo.c
+++ b/capture_ifinfo.c
@@ -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 */
diff --git a/capture_ifinfo.h b/capture_ifinfo.h
index 28ebb5c701..e0cec1db7f 100644
--- a/capture_ifinfo.h
+++ b/capture_ifinfo.h
@@ -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 */
diff --git a/capture_opts.c b/capture_opts.c
index 96bec3c9af..23297b60eb 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -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);
diff --git a/capture_opts.h b/capture_opts.h
index fdf7672220..34709fce04 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -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
diff --git a/capture_sync.c b/capture_sync.c
index 6fe6fd1fc9..f412c4e51a 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -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
diff --git a/capture_sync.h b/capture_sync.h
index 26a6b7afe4..826c20d12d 100644
--- a/capture_sync.h
+++ b/capture_sync.h
@@ -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
diff --git a/dumpcap.c b/dumpcap.c
index 669c96d56b..ef865b97e7 100644
--- 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);
diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c
index a6831a88df..405cd173e1 100644
--- a/gtk/capture_dlg.c
+++ b/gtk/capture_dlg.c
@@ -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);
diff --git a/gtk/main.c b/gtk/main.c
index 5d4b5bc185..b5c82a7c5e 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -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);
}
diff --git a/gtk/prefs_capture.c b/gtk/prefs_capture.c
index 17cd411a32..6debfe3ae9 100644
--- a/gtk/prefs_capture.c
+++ b/gtk/prefs_capture.c
@@ -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)
diff --git a/tshark.c b/tshark.c
index 60dce5050a..46d211377d 100644
--- 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);
}