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
This commit is contained in:
Guy Harris 2010-05-13 17:37:39 +00:00
parent 951485bf35
commit 1c18115bd3
12 changed files with 342 additions and 167 deletions

View 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 *

View 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 */

View 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 */

View 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);

View 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

View 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

View 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

152
dumpcap.c
View File

@ -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;
pcap_t *pch;
int deflt;
if_capabilities_t *caps;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pch;
#ifdef HAVE_PCAP_CREATE
int status;
#endif
int deflt;
#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);
#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;
}
#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);
caps->can_set_rfmon = FALSE;
if (pch == NULL) {
if (err_str != NULL)
*err_str = g_strdup(errbuf);
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);

View 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 (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++;
}
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++;
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);

View 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;
if_capabilities_t *caps;
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);
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);
}

View 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)

View File

@ -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;
if_capabilities_t *caps;
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);
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);
}
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);
}