diff options
-rw-r--r-- | capture-pcap-util.c | 7 | ||||
-rw-r--r-- | capture_ifinfo.c | 70 | ||||
-rw-r--r-- | capture_ifinfo.h | 19 | ||||
-rw-r--r-- | capture_opts.c | 13 | ||||
-rw-r--r-- | capture_opts.h | 8 | ||||
-rw-r--r-- | capture_sync.c | 10 | ||||
-rw-r--r-- | capture_sync.h | 5 | ||||
-rw-r--r-- | dumpcap.c | 146 | ||||
-rw-r--r-- | gtk/capture_dlg.c | 56 | ||||
-rw-r--r-- | gtk/main.c | 30 | ||||
-rw-r--r-- | gtk/prefs_capture.c | 112 | ||||
-rw-r--r-- | tshark.c | 31 |
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 @@ -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) @@ -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); } |