aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
}