diff --git a/capture.c b/capture.c index eb3b042311..715eeac4c2 100644 --- a/capture.c +++ b/capture.c @@ -81,49 +81,49 @@ static GList *capture_callbacks = NULL; static void capture_callback_invoke(int event, capture_options *capture_opts) { - capture_callback_data_t *cb; - GList *cb_item = capture_callbacks; + capture_callback_data_t *cb; + GList *cb_item = capture_callbacks; - /* there should be at least one interested */ - g_assert(cb_item != NULL); + /* there should be at least one interested */ + g_assert(cb_item != NULL); - while(cb_item != NULL) { - cb = cb_item->data; - cb->cb_fct(event, capture_opts, cb->user_data); - cb_item = g_list_next(cb_item); - } + while(cb_item != NULL) { + cb = cb_item->data; + cb->cb_fct(event, capture_opts, cb->user_data); + cb_item = g_list_next(cb_item); + } } void capture_callback_add(capture_callback_t func, gpointer user_data) { - capture_callback_data_t *cb; + capture_callback_data_t *cb; - cb = g_malloc(sizeof(capture_callback_data_t)); - cb->cb_fct = func; - cb->user_data = user_data; + cb = g_malloc(sizeof(capture_callback_data_t)); + cb->cb_fct = func; + cb->user_data = user_data; - capture_callbacks = g_list_append(capture_callbacks, cb); + capture_callbacks = g_list_append(capture_callbacks, cb); } void capture_callback_remove(capture_callback_t func) { - capture_callback_data_t *cb; - GList *cb_item = capture_callbacks; + capture_callback_data_t *cb; + GList *cb_item = capture_callbacks; - while(cb_item != NULL) { - cb = cb_item->data; - if(cb->cb_fct == func) { - capture_callbacks = g_list_remove(capture_callbacks, cb); - g_free(cb); - return; - } - cb_item = g_list_next(cb_item); + while(cb_item != NULL) { + cb = cb_item->data; + if(cb->cb_fct == func) { + capture_callbacks = g_list_remove(capture_callbacks, cb); + g_free(cb); + return; } + cb_item = g_list_next(cb_item); + } - g_assert_not_reached(); + g_assert_not_reached(); } /** @@ -144,9 +144,8 @@ capture_start(capture_options *capture_opts) /* close the currently loaded capture file */ cf_close(capture_opts->cf); - + collect_ifaces(capture_opts); g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start ..."); - #ifdef _WIN32 if (capture_opts->ifaces->len < 2) { #else @@ -176,7 +175,6 @@ capture_start(capture_options *capture_opts) } cf_set_tempfile_source(capture_opts->cf, source->str); g_string_free(source, TRUE); - /* try to start the capture child process */ ret = sync_pipe_start(capture_opts); if(!ret) { @@ -548,239 +546,242 @@ capture_input_cfilter_error_message(capture_options *capture_opts, guint i, char void capture_input_closed(capture_options *capture_opts, gchar *msg) { - int err; - int packet_count_save; + int err; + int packet_count_save; - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!"); - g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING); + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!"); + g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING); - if (msg != NULL) - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg); - - /* if we didn't start the capture, do a fake start. */ - /* (happens if we got an error message - we won't get a filename then). */ - if(capture_opts->state == CAPTURE_PREPARING) { - if(capture_opts->real_time_mode) { - capture_callback_invoke(capture_cb_capture_update_started, capture_opts); - } else { - capture_callback_invoke(capture_cb_capture_fixed_started, capture_opts); - } - } + if (msg != NULL) + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg); + /* if we didn't start the capture, do a fake start. */ + /* (happens if we got an error message - we won't get a filename then). */ + if(capture_opts->state == CAPTURE_PREPARING) { if(capture_opts->real_time_mode) { - cf_read_status_t status; + capture_callback_invoke(capture_cb_capture_update_started, capture_opts); + } else { + capture_callback_invoke(capture_cb_capture_fixed_started, capture_opts); + } + } - /* Read what remains of the capture file. */ - status = cf_finish_tail(capture_opts->cf, &err); + if(capture_opts->real_time_mode) { + cf_read_status_t status; - /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */ - packet_count_save = cf_get_packet_count(capture_opts->cf); - /* Tell the GUI we are not doing a capture any more. - Must be done after the cf_finish_tail(), so file lengths are - correctly displayed */ - capture_callback_invoke(capture_cb_capture_update_finished, capture_opts); + /* Read what remains of the capture file. */ + status = cf_finish_tail(capture_opts->cf, &err); - /* Finish the capture. */ - switch (status) { + /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */ + packet_count_save = cf_get_packet_count(capture_opts->cf); + /* Tell the GUI we are not doing a capture any more. + Must be done after the cf_finish_tail(), so file lengths are + correctly displayed */ + capture_callback_invoke(capture_cb_capture_update_finished, capture_opts); - case CF_READ_OK: - if ((packet_count_save == 0) && !capture_opts->restart) { - simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, -"%sNo packets captured!%s\n" -"\n" -"As no data was captured, closing the %scapture file!\n" -"\n" -"\n" -"Help about capturing can be found at:\n" -"\n" -" http://wiki.wireshark.org/CaptureSetup" + /* Finish the capture. */ + switch (status) { + + case CF_READ_OK: + if ((packet_count_save == 0) && !capture_opts->restart) { + simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, + "%sNo packets captured!%s\n" + "\n" + "As no data was captured, closing the %scapture file!\n" + "\n" + "\n" + "Help about capturing can be found at:\n" + "\n" + " http://wiki.wireshark.org/CaptureSetup" #ifdef _WIN32 -"\n\n" -"Wireless (Wi-Fi/WLAN):\n" -"Try to switch off promiscuous mode in the Capture Options!" + "\n\n" + "Wireless (Wi-Fi/WLAN):\n" + "Try to switch off promiscuous mode in the Capture Options!" #endif -"", - simple_dialog_primary_start(), simple_dialog_primary_end(), - cf_is_tempfile(capture_opts->cf) ? "temporary " : ""); - cf_close(capture_opts->cf); - } - break; - case CF_READ_ERROR: - /* Just because we got an error, that doesn't mean we were unable - to read any of the file; we handle what we could get from the - file. */ - break; - - case CF_READ_ABORTED: - /* Exit by leaving the main loop, so that any quit functions - we registered get called. */ - main_window_quit(); - break; - } - - } else { - /* first of all, we are not doing a capture any more */ - capture_callback_invoke(capture_cb_capture_fixed_finished, capture_opts); - - /* this is a normal mode capture and if no error happened, read in the capture file data */ - if(capture_opts->save_file != NULL) { - capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf), - cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf)); - } - } - - if(capture_opts->show_info) - capture_info_close(); - - capture_opts->state = CAPTURE_STOPPED; - - /* if we couldn't open a capture file, there's nothing more for us to do */ - if(capture_opts->save_file == NULL) { + "", + simple_dialog_primary_start(), simple_dialog_primary_end(), + cf_is_tempfile(capture_opts->cf) ? "temporary " : ""); cf_close(capture_opts->cf); - return; + } + break; + case CF_READ_ERROR: + /* Just because we got an error, that doesn't mean we were unable + to read any of the file; we handle what we could get from the + file. */ + break; + + case CF_READ_ABORTED: + /* Exit by leaving the main loop, so that any quit functions + we registered get called. */ + main_window_quit(); + break; } - /* does the user wants to restart the current capture? */ - if(capture_opts->restart) { - capture_opts->restart = FALSE; + } else { + /* first of all, we are not doing a capture any more */ + capture_callback_invoke(capture_cb_capture_fixed_finished, capture_opts); - ws_unlink(capture_opts->save_file); - - /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */ - if(cf_is_tempfile(capture_opts->cf)) { - g_free(capture_opts->save_file); - capture_opts->save_file = NULL; - } - - /* ... and start the capture again */ - capture_start(capture_opts); - } else { - /* We're not doing a capture any more, so we don't have a save file. */ - g_free(capture_opts->save_file); - capture_opts->save_file = NULL; + /* this is a normal mode capture and if no error happened, read in the capture file data */ + if(capture_opts->save_file != NULL) { + capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf), + cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf)); } + } + + if(capture_opts->show_info) + capture_info_close(); + + capture_opts->state = CAPTURE_STOPPED; + + /* if we couldn't open a capture file, there's nothing more for us to do */ + if(capture_opts->save_file == NULL) { + cf_close(capture_opts->cf); + return; + } + + /* does the user wants to restart the current capture? */ + if(capture_opts->restart) { + capture_opts->restart = FALSE; + + ws_unlink(capture_opts->save_file); + + /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */ + if(cf_is_tempfile(capture_opts->cf)) { + g_free(capture_opts->save_file); + capture_opts->save_file = NULL; + } + + /* ... and start the capture again */ + if (capture_opts->ifaces->len == 0) { + collect_ifaces(capture_opts); + } + capture_start(capture_opts); + } else { + /* We're not doing a capture any more, so we don't have a save file. */ + g_free(capture_opts->save_file); + capture_opts->save_file = NULL; + } } if_stat_cache_t * -capture_stat_start(GList *if_list) { - int stat_fd, fork_child; - gchar *msg; - if_stat_cache_t *sc = NULL; - GList *if_entry; - if_info_t *if_info; - if_stat_cache_item_t *sc_item; +capture_stat_start(capture_options *capture_opts) { + int stat_fd, fork_child; + gchar *msg; + if_stat_cache_t *sc = NULL; + if_stat_cache_item_t *sc_item; + guint i; + interface_t device; - /* Fire up dumpcap. */ - /* - * XXX - on systems with BPF, the number of BPF devices limits the - * number of devices on which you can capture simultaneously. - * - * This means that - * - * 1) this might fail if you run out of BPF devices - * - * and - * - * 2) opening every interface could leave too few BPF devices - * for *other* programs. - * - * It also means the system could end up getting a lot of traffic - * that it has to pass through the networking stack and capture - * mechanism, so opening all the devices and presenting packet - * counts might not always be a good idea. - */ - if (sync_interface_stats_open(&stat_fd, &fork_child, &msg) == 0) { - sc = g_malloc(sizeof(if_stat_cache_t)); - sc->stat_fd = stat_fd; - sc->fork_child = fork_child; - sc->cache_list = NULL; + /* Fire up dumpcap. */ + /* + * XXX - on systems with BPF, the number of BPF devices limits the + * number of devices on which you can capture simultaneously. + * + * This means that + * + * 1) this might fail if you run out of BPF devices + * + * and + * + * 2) opening every interface could leave too few BPF devices + * for *other* programs. + * + * It also means the system could end up getting a lot of traffic + * that it has to pass through the networking stack and capture + * mechanism, so opening all the devices and presenting packet + * counts might not always be a good idea. + */ + if (sync_interface_stats_open(&stat_fd, &fork_child, &msg) == 0) { + sc = g_malloc(sizeof(if_stat_cache_t)); + sc->stat_fd = stat_fd; + sc->fork_child = fork_child; + sc->cache_list = NULL; - /* Initialize the cache */ - for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) { - if_info = if_entry->data; - if (if_info) { - sc_item = g_malloc0(sizeof(if_stat_cache_item_t)); - sc_item->name = g_strdup(if_info->name); - sc->cache_list = g_list_append(sc->cache_list, sc_item); - } - } + /* Initialize the cache */ + for (i = 0; i < capture_opts->all_ifaces->len; i++) { + device = g_array_index(capture_opts->all_ifaces, interface_t, i); + if (&(device.if_info)) { + sc_item = g_malloc0(sizeof(if_stat_cache_item_t)); + sc_item->name = g_strdup(device.if_info.name); + sc->cache_list = g_list_append(sc->cache_list, sc_item); + } } - return sc; + } + return sc; } #define MAX_STAT_LINE_LEN 500 static void capture_stat_cache_update(if_stat_cache_t *sc) { - gchar stat_line[MAX_STAT_LINE_LEN]; - gchar **stat_parts; - GList *sc_entry; - if_stat_cache_item_t *sc_item; + gchar stat_line[MAX_STAT_LINE_LEN]; + gchar **stat_parts; + GList *sc_entry; + if_stat_cache_item_t *sc_item; - if (!sc) - return; + if (!sc) + return; - while (sync_pipe_gets_nonblock(sc->stat_fd, stat_line, MAX_STAT_LINE_LEN) > 0) { - g_strstrip(stat_line); - stat_parts = g_strsplit(stat_line, "\t", 3); - if (stat_parts[0] == NULL || stat_parts[1] == NULL || - stat_parts[2] == NULL) { - g_strfreev(stat_parts); - continue; - } - for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) { - sc_item = sc_entry->data; - if (strcmp(sc_item->name, stat_parts[0]) == 0) { - sc_item->ps.ps_recv = (u_int) strtoul(stat_parts[1], NULL, 10); - sc_item->ps.ps_drop = (u_int) strtoul(stat_parts[2], NULL, 10); - } - } - g_strfreev(stat_parts); + while (sync_pipe_gets_nonblock(sc->stat_fd, stat_line, MAX_STAT_LINE_LEN) > 0) { + g_strstrip(stat_line); + stat_parts = g_strsplit(stat_line, "\t", 3); + if (stat_parts[0] == NULL || stat_parts[1] == NULL || + stat_parts[2] == NULL) { + g_strfreev(stat_parts); + continue; } + for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) { + sc_item = sc_entry->data; + if (strcmp(sc_item->name, stat_parts[0]) == 0) { + sc_item->ps.ps_recv = (u_int) strtoul(stat_parts[1], NULL, 10); + sc_item->ps.ps_drop = (u_int) strtoul(stat_parts[2], NULL, 10); + } + } + g_strfreev(stat_parts); + } } gboolean capture_stats(if_stat_cache_t *sc, char *ifname, struct pcap_stat *ps) { - GList *sc_entry; - if_stat_cache_item_t *sc_item; + GList *sc_entry; + if_stat_cache_item_t *sc_item; - if (!sc || !ifname || !ps) { - return FALSE; - } - - capture_stat_cache_update(sc); - for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) { - sc_item = sc_entry->data; - if (strcmp(sc_item->name, ifname) == 0) { - memcpy(ps, &sc_item->ps, sizeof(struct pcap_stat)); - return TRUE; - } - } + if (!sc || !ifname || !ps) { return FALSE; + } + + capture_stat_cache_update(sc); + for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) { + sc_item = sc_entry->data; + if (strcmp(sc_item->name, ifname) == 0) { + memcpy(ps, &sc_item->ps, sizeof(struct pcap_stat)); + return TRUE; + } + } + return FALSE; } void capture_stat_stop(if_stat_cache_t *sc) { - GList *sc_entry; - if_stat_cache_item_t *sc_item; - int ret; - gchar *msg; + GList *sc_entry; + if_stat_cache_item_t *sc_item; + int ret; + gchar *msg; - if (!sc) - return; + if (!sc) + return; - ret = sync_interface_stats_close(&sc->stat_fd, &sc->fork_child, &msg); - if (ret == -1) { - /* XXX - report failure? */ - g_free(msg); - } + ret = sync_interface_stats_close(&sc->stat_fd, &sc->fork_child, &msg); + if (ret == -1) { + /* XXX - report failure? */ + g_free(msg); + } - for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) { - sc_item = sc_entry->data; - g_free(sc_item->name); - g_free(sc_item); - } - g_free(sc); + for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) { + sc_item = sc_entry->data; + g_free(sc_item->name); + g_free(sc_item); + } + g_free(sc); } #endif /* HAVE_LIBPCAP */ diff --git a/capture.h b/capture.h index d4cc76986b..93ea812ba2 100644 --- a/capture.h +++ b/capture.h @@ -114,7 +114,7 @@ typedef struct if_stat_cache_s if_stat_cache_t; * @param if_list A GList of if_info_t items * @return A pointer to the statistics state data. */ -extern if_stat_cache_t * capture_stat_start(GList *if_list); +extern if_stat_cache_t * capture_stat_start(capture_options *capture_opts); /** * Fetch capture statistics, similar to pcap_stats(). diff --git a/capture_opts.c b/capture_opts.c index f200be3735..e2074b5555 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -38,6 +38,9 @@ #include #include +#include +#include "ui/simple_dialog.h" +#include "capture_ui_utils.h" #include "capture_opts.h" #include "ringbuffer.h" @@ -57,6 +60,8 @@ capture_opts_init(capture_options *capture_opts, void *cf) { capture_opts->cf = cf; capture_opts->ifaces = g_array_new(FALSE, FALSE, sizeof(interface_options)); + capture_opts->all_ifaces = g_array_new(FALSE, FALSE, sizeof(interface_t)); + capture_opts->num_selected = 0; capture_opts->default_options.name = NULL; capture_opts->default_options.descr = NULL; capture_opts->default_options.cfilter = NULL; @@ -431,7 +436,7 @@ get_auth_arguments(capture_options *capture_opts, const char *arg) } #endif -static int +int capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p) { long adapter_index; @@ -527,6 +532,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str return 0; } + int capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture) { @@ -827,7 +833,7 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt /* Did the user specify an interface to use? */ - if (capture_opts->ifaces->len == 0) { + if (capture_opts->num_selected == 0 && capture_opts->ifaces->len == 0) { /* No - is a default specified in the preferences file? */ if (capture_device != NULL) { /* Yes - use it. */ @@ -959,4 +965,49 @@ static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_ return 0; } +void +collect_ifaces(capture_options *capture_opts) +{ + guint i; + interface_t device; + interface_options interface_opts; + for (i = 0; i < capture_opts->all_ifaces->len; i++) { + device = g_array_index(capture_opts->all_ifaces, interface_t, i); + if (!device.hidden && device.selected) { + interface_opts.name = g_strdup(device.name); + interface_opts.descr = g_strdup(device.display_name); + interface_opts.monitor_mode = device.monitor_mode_enabled; + interface_opts.linktype = device.active_dlt; + interface_opts.cfilter = g_strdup(device.cfilter); + interface_opts.snaplen = device.snaplen; + interface_opts.has_snaplen = device.has_snaplen; + interface_opts.promisc_mode = device.pmode; +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + interface_opts.buffer_size = device.buffer; +#endif + if (!device.local) { +#ifdef HAVE_PCAP_REMOTE + interface_opts.src_type = CAPTURE_IFREMOTE; + interface_opts.remote_host = g_strdup(device.remote_opts.remote_host_opts.remote_host); + interface_opts.remote_port = g_strdup(device.remote_opts.remote_host_opts.remote_port); + interface_opts.auth_type = device.remote_opts.remote_host_opts.auth_type; + interface_opts.auth_username = g_strdup(device.remote_opts.remote_host_opts.auth_username); + interface_opts.auth_password = g_strdup(device.remote_opts.remote_host_opts.auth_password); + interface_opts.datatx_udp = device.remote_opts.remote_host_opts.datatx_udp; + interface_opts.nocap_rpcap = device.remote_opts.remote_host_opts.nocap_rpcap; + interface_opts.nocap_local = device.remote_opts.remote_host_opts.nocap_local; +#endif +#ifdef HAVE_PCAP_SETSAMPLING + interface_opts.sampling_method = device.remote_opts.sampling_method; + interface_opts.sampling_param = device.remote_opts.sampling_param; +#endif + } + g_array_append_val(capture_opts->ifaces, interface_opts); + } else { + continue; + } + } +} + + #endif /* HAVE_LIBPCAP */ diff --git a/capture_opts.h b/capture_opts.h index baa40099a7..a93ad457cc 100644 --- a/capture_opts.h +++ b/capture_opts.h @@ -77,6 +77,73 @@ typedef enum { } capture_sampling; #endif +typedef enum { + IF_WIRED, + IF_AIRPCAP, + IF_PIPE, + IF_STDIN, + IF_BLUETOOTH, + IF_WIRELESS, + IF_DIALUP, + IF_USB, + IF_VIRTUAL +} interface_type; + +#ifdef HAVE_PCAP_REMOTE +struct remote_host { + gchar *remote_host; /**< Host name or network address for remote capturing */ + gchar *remote_port; /**< TCP port of remote RPCAP server */ + gint auth_type; /**< Authentication type */ + gchar *auth_username; /**< Remote authentication parameters */ + gchar *auth_password; /**< Remote authentication parameters */ + gboolean datatx_udp; + gboolean nocap_rpcap; + gboolean nocap_local; +}; + +typedef struct remote_options_tag { + capture_source src_type; + struct remote_host remote_host_opts; +#ifdef HAVE_PCAP_SETSAMPLING + capture_sampling sampling_method; + int sampling_param; +#endif +} remote_options; +#endif /* HAVE_PCAP_REMOTE */ + +typedef struct interface_tag { + gchar *name; + gchar *display_name; + guint type; + gchar *addresses; + gint no_addresses; + gchar *cfilter; + GList *links; + gint active_dlt; + gboolean pmode; + gboolean has_snaplen; + guint snaplen; + gboolean local; +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + gint buffer; + gboolean monitor_mode_enabled; + gboolean monitor_mode_supported; +#endif +#ifdef HAVE_PCAP_REMOTE + remote_options remote_opts; +#endif + guint32 last_packets; + if_info_t if_info; + gboolean selected; + gboolean hidden; + gboolean locked; +} interface_t; + +typedef struct link_row_tag { + gchar *name; + gint dlt; +} link_row; + typedef struct interface_options_tag { gchar *name; gchar *descr; @@ -112,6 +179,8 @@ typedef struct capture_options_tag { void *cf; /**< handle to cfile (note: untyped handle) */ GArray *ifaces; /**< array of interfaces. Currently only used by dumpcap. */ + GArray *all_ifaces; + guint num_selected; interface_options default_options; gboolean saving_to_file; /**< TRUE if capture is writing to a file */ gchar *save_file; /**< the capture file name */ @@ -169,6 +238,9 @@ capture_opts_init(capture_options *capture_opts, void *cf); extern int capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture); +extern int +capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p); + /* log content of capture_opts */ extern void capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts); @@ -194,6 +266,24 @@ capture_opts_trim_ring_num_files(capture_options *capture_opts); extern gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capture_device); +extern void +collect_ifaces(capture_options *capture_opts); + +typedef struct { + gboolean monitor_mode; + int linktype; +} cap_settings_t; + +/** Get capture settings for interface + * + * @param if_name interface name + */ +cap_settings_t +capture_get_cap_settings (gchar *if_name); + +extern void +scan_local_interfaces(capture_options* capture_opts, int *error); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/capture_sync.c b/capture_sync.c index 02223ef28a..04614b2ebe 100644 --- a/capture_sync.c +++ b/capture_sync.c @@ -463,9 +463,11 @@ sync_pipe_start(capture_options *capture_opts) { } #endif +#ifdef HAVE_PCAP_CREATE if (interface_opts.monitor_mode) { argv = sync_pipe_add_arg(argv, &argc, "-I"); } +#endif #ifdef HAVE_PCAP_REMOTE if (interface_opts.datatx_udp) diff --git a/capture_ui_utils.c b/capture_ui_utils.c index 1ebe978c68..48bca7a31b 100644 --- a/capture_ui_utils.c +++ b/capture_ui_utils.c @@ -38,6 +38,9 @@ #include "epan/ex-opt.h" #include "capture_ifinfo.h" #include "capture_ui_utils.h" +#include "ui/simple_dialog.h" +#include "wiretap/wtap.h" +#include "epan/to_str.h" /* * Find user-specified capture device description that matches interface diff --git a/tshark.c b/tshark.c index 3419f5e5c4..efe2936d73 100644 --- a/tshark.c +++ b/tshark.c @@ -95,6 +95,7 @@ #endif /* HAVE_LIBPCAP */ #include "log.h" #include +#include "capture_opts.h" /* * This is the template for the decode as option; it is shared between the diff --git a/ui/gtk/capture_dlg.c b/ui/gtk/capture_dlg.c index 69965a0325..84e0fb6dd1 100644 --- a/ui/gtk/capture_dlg.c +++ b/ui/gtk/capture_dlg.c @@ -182,8 +182,7 @@ static GtkWidget *cap_open_w = NULL, *opt_edit_w = NULL, *ok_bt; static gboolean cap_open_complete; /* valid only if cap_open_w != NULL */ static GHashTable *cap_settings_history=NULL; -static gint16 num_selected; -static GArray *rows = NULL; +static gint marked_interface; static gint marked_row; #ifdef HAVE_PCAP_REMOTE @@ -218,9 +217,6 @@ capture_dlg_prep(gpointer parent_w); extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg); -static void -make_and_fill_rows(void); - /* stop the currently running capture */ void capture_stop_cb(GtkWidget *w _U_, gpointer d _U_) @@ -797,7 +793,7 @@ error_list_remote_interface_cb (gpointer dialog _U_, gint btn _U_, gpointer data static void insert_new_rows(GList *list) { - interface_row row; + interface_t device; GtkTreeIter iter; GList *if_entry; if_info_t *if_info; @@ -806,10 +802,9 @@ insert_new_rows(GList *list) if_capabilities_t *caps; gint linktype_count; cap_settings_t cap_settings; - gchar *err_str, *err_str_norfmon; GSList *curr_addr; int ips = 0; - guint i, count=0; + guint i; if_addr_t *addr; GList *lt_entry; data_link_info_t *data_link_info; @@ -818,21 +813,19 @@ insert_new_rows(GList *list) GString *ip_str; GtkTreeView *if_cb; GtkTreeModel *model; - interface_options interface_opts; link_row *link = NULL; if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY); model = gtk_tree_view_get_model(if_cb); - count = rows->len; /* Scan through the list and build a list of strings to display. */ for (if_entry = g_list_first(list); if_entry != NULL; if_entry = g_list_next(if_entry)) { if_info = (if_info_t *)if_entry->data; #ifdef HAVE_PCAP_REMOTE add_interface_to_remote_list(if_info); #endif - for (i = 0; i < count; i++) { - row = g_array_index(rows, interface_row, i); - if (strcmp(row.name, if_info->name) == 0) { + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (strcmp(device.name, if_info->name) == 0) { found = TRUE; break; } @@ -842,8 +835,9 @@ insert_new_rows(GList *list) continue; } ip_str = g_string_new(""); + str = ""; ips = 0; - row.name = g_strdup(if_info->name); + device.name = g_strdup(if_info->name); /* Is this interface hidden and, if so, should we include it anyway? */ descr = capture_dev_user_descr_find(if_info->name); @@ -863,82 +857,19 @@ insert_new_rows(GList *list) } } /* else descr != NULL */ if (if_info->loopback) { - row.display_name = g_strdup_printf("%s (loopback)", if_string); + device.display_name = g_strdup_printf("%s (loopback)", if_string); } else { - row.display_name = g_strdup(if_string); + device.display_name = g_strdup(if_string); } - found = FALSE; - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - if (strcmp(interface_opts.name, (char*)row.name)!=0) - continue; - else { - found = TRUE; - break; - } - } - if (found) { #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - row.buffer = interface_opts.buffer_size; + device.buffer = global_capture_opts.default_options.buffer_size; #endif - row.pmode = interface_opts.promisc_mode; - row.has_snaplen = interface_opts.has_snaplen; - row.snaplen = interface_opts.snaplen; - row.cfilter = g_strdup(interface_opts.cfilter); - } else { -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - row.buffer = global_capture_opts.default_options.buffer_size; -#endif - row.pmode = global_capture_opts.default_options.promisc_mode; - row.has_snaplen = global_capture_opts.default_options.has_snaplen; - row.snaplen = global_capture_opts.default_options.snaplen; - row.cfilter = g_strdup(global_capture_opts.default_options.cfilter); - } + device.pmode = global_capture_opts.default_options.promisc_mode; + device.has_snaplen = global_capture_opts.default_options.has_snaplen; + device.snaplen = global_capture_opts.default_options.snaplen; + device.cfilter = g_strdup(global_capture_opts.default_options.cfilter); cap_settings = capture_get_cap_settings(if_string); - caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, - &err_str); - if (caps == NULL) { - /* Error attempting to get interface capabilities. */ - if (cap_settings.monitor_mode) { - /* - * Perhaps this is the libpcap bug on Linux where - * attempting to set monitor mode with the Wireless - * Extensions ioctls doesn't work correctly. - * - * Try fetching the capabilities without monitor mode; - * if that succeeds, report the monitor-mode problem, - * and use the no-monitor-mode capabilities. If that - * fails, report that failure. In either case, force - * monitor mode off. - */ - cap_settings.monitor_mode = FALSE; - caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, - &err_str_norfmon); - if (caps == NULL) { - /* Epic fail. */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str_norfmon); - g_free(err_str_norfmon); - g_free(err_str); - } else { - /* - * OK, it's probably that bug. Suggest using airmon-ng, - * just in case the adapter has a mac80211 driver and - * libpcap was built without libnl so that it can't - * use the mac80211 features to create a monitor-mode - * device. - */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s\n\n" - "Try using airmon-ng, as suggested by CaptureSetup/WLAN in the Wireshark Wiki.", - err_str); - g_free(err_str); - } - } else { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - } - } - + caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, NULL); gtk_list_store_append (GTK_LIST_STORE(model), &iter); for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) { if (ips != 0) { @@ -959,11 +890,11 @@ insert_new_rows(GList *list) } } /* for curr_addr */ linktype_count = 0; - row.links = NULL; + device.links = NULL; if (caps != NULL) { #ifdef HAVE_PCAP_CREATE - row.monitor_mode_enabled = cap_settings.monitor_mode; - row.monitor_mode_supported = caps->can_set_rfmon; + device.monitor_mode_enabled = cap_settings.monitor_mode; + device.monitor_mode_supported = caps->can_set_rfmon; #endif 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; @@ -974,68 +905,69 @@ insert_new_rows(GList *list) } if (linktype_count == 0) { link_type_name = g_strdup(str); - row.active_dlt = data_link_info->dlt; + device.active_dlt = data_link_info->dlt; } link = (link_row *)g_malloc(sizeof(link_row)); link->dlt = data_link_info->dlt; link->name = g_strdup(str); - row.links = g_list_append(row.links, link); + device.links = g_list_append(device.links, link); linktype_count++; } /* for link_types */ } else { cap_settings.monitor_mode = FALSE; #if defined(HAVE_PCAP_CREATE) - row.monitor_mode_enabled = FALSE; - row.monitor_mode_supported = FALSE; + device.monitor_mode_enabled = FALSE; + device.monitor_mode_supported = FALSE; #endif - row.active_dlt = -1; + device.active_dlt = -1; link_type_name = g_strdup("default"); } - row.addresses = g_strdup(ip_str->str); - row.no_addresses = ips; + device.addresses = g_strdup(ip_str->str); + device.no_addresses = ips; if (ips == 0) { - temp = g_strdup_printf("%s", row.display_name); + temp = g_strdup_printf("%s", device.display_name); } else { - temp = g_strdup_printf("%s\n%s", row.display_name, row.addresses); + temp = g_strdup_printf("%s\n%s", device.display_name, device.addresses); } #ifdef HAVE_PCAP_REMOTE - row.remote_opts.src_type= global_remote_opts.src_type; - row.remote_opts.remote_host_opts.remote_host = g_strdup(global_remote_opts.remote_host_opts.remote_host); - row.remote_opts.remote_host_opts.remote_port = g_strdup(global_remote_opts.remote_host_opts.remote_port); - row.remote_opts.remote_host_opts.auth_type = global_remote_opts.remote_host_opts.auth_type; - row.remote_opts.remote_host_opts.auth_username = g_strdup(global_remote_opts.remote_host_opts.auth_username); - row.remote_opts.remote_host_opts.auth_password = g_strdup(global_remote_opts.remote_host_opts.auth_password); - row.remote_opts.remote_host_opts.datatx_udp = global_remote_opts.remote_host_opts.datatx_udp; - row.remote_opts.remote_host_opts.nocap_rpcap = global_remote_opts.remote_host_opts.nocap_rpcap; - row.remote_opts.remote_host_opts.nocap_local = global_remote_opts.remote_host_opts.nocap_local; + device.remote_opts.src_type= global_remote_opts.src_type; + device.remote_opts.remote_host_opts.remote_host = g_strdup(global_remote_opts.remote_host_opts.remote_host); + device.remote_opts.remote_host_opts.remote_port = g_strdup(global_remote_opts.remote_host_opts.remote_port); + device.remote_opts.remote_host_opts.auth_type = global_remote_opts.remote_host_opts.auth_type; + device.remote_opts.remote_host_opts.auth_username = g_strdup(global_remote_opts.remote_host_opts.auth_username); + device.remote_opts.remote_host_opts.auth_password = g_strdup(global_remote_opts.remote_host_opts.auth_password); + device.remote_opts.remote_host_opts.datatx_udp = global_remote_opts.remote_host_opts.datatx_udp; + device.remote_opts.remote_host_opts.nocap_rpcap = global_remote_opts.remote_host_opts.nocap_rpcap; + device.remote_opts.remote_host_opts.nocap_local = global_remote_opts.remote_host_opts.nocap_local; #endif #ifdef HAVE_PCAP_SETSAMPLING - row.remote_opts.sampling_method = global_remote_opts.sampling_method; - row.remote_opts.sampling_param = global_remote_opts.sampling_param; + device.remote_opts.sampling_method = global_remote_opts.sampling_method; + device.remote_opts.sampling_param = global_remote_opts.sampling_param; #endif - g_array_append_val(rows, row); - if (row.has_snaplen) { - snaplen_string = g_strdup_printf("%d", row.snaplen); + g_array_append_val(global_capture_opts.all_ifaces, device); + if (device.has_snaplen) { + snaplen_string = g_strdup_printf("%d", device.snaplen); } else { snaplen_string = g_strdup("default"); } #if defined(HAVE_PCAP_CREATE) - gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, MONITOR, "no",FILTER, "",-1); + gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, MONITOR, "no",FILTER, "",-1); #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE) - gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, FILTER, "",-1); + gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, FILTER, "",-1); #else - gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, -1); + gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, -1); #endif - count++; g_string_free(ip_str, TRUE); #ifdef HAVE_PCAP_REMOTE - add_interface_to_list(if_info->name, if_info->description, &row.remote_opts); + add_interface_to_list(global_capture_opts.all_ifaces->len-1); #endif } /*for*/ gtk_tree_view_set_model(GTK_TREE_VIEW(if_cb), model); } +#endif +#ifdef HAVE_PCAP_REMOTE /* Retrieve the list of local or remote interfaces according to selected * options and re-fill interface name combobox */ static void @@ -1356,19 +1288,19 @@ options_remote_ok_cb(GtkWidget *win _U_, GtkWidget *parent_w) GtkWidget *samp_none_rb, *samp_count_rb, *samp_timer_rb, *samp_count_sb, *samp_timer_sb; #endif - interface_row row; + interface_t device; if (parent_w == NULL) return; - row = g_array_index(rows, interface_row, marked_row); - g_array_remove_index(rows, marked_row); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface); + g_array_remove_index(global_capture_opts.all_ifaces, marked_interface); datatx_udp_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_DATATX_UDP_CB_KEY); nocap_rpcap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_NOCAP_RPCAP_CB_KEY); - row.remote_opts.remote_host_opts.datatx_udp = + device.remote_opts.remote_host_opts.datatx_udp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(datatx_udp_cb)); - row.remote_opts.remote_host_opts.nocap_rpcap = + device.remote_opts.remote_host_opts.nocap_rpcap = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb)); #ifdef HAVE_PCAP_SETSAMPLING @@ -1379,16 +1311,16 @@ options_remote_ok_cb(GtkWidget *win _U_, GtkWidget *parent_w) samp_timer_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_SB_KEY); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_none_rb))) - row.remote_opts.sampling_method = CAPTURE_SAMP_NONE; + device.remote_opts.sampling_method = CAPTURE_SAMP_NONE; else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb))) { - row.remote_opts.sampling_method = CAPTURE_SAMP_BY_COUNT; - row.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_count_sb)); + device.remote_opts.sampling_method = CAPTURE_SAMP_BY_COUNT; + device.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_count_sb)); } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb))) { - row.remote_opts.sampling_method = CAPTURE_SAMP_BY_TIMER; - row.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_timer_sb)); + device.remote_opts.sampling_method = CAPTURE_SAMP_BY_TIMER; + device.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_timer_sb)); } #endif /* HAVE_PCAP_SETSAMPLING*/ - g_array_insert_val(rows, marked_row, row); + g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device); window_destroy(GTK_WIDGET(parent_w)); } #endif /*HAVE_PCAP_REMOTE*/ @@ -1430,7 +1362,7 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_) GtkAdjustment *samp_count_adj, *samp_timer_adj; GSList *samp_group; #endif - interface_row row; + interface_t device; caller = gtk_widget_get_toplevel(w); opt_remote_w = g_object_get_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY); @@ -1439,7 +1371,7 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_) return; } - row = g_array_index(rows, interface_row, marked_row); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface); opt_remote_w = dlg_window_new("Remote Capture Settings"); g_object_set_data(G_OBJECT(opt_remote_w), E_OPT_REMOTE_CALLER_PTR_KEY, caller); g_object_set_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY, opt_remote_w); @@ -1458,12 +1390,12 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_) nocap_rpcap_cb = gtk_check_button_new_with_mnemonic("Do not capture own RPCAP traffic"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb), - row.remote_opts.remote_host_opts.nocap_rpcap); + device.remote_opts.remote_host_opts.nocap_rpcap); gtk_container_add(GTK_CONTAINER(capture_vb), nocap_rpcap_cb); datatx_udp_cb = gtk_check_button_new_with_mnemonic("Use UDP for data transfer"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(datatx_udp_cb), - row.remote_opts.remote_host_opts.datatx_udp); + device.remote_opts.remote_host_opts.datatx_udp); gtk_container_add(GTK_CONTAINER(capture_vb), datatx_udp_cb); #ifdef HAVE_PCAP_SETSAMPLING @@ -1482,7 +1414,7 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_) /* "No sampling" row */ samp_none_rb = gtk_radio_button_new_with_label(NULL, "None"); - if (row.remote_opts.sampling_method == CAPTURE_SAMP_NONE) + if (device.remote_opts.sampling_method == CAPTURE_SAMP_NONE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_none_rb), TRUE); g_signal_connect(samp_none_rb, "toggled", G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w); @@ -1491,14 +1423,14 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_) /* "Sampling by counter" row */ samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_none_rb)); samp_count_rb = gtk_radio_button_new_with_label(samp_group, "1 of"); - if (row.remote_opts.sampling_method == CAPTURE_SAMP_BY_COUNT) + if (device.remote_opts.sampling_method == CAPTURE_SAMP_BY_COUNT) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_count_rb), TRUE); g_signal_connect(samp_count_rb, "toggled", G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w); gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_count_rb, 0, 1, 1, 2); samp_count_adj = (GtkAdjustment *) gtk_adjustment_new( - (gfloat)row.remote_opts.sampling_param, + (gfloat)device.remote_opts.sampling_param, 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0); samp_count_sb = gtk_spin_button_new(samp_count_adj, 0, 0); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_count_sb), TRUE); @@ -1511,14 +1443,14 @@ options_remote_cb(GtkWidget *w _U_, gpointer d _U_) /* "Sampling by timer" row */ samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_count_rb)); samp_timer_rb = gtk_radio_button_new_with_label(samp_group, "1 every"); - if (row.remote_opts.sampling_method == CAPTURE_SAMP_BY_TIMER) + if (device.remote_opts.sampling_method == CAPTURE_SAMP_BY_TIMER) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_timer_rb), TRUE); g_signal_connect(samp_timer_rb, "toggled", G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w); gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_timer_rb, 0, 1, 2, 3); samp_timer_adj = (GtkAdjustment *) gtk_adjustment_new( - (gfloat)row.remote_opts.sampling_param, + (gfloat)device.remote_opts.sampling_param, 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0); samp_timer_sb = gtk_spin_button_new(samp_timer_adj, 0, 0); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_timer_sb), TRUE); @@ -1709,131 +1641,83 @@ options_edit_destroy_cb(GtkWidget *win, gpointer user_data _U_) static void update_options_table(gint index) { - guint i; - gboolean found = FALSE; - interface_row row; - interface_options interface_opts; + interface_t device; GtkTreePath *path; GtkTreeView *if_cb; GtkTreeModel *model; GtkTreeIter iter; - gchar *temp, *path_str, *snaplen_string; + gchar *temp, *path_str, *snaplen_string, *linkname=""; GList *list; link_row *link = NULL; gboolean enabled; - row = g_array_index(rows, interface_row, index); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface); - if (global_capture_opts.ifaces->len > 0) { - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - if (strcmp(interface_opts.name, row.name) == 0) { - found = TRUE; + if (!device.hidden) { + if (device.no_addresses == 0) { + temp = g_strdup_printf("%s", device.display_name); + } else { + temp = g_strdup_printf("%s\n%s", device.display_name, device.addresses); + } + for (list=device.links; list!=NULL; list=g_list_next(list)) + { + link = (link_row*)(list->data); + linkname = g_strdup(link->name); + if (link->dlt == device.active_dlt) { break; } } - if (found) { - global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i); - g_free(interface_opts.cfilter); - interface_opts.linktype = row.active_dlt; - interface_opts.promisc_mode = row.pmode; - interface_opts.has_snaplen = row.has_snaplen; - interface_opts.snaplen = row.snaplen; - interface_opts.cfilter = g_strdup(row.cfilter); -#ifdef HAVE_PCAP_CREATE - interface_opts.monitor_mode = row.monitor_mode_enabled; -#else - interface_opts.monitor_mode = FALSE; -#endif -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = row.buffer; -#endif - g_array_insert_val(global_capture_opts.ifaces, i, interface_opts); - } - } - if (!found || global_capture_opts.ifaces->len == 0) { - interface_opts.name = g_strdup(row.name); - interface_opts.descr = get_interface_descriptive_name(interface_opts.name); - interface_opts.linktype = row.active_dlt; - interface_opts.promisc_mode = row.pmode; - interface_opts.has_snaplen = row.has_snaplen; - interface_opts.snaplen = row.snaplen; - interface_opts.cfilter = g_strdup(row.cfilter); -#ifdef HAVE_PCAP_CREATE - interface_opts.monitor_mode = row.monitor_mode_enabled; -#else - interface_opts.monitor_mode = FALSE; -#endif -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = row.buffer; -#endif -#ifdef HAVE_PCAP_REMOTE - interface_opts.src_type = global_capture_opts.default_options.src_type; - interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - interface_opts.auth_type = global_capture_opts.default_options.auth_type; - interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; -#endif -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; - interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; -#endif - g_array_append_val(global_capture_opts.ifaces, interface_opts); - } - if (row.no_addresses == 0) { - temp = g_strdup_printf("%s", row.display_name); - } else { - temp = g_strdup_printf("%s\n%s", row.display_name, row.addresses); - } - for (list=row.links; list!=NULL; list=g_list_next(list)) - { - link = (link_row*)(list->data); - if (link->dlt == row.active_dlt) { - break; - } - } - if (row.has_snaplen) { - snaplen_string = g_strdup_printf("%d", row.snaplen); - } else { - snaplen_string = g_strdup("default"); - } - if (cap_open_w) { - if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY); - path_str = g_strdup_printf("%d", marked_row); - path = gtk_tree_path_new_from_string(path_str); - model = gtk_tree_view_get_model(if_cb); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get(model, &iter, CAPTURE, &enabled, -1); - if (enabled == FALSE) { - num_selected++; - } - -#if defined(HAVE_PCAP_CREATE) - gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp, LINK, link->name, PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, MONITOR, row.monitor_mode_supported?(row.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, row.cfilter, -1); -#elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE) - gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp,LINK, link->name, PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, FILTER, row.cfilter, -1); -#else - gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp,LINK, link->name, PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, row.cfilter, -1); -#endif - if (num_selected > 0) { - gtk_widget_set_sensitive(ok_bt, TRUE); + if (device.has_snaplen) { + snaplen_string = g_strdup_printf("%d", device.snaplen); } else { - gtk_widget_set_sensitive(ok_bt, FALSE); + snaplen_string = g_strdup("default"); + } + if (cap_open_w) { + if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY); + path_str = g_strdup_printf("%d", index); + path = gtk_tree_path_new_from_string(path_str); + model = gtk_tree_view_get_model(if_cb); + gtk_tree_model_get(model, &iter, CAPTURE, &enabled, -1); + if (enabled == FALSE) { + device.selected = TRUE; + global_capture_opts.num_selected++; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface); + g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device); + } + #if defined(HAVE_PCAP_CREATE) + gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname, PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, MONITOR, device.monitor_mode_supported?(device.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, device.cfilter, -1); + #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE) + gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, linkname, PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, FILTER, device.cfilter, -1); + #else + gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, linkname, PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, device.cfilter, -1); + #endif + if (global_capture_opts.num_selected > 0) { + gtk_widget_set_sensitive(ok_bt, TRUE); + } else { + gtk_widget_set_sensitive(ok_bt, FALSE); + } + gtk_tree_path_free (path); + } + if (interfaces_dialog_window_present()) { + update_selected_interface(g_strdup(device.name)); + } + if (get_welcome_window() != NULL) { + change_interface_selection(g_strdup(device.name), device.selected); } - gtk_tree_path_free (path); - } - if (interfaces_dialog_window_present()) { - update_selected_interface(g_strdup(row.name), TRUE); - } - if (get_welcome_window() != NULL) { - change_interface_selection(g_strdup(row.name), TRUE); } } + +void +update_all_rows(void) +{ + GtkTreeView *view; + + view = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY); + create_and_fill_model(GTK_TREE_VIEW(view)); +} + + static void save_options_cb(GtkWidget *win _U_, gpointer user_data _U_) { @@ -1846,13 +1730,13 @@ save_options_cb(GtkWidget *win _U_, gpointer user_data _U_) GtkWidget *buffer_size_sb; #endif - interface_row row; + interface_t device; gpointer ptr; int dlt; const gchar *filter_text; - - row = g_array_index(rows, interface_row, marked_row); - rows = g_array_remove_index(rows, marked_row); + + device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface); + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface); snap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY); snap_sb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY); #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) @@ -1866,37 +1750,36 @@ save_options_cb(GtkWidget *win _U_, gpointer user_data _U_) linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY); - if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) { + if (device.links != NULL && !ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) { g_assert_not_reached(); /* Programming error: somehow nothing is active */ } - if ((dlt = GPOINTER_TO_INT(ptr)) == -1) { + if ((dlt = GPOINTER_TO_INT(ptr)) == -1 && device.links != NULL) { g_assert_not_reached(); /* Programming error: somehow managed to select an "unsupported" entry */ } - row.active_dlt = dlt; + device.active_dlt = dlt; #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - row.buffer = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb)); + device.buffer = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb)); #endif - row.pmode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb)); - row.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); - if (row.has_snaplen) { - row.snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb)); - if (row.snaplen < 1) - row.snaplen = WTAP_MAX_PACKET_SIZE; - else if (row.snaplen < MIN_PACKET_SIZE) - row.snaplen = MIN_PACKET_SIZE; + device.pmode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb)); + device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); + if (device.has_snaplen) { + device.snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb)); + if (device.snaplen < 1) + device.snaplen = WTAP_MAX_PACKET_SIZE; + else if (device.snaplen < MIN_PACKET_SIZE) + device.snaplen = MIN_PACKET_SIZE; } else { - row.snaplen = WTAP_MAX_PACKET_SIZE; + device.snaplen = WTAP_MAX_PACKET_SIZE; } - filter_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(filter_cm)); - if (row.cfilter) - g_free(row.cfilter); + if (device.cfilter) + g_free(device.cfilter); g_assert(filter_text != NULL); - row.cfilter = g_strdup(filter_text); + device.cfilter = g_strdup(filter_text); #ifdef HAVE_PCAP_CREATE - row.monitor_mode_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb)); + device.monitor_mode_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb)); #endif - g_array_insert_val(rows, marked_row, row); + g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device); window_destroy(opt_edit_w); update_options_table(marked_row); } @@ -1905,10 +1788,10 @@ static void adjust_snap_sensitivity(GtkWidget *tb _U_, gpointer parent_w _U_) { GtkWidget *snap_cb, *snap_sb; - interface_row row; + interface_t device; - row = g_array_index(rows, interface_row, marked_row); - rows = g_array_remove_index(rows, marked_row); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface); + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface); snap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY); snap_sb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY); @@ -1917,13 +1800,13 @@ adjust_snap_sensitivity(GtkWidget *tb _U_, gpointer parent_w _U_) to" checkbox is on. */ gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb))); - row.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); - g_array_insert_val(rows, marked_row, row); + device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); + g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device); } void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column _U_, gpointer userdata) { - GtkWidget *caller, *window, *swindow=NULL, + GtkWidget *caller, *window, *swindow=NULL, *if_view, *main_vb, *if_hb, *if_lb, *if_lb_name, *main_hb, *left_vb, #if defined (HAVE_AIRPCAP) || defined (HAVE_PCAP_REMOTE) || defined (HAVE_PCAP_CREATE) @@ -1956,61 +1839,60 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum #ifdef HAVE_AIRPCAP GtkWidget *advanced_bt; #endif - interface_row row; - displayed_interface d_interface; + interface_t device; GtkTreeModel *model; GtkTreeIter iter; link_row *temp; gboolean found = FALSE; gint num_supported_link_types; guint i; - gchar *tok; + gchar *tok, *name; + GtkCellRenderer *renderer; + GtkListStore *store; window = (GtkWidget *)userdata; caller = gtk_widget_get_toplevel(GTK_WIDGET(window)); - opt_edit_w = (GtkWidget *)g_object_get_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY); + opt_edit_w = g_object_get_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY); if (opt_edit_w != NULL) { reactivate_window(opt_edit_w); return; } - row.name = NULL; - row.display_name = NULL; - row.no_addresses = 0; - row.addresses = NULL; - row.links = NULL; - row.active_dlt = -1; - row.pmode = FALSE; + device.name = NULL; + device.display_name = NULL; + device.no_addresses = 0; + device.addresses = NULL; + device.links = NULL; + device.active_dlt = -1; + device.pmode = FALSE; #ifdef HAVE_PCAP_CREATE - row.monitor_mode_enabled = FALSE; - row.monitor_mode_supported = FALSE; + device.monitor_mode_enabled = FALSE; + device.monitor_mode_supported = FALSE; #endif - row.has_snaplen = FALSE; - row.snaplen = 65535; - row.cfilter = NULL; + device.has_snaplen = FALSE; + device.snaplen = 65535; + device.cfilter = NULL; #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - row.buffer = 1; + device.buffer = 1; #endif model = gtk_tree_view_get_model(view); gtk_tree_model_get_iter (model, &iter, path); - marked_row = atoi(gtk_tree_path_to_string(path)); - - if (cap_open_w) { - row = g_array_index(rows, interface_row, marked_row); - } else if (get_welcome_window() != NULL) { - d_interface = get_interface_data(marked_row); - if (!rows || rows->len == 0) { - make_and_fill_rows(); - } - for (i = 0; i < rows->len; i++) { - row = g_array_index(rows, interface_row, i); - if (strcmp(row.name, (char*)d_interface.name)==0) { - marked_row = i; - break; - } + + if (window == get_welcome_window()) { + gtk_tree_model_get(model, &iter, IFACE_NAME, &name, -1); + } else if (window == cap_open_w) { + gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &name, -1); + } + + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (strcmp(device.name, name) == 0) { + marked_interface = i; + break; } } + marked_row = atoi(gtk_tree_path_to_string(path)); opt_edit_w = dlg_window_new("Edit Interface Settings"); g_object_set_data(G_OBJECT(opt_edit_w), E_OPT_EDIT_CALLER_PTR_KEY, caller); g_object_set_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY, opt_edit_w); @@ -2034,7 +1916,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum if_lb = gtk_label_new("Interface: "); gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 3); - if_lb_name = gtk_label_new(row.display_name); + if_lb_name = gtk_label_new(device.display_name); gtk_box_pack_start(GTK_BOX(if_hb), if_lb_name, FALSE, FALSE, 3); /* IP addresses row */ @@ -2049,22 +1931,29 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum if_ip_lb = gtk_label_new("IP address:"); gtk_misc_set_alignment(GTK_MISC(if_ip_lb), 0, 0); /* Left justified */ gtk_box_pack_start(GTK_BOX(if_vb_left), if_ip_lb, FALSE, FALSE, 0); - - if (row.no_addresses > 0) { - GtkWidget *if_ip_list = gtk_vbox_new(FALSE, 0); - gchar *temp_addresses = g_strdup(row.addresses); + if (device.no_addresses > 0) { + gchar *temp_addresses = g_strdup(device.addresses); gtk_box_pack_start(GTK_BOX(capture_vb), if_ip_hb, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, TRUE, TRUE, 3); swindow = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_NONE); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_widget_set_size_request(GTK_WIDGET(swindow), -1, 50); + gtk_widget_set_size_request(GTK_WIDGET(swindow),-1, 50); + if_view = gtk_tree_view_new (); + g_object_set(G_OBJECT(if_view), "headers-visible", FALSE, NULL); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + GTK_CELL_RENDERER(renderer), + "text", 0, + NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column); + store = gtk_list_store_new(1, G_TYPE_STRING); for (tok = strtok (temp_addresses, "\n"); tok; tok = strtok(NULL, "\n")) { - if_ip_name = gtk_label_new(tok); - gtk_misc_set_alignment(GTK_MISC(if_ip_name), 0, 0); /* Left justified */ - gtk_box_pack_start(GTK_BOX(if_ip_list), if_ip_name, FALSE, FALSE, 3); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, tok, -1); } - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(swindow), if_ip_list); + gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store)); + gtk_container_add (GTK_CONTAINER (swindow), if_view); gtk_box_pack_start(GTK_BOX(if_vb_right), swindow, TRUE, TRUE, 0); g_free(temp_addresses); } else { @@ -2124,7 +2013,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_combo_box, FALSE, FALSE, 0); g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY, linktype_combo_box); num_supported_link_types = 0; - for (list=row.links; list!=NULL; list=g_list_next(list)) + for (list=device.links; list!=NULL; list=g_list_next(list)) { temp = (link_row*)(list->data); ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box), @@ -2132,7 +2021,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum GINT_TO_POINTER(temp->dlt) /* Flag as "not supported" */ ); num_supported_link_types++; - if (temp->dlt == row.active_dlt) { + if (temp->dlt == device.active_dlt) { ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box), num_supported_link_types - 1); found = TRUE; } @@ -2148,7 +2037,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum promisc_cb = gtk_check_button_new_with_mnemonic( "Capture packets in _promiscuous mode"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb), - row.pmode); + device.pmode); gtk_widget_set_tooltip_text(promisc_cb, "Usually a network adapter will only capture the traffic sent to its own network address. " "If you want to capture all traffic that the network adapter can \"see\", mark this option. " @@ -2159,8 +2048,8 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum #ifdef HAVE_PCAP_CREATE /* Monitor mode row */ monitor_cb = gtk_check_button_new_with_mnemonic( "Capture packets in monitor mode"); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor_cb), row.monitor_mode_enabled); - gtk_widget_set_sensitive(monitor_cb, row.monitor_mode_supported); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor_cb), device.monitor_mode_enabled); + gtk_widget_set_sensitive(monitor_cb, device.monitor_mode_supported); g_signal_connect(monitor_cb, "toggled", G_CALLBACK(capture_prep_monitor_changed_cb), NULL); gtk_widget_set_tooltip_text(monitor_cb, @@ -2186,14 +2075,14 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum snap_cb = gtk_check_button_new_with_mnemonic("_Limit each packet to"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(snap_cb), - row.has_snaplen); + device.has_snaplen); g_signal_connect(snap_cb, "toggled", G_CALLBACK(adjust_snap_sensitivity), NULL); gtk_widget_set_tooltip_text(snap_cb, "Limit the maximum number of bytes to be captured from each packet. This size includes the " "link-layer header and all subsequent headers. "); gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0); - snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) row.snaplen, + snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) device.snaplen, MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0); snap_sb = gtk_spin_button_new (snap_adj, 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE); @@ -2205,7 +2094,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum snap_lb = gtk_label_new("bytes"); gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5f); gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0); - gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), row.has_snaplen); + gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), device.has_snaplen); /* Filter row */ filter_hb = gtk_hbox_new(FALSE, 3); @@ -2238,8 +2127,8 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum if (global_capture_opts.default_options.cfilter && (strlen(global_capture_opts.default_options.cfilter) > 0)) { gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), global_capture_opts.default_options.cfilter); } - if (row.cfilter && (strlen(row.cfilter) > 0)) { - gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), row.cfilter); + if (device.cfilter && (strlen(device.cfilter) > 0)) { + gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), device.cfilter); gtk_combo_box_set_active(GTK_COMBO_BOX(filter_cm), 0); } @@ -2266,10 +2155,10 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum buffer_size_lb = gtk_label_new("Buffer size:"); gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_lb, FALSE, FALSE, 0); - buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) row.buffer, + buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) device.buffer, 1, 65535, 1.0, 10.0, 0.0); buffer_size_sb = gtk_spin_button_new (buffer_size_adj, 0, 0); - gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) row.buffer); + gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) device.buffer); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (buffer_size_sb), TRUE); gtk_widget_set_size_request(buffer_size_sb, 80, -1); gtk_widget_set_tooltip_text(buffer_size_sb, @@ -2293,7 +2182,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum /* Both the callback and the data are global */ g_signal_connect(remote_bt, "clicked", G_CALLBACK(options_remote_cb), NULL); g_object_set_data(G_OBJECT(opt_edit_w), E_OPT_REMOTE_BT_KEY, remote_bt); - if (strncmp (row.name, "rpcap://", 8) == 0) { + if (strncmp (device.name, "rpcap://", 8) == 0) { gtk_widget_set_sensitive(remote_bt, TRUE); } else { gtk_widget_set_sensitive(remote_bt, FALSE); @@ -2308,7 +2197,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum /* Both the callback and the data are global */ g_signal_connect(advanced_bt,"clicked", G_CALLBACK(options_airpcap_advanced_cb), airpcap_tb); g_object_set_data(G_OBJECT(top_level),AIRPCAP_OPTIONS_ADVANCED_KEY, advanced_bt); - airpcap_if_selected = get_airpcap_if_from_name(airpcap_if_list, row.name); + airpcap_if_selected = get_airpcap_if_from_name(airpcap_if_list, device.name); if (airpcap_if_selected != NULL) { /* It is an airpcap interface */ gtk_widget_set_sensitive(advanced_bt, TRUE); @@ -2324,7 +2213,7 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL); gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5); - ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK); + ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK); g_signal_connect(ok_bt, "clicked", G_CALLBACK(save_options_cb), NULL); gtk_widget_set_tooltip_text(ok_bt, "Accept interface settings."); @@ -2338,7 +2227,6 @@ void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColum g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_CAPTURE_OPTIONS_DIALOG); gtk_widget_grab_default(ok_bt); dlg_set_activate(filter_te, ok_bt); - gtk_widget_grab_focus(filter_te); g_signal_connect(opt_edit_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL); g_signal_connect(opt_edit_w, "destroy", G_CALLBACK(options_edit_destroy_cb), NULL); gtk_widget_show_all(opt_edit_w); @@ -2354,191 +2242,87 @@ static void toggle_callback(GtkCellRendererToggle *cell _U_, GtkTreeView *if_cb; GtkTreeModel *model; GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - gboolean enabled, found = FALSE; + gboolean enabled; GtkWidget *pcap_ng_cb; - interface_options interface_opts; - interface_row row; - int index = atoi(path_str); + interface_t device; + gchar *name; + gint index = -1; guint i; if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY); model = gtk_tree_view_get_model(if_cb); gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, CAPTURE, &enabled, -1); - row = g_array_index(rows, interface_row, index); - if (enabled == FALSE) - num_selected++; - else - num_selected--; - enabled ^= 1; - pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY); - if (num_selected >= 2) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE); - gtk_widget_set_sensitive(pcap_ng_cb, FALSE); - } else { - gtk_widget_set_sensitive(pcap_ng_cb, TRUE); - } - if (num_selected > 0) { - gtk_widget_set_sensitive(ok_bt, TRUE); - } else { - gtk_widget_set_sensitive(ok_bt, FALSE); - } - /* do something with the new enabled value, and set the new - enabled value in your treemodel */ - gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enabled, -1); - - if (global_capture_opts.ifaces->len > 0) { - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - if (strcmp(interface_opts.name, row.name) == 0) { - found = TRUE; - break; - } - } - if (found) { - global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i); - g_free(interface_opts.cfilter); - if (enabled) { - interface_opts.linktype = row.active_dlt; - interface_opts.promisc_mode = row.pmode; - interface_opts.has_snaplen = row.has_snaplen; - interface_opts.snaplen = row.snaplen; - interface_opts.cfilter = g_strdup(row.cfilter); -#ifdef HAVE_PCAP_CREATE - interface_opts.monitor_mode = row.monitor_mode_enabled; -#else - interface_opts.monitor_mode = FALSE; -#endif -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = row.buffer; -#endif -#ifdef HAVE_PCAP_REMOTE - interface_opts.src_type = row.remote_opts.src_type; - if (interface_opts.src_type == CAPTURE_IFREMOTE) { - interface_opts.remote_host = g_strdup(row.remote_opts.remote_host_opts.remote_host); - interface_opts.remote_port = g_strdup(row.remote_opts.remote_host_opts.remote_port); - interface_opts.auth_type = row.remote_opts.remote_host_opts.auth_type; - interface_opts.auth_username = g_strdup(row.remote_opts.remote_host_opts.auth_username); - interface_opts.auth_password = g_strdup(row.remote_opts.remote_host_opts.auth_password); - interface_opts.datatx_udp = row.remote_opts.remote_host_opts.datatx_udp; - interface_opts.nocap_rpcap = row.remote_opts.remote_host_opts.nocap_rpcap; - interface_opts.nocap_local = row.remote_opts.remote_host_opts.nocap_local; -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = row.remote_opts.sampling_method; - interface_opts.sampling_param = row.remote_opts.sampling_param; -#endif - } else { - interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - interface_opts.auth_type = global_capture_opts.default_options.auth_type; - interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; - interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; -#endif - } -#endif - g_array_insert_val(global_capture_opts.ifaces, i, interface_opts); - } else { /* not enabled */ - if (interfaces_dialog_window_present()) { - update_selected_interface(g_strdup(interface_opts.name), FALSE); - } - if (get_welcome_window() != NULL) { - change_interface_selection(g_strdup(interface_opts.name), FALSE); - } - } - } - } - if (!found && enabled) { - interface_opts.name = g_strdup(row.name); - interface_opts.descr = get_interface_descriptive_name(interface_opts.name); - interface_opts.linktype = row.active_dlt; - interface_opts.promisc_mode = row.pmode; - interface_opts.has_snaplen = row.has_snaplen; - interface_opts.snaplen = row.snaplen; - interface_opts.cfilter = g_strdup(row.cfilter); -#ifdef HAVE_PCAP_CREATE - interface_opts.monitor_mode = row.monitor_mode_enabled; -#else - interface_opts.monitor_mode = FALSE; -#endif -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = row.buffer; -#endif -#ifdef HAVE_PCAP_REMOTE - interface_opts.src_type = row.remote_opts.src_type; - if (interface_opts.src_type == CAPTURE_IFREMOTE) { - interface_opts.remote_host = g_strdup(row.remote_opts.remote_host_opts.remote_host); - interface_opts.remote_port = g_strdup(row.remote_opts.remote_host_opts.remote_port); - interface_opts.auth_type = row.remote_opts.remote_host_opts.auth_type; - interface_opts.auth_username = g_strdup(row.remote_opts.remote_host_opts.auth_username); - interface_opts.auth_password = g_strdup(row.remote_opts.remote_host_opts.auth_password); - interface_opts.datatx_udp = row.remote_opts.remote_host_opts.datatx_udp; - interface_opts.nocap_rpcap = row.remote_opts.remote_host_opts.nocap_rpcap; - interface_opts.nocap_local = row.remote_opts.remote_host_opts.nocap_local; -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = row.remote_opts.sampling_method; - interface_opts.sampling_param = row.remote_opts.sampling_param; -#endif - } else { - interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - interface_opts.auth_type = global_capture_opts.default_options.auth_type; - interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; - interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; -#endif - } -#endif - g_array_append_val(global_capture_opts.ifaces, interface_opts); - if (interfaces_dialog_window_present()) { - update_selected_interface(g_strdup(interface_opts.name), TRUE); - } - if (get_welcome_window() != NULL) { - change_interface_selection(g_strdup(interface_opts.name), TRUE); - } - } - gtk_tree_path_free (path); -} - -void enable_selected_interface(gchar *name, gboolean enable) -{ - guint i; - interface_row row; - GtkTreeIter iter; - GtkTreeView *if_cb; - GtkTreeModel *model; - gchar *path_str; - gboolean enabled; - - for (i = 0; i < rows->len; i++) { - row = g_array_index(rows, interface_row, i); - if (strcmp(name, row.name) == 0) { - if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY); - model = gtk_tree_view_get_model(if_cb); - path_str = g_strdup_printf("%d", i); - gtk_tree_model_get_iter_from_string(model, &iter, path_str); - gtk_tree_model_get (model, &iter, CAPTURE, &enabled, -1); - if ((enabled == TRUE) && (enable == FALSE)) { - num_selected--; - } - if ((enabled == FALSE) && (enable == TRUE)) { - num_selected++; - } - gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enable, -1); + gtk_tree_model_get (model, &iter, CAPTURE, &enabled, IFACE_HIDDEN_NAME, &name, -1); + /* Look for the right interface. The number of interfaces shown might be less + * than the real number. Therefore the path index does not correspond + * necessarily to the position in the list */ + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (strcmp(device.name, name) == 0) { + index = i; break; } } - if (num_selected > 0) { + if (!device.locked) { + if (enabled == FALSE) { + device.selected = TRUE; + global_capture_opts.num_selected++; + } else { + device.selected = FALSE; + global_capture_opts.num_selected--; + } + device.locked = TRUE; + } + if (index != -1) { + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, index); + g_array_insert_val(global_capture_opts.all_ifaces, index, device); + pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY); + if (global_capture_opts.num_selected >= 2) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE); + gtk_widget_set_sensitive(pcap_ng_cb, FALSE); + } else { + gtk_widget_set_sensitive(pcap_ng_cb, TRUE); + } + if (global_capture_opts.num_selected > 0) { + gtk_widget_set_sensitive(ok_bt, TRUE); + } else { + gtk_widget_set_sensitive(ok_bt, FALSE); + } + /* do something with the new enabled value, and set the new + enabled value in your treemodel */ + gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, -1); + if (interfaces_dialog_window_present()) { + update_selected_interface(g_strdup(device.name)); + } + if (get_welcome_window() != NULL) { + change_interface_selection(g_strdup(device.name), device.selected); + } + } + device.locked = FALSE; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, index); + g_array_insert_val(global_capture_opts.all_ifaces, index, device); + gtk_tree_path_free (path); +} + +void enable_selected_interface(gchar *name, gboolean selected) +{ + GtkTreeIter iter; + GtkTreeView *if_cb; + GtkTreeModel *model; + gchar *name_str; + + if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY); + model = gtk_tree_view_get_model(if_cb); + gtk_tree_model_get_iter_first(model, &iter); + do { + gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &name_str, -1); + if (strcmp(name, name_str) == 0) { + gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, selected, -1); + break; + } + } + while (gtk_tree_model_iter_next(model, &iter)); + if (global_capture_opts.num_selected > 0) { gtk_widget_set_sensitive(ok_bt, TRUE); } else { gtk_widget_set_sensitive(ok_bt, FALSE); @@ -2563,17 +2347,17 @@ static void capture_all_cb(GtkToggleButton *button, gpointer d _U_) do { gtk_tree_model_get (model, &iter, CAPTURE, &capture_set, -1); if (!capture_set && enabled) { - num_selected++; + global_capture_opts.num_selected++; } else if (capture_set && !enabled) { - num_selected--; + global_capture_opts.num_selected--; } gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enabled, -1); } while (gtk_tree_model_iter_next(model, &iter)); } - if (num_selected >= 2) { + if (global_capture_opts.num_selected >= 2) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE); gtk_widget_set_sensitive(pcap_ng_cb, FALSE); - } else if (num_selected <= 1) { + } else if (global_capture_opts.num_selected <= 1) { gtk_widget_set_sensitive(pcap_ng_cb, TRUE); } if (interfaces_dialog_window_present()) { @@ -2582,7 +2366,7 @@ static void capture_all_cb(GtkToggleButton *button, gpointer d _U_) if (get_welcome_window() != NULL) { change_selection_for_all(enabled); } - if (num_selected > 0) { + if (global_capture_opts.num_selected > 0) { gtk_widget_set_sensitive(ok_bt, TRUE); } else { gtk_widget_set_sensitive(ok_bt, FALSE); @@ -2596,7 +2380,7 @@ static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_) GtkTreeView *if_cb; GtkTreeModel *model; gboolean enabled = FALSE; - interface_row row; + interface_t device; interface_options interface_opts; guint i; @@ -2611,11 +2395,11 @@ static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_) } while (gtk_tree_model_iter_next(model, &iter)); } - for (i = 0; i < rows->len; i++) { - row = g_array_index(rows, interface_row, i); - rows = g_array_remove_index(rows, i); - row.pmode = (enabled?TRUE:FALSE); - g_array_insert_val(rows, i, row); + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + device.pmode = (enabled?TRUE:FALSE); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); } for (i = 0; i < global_capture_opts.ifaces->len; i++) { @@ -2630,24 +2414,24 @@ static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_) void show_remote_dialog(GtkWidget *w) { - g_free(global_remote_opts.remote_host_opts.remote_host); - g_free(global_remote_opts.remote_host_opts.remote_port); - g_free(global_remote_opts.remote_host_opts.auth_username); - g_free(global_remote_opts.remote_host_opts.auth_password); - global_remote_opts.src_type = CAPTURE_IFREMOTE; - global_remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - global_remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - global_remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type; - global_remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - global_remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - global_remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - global_remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - global_remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local; + g_free(global_remote_opts.remote_host_opts.remote_host); + g_free(global_remote_opts.remote_host_opts.remote_port); + g_free(global_remote_opts.remote_host_opts.auth_username); + g_free(global_remote_opts.remote_host_opts.auth_password); + global_remote_opts.src_type = CAPTURE_IFREMOTE; + global_remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); + global_remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); + global_remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type; + global_remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); + global_remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); + global_remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; + global_remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; + global_remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local; #ifdef HAVE_PCAP_SETSAMPLING - global_remote_opts.sampling_method = global_capture_opts.default_options.sampling_method; - global_remote_opts.sampling_param = global_capture_opts.default_options.sampling_param; + global_remote_opts.sampling_method = global_capture_opts.default_options.sampling_method; + global_remote_opts.sampling_param = global_capture_opts.default_options.sampling_param; #endif - capture_remote_cb(GTK_WIDGET(w), FALSE); + capture_remote_cb(GTK_WIDGET(w), FALSE); } #endif @@ -2711,6 +2495,8 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) *help_bt; #ifdef HAVE_AIRPCAP GtkWidget *decryption_cb; + int err; + gchar *err_str; #endif #ifdef HAVE_PCAP_REMOTE GtkWidget *iftype_cbx; @@ -2719,10 +2505,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) GtkAdjustment *ringbuffer_nbf_adj, *stop_packets_adj, *stop_filesize_adj, *stop_duration_adj, *stop_files_adj, *ring_filesize_adj, *file_duration_adj; - GList *if_list; int row; - int err; - gchar *err_str; guint32 value; gchar *cap_title; GtkWidget *view; @@ -2742,7 +2525,6 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) return; } - num_selected = 0; /* use user-defined title if preference is set */ cap_title = create_user_window_title("Wireshark: Capture Options"); @@ -2751,14 +2533,6 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) cap_open_w = dlg_window_new(cap_title); g_free(cap_title); - if_list = capture_interface_list(&err, &err_str); - - if (if_list == NULL && - (err == CANT_GET_INTERFACE_LIST || err == DONT_HAVE_PCAP)) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - } - if_list = g_list_sort (if_list, if_list_comparator_alph); #ifdef HAVE_AIRPCAP /* update airpcap interface list */ @@ -2809,6 +2583,13 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) g_object_set (GTK_TREE_VIEW(view), "has-tooltip", TRUE, NULL); g_signal_connect (GTK_TREE_VIEW(view), "query-tooltip", G_CALLBACK (query_tooltip_tree_view_cb), NULL); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + GTK_CELL_RENDERER(renderer), + "text", IFACE_HIDDEN_NAME, + NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); + gtk_tree_view_column_set_visible(column, FALSE); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view), -1, "Interface", renderer, "markup", INTERFACE, NULL); column = gtk_tree_view_get_column(GTK_TREE_VIEW (view), INTERFACE); @@ -2859,7 +2640,6 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) gtk_container_add (GTK_CONTAINER (swindow), view); gtk_box_pack_start(GTK_BOX(capture_vb), swindow, TRUE, TRUE, 0); - free_interface_list(if_list); g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY, view); main_hb = gtk_hbox_new(FALSE, 5); @@ -3228,7 +3008,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_START); g_signal_connect(ok_bt, "clicked", G_CALLBACK(capture_start_cb), NULL); gtk_widget_set_tooltip_text(ok_bt, "Start the capture process."); - if (num_selected > 0) { + if (global_capture_opts.num_selected > 0) { gtk_widget_set_sensitive(ok_bt, TRUE); } else { gtk_widget_set_sensitive(ok_bt, FALSE); @@ -3309,7 +3089,7 @@ capture_start_confirmed(void) guint i; /* did the user ever select a capture interface before? */ - if(global_capture_opts.ifaces->len == 0 && prefs.capture_device == NULL) { + if(global_capture_opts.num_selected == 0 && prefs.capture_device == NULL) { simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTN_OK, "%sNo capture interface selected!%s\n\n" @@ -3361,10 +3141,6 @@ void capture_start_cb(GtkWidget *w _U_, gpointer d _U_) { gpointer dialog; - gchar *if_name; - cap_settings_t *cap_settings_p = NULL; - interface_options interface_opts; - guint i; #ifdef HAVE_AIRPCAP airpcap_if_active = airpcap_if_selected; @@ -3389,60 +3165,10 @@ capture_start_cb(GtkWidget *w _U_, gpointer d _U_) if (!success) return; /* error in options dialog */ } - - if (global_capture_opts.ifaces->len == 0) { - if (prefs.capture_device == NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + if (global_capture_opts.num_selected == 0) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "You didn't specify an interface on which to capture packets."); - return; - } - interface_opts.name = g_strdup(get_if_name(prefs.capture_device)); - interface_opts.descr = get_interface_descriptive_name(interface_opts.name); -#ifdef HAVE_PCAP_CREATE - interface_opts.monitor_mode = prefs_capture_device_monitor_mode(interface_opts.name); -#else - interface_opts.monitor_mode = FALSE; -#endif - interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name); - interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter); - interface_opts.snaplen = global_capture_opts.default_options.snaplen; - interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen; - interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode; -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = global_capture_opts.default_options.buffer_size; -#endif -#ifdef HAVE_PCAP_REMOTE - interface_opts.src_type = global_capture_opts.default_options.src_type; - interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - interface_opts.auth_type = global_capture_opts.default_options.auth_type; - interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; - #endif - #ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; - interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; - #endif - g_array_insert_val(global_capture_opts.ifaces, 0, interface_opts); - } - - if (cap_settings_history != NULL) { - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - if_name = g_strdup(interface_opts.name); - cap_settings_p = (cap_settings_t *)g_hash_table_lookup(cap_settings_history, if_name); - if (cap_settings_p == NULL) { - cap_settings_p = g_new(cap_settings_t,1); - g_hash_table_insert(cap_settings_history, if_name, cap_settings_p); - } else { - g_free(if_name); - } - cap_settings_p->monitor_mode = interface_opts.monitor_mode; - cap_settings_p->linktype = interface_opts.linktype; - } + return; } if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) { @@ -3465,18 +3191,18 @@ select_link_type_cb(GtkWidget *linktype_combo_box, gpointer data _U_) { gpointer ptr; int dlt; - interface_row row; + interface_t device; - row = g_array_index(rows, interface_row, marked_row); - rows = g_array_remove_index(rows, marked_row); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface); + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface); if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) { g_assert_not_reached(); /* Programming error: somehow nothing is active */ } if ((dlt = GPOINTER_TO_INT(ptr)) == -1) { g_assert_not_reached(); /* Programming error: somehow managed to select an "unsupported" entry */ } - row.active_dlt = dlt; - g_array_insert_val(rows, marked_row, row); + device.active_dlt = dlt; + g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device); capture_filter_check_syntax_cb(linktype_combo_box, data); } @@ -3534,7 +3260,7 @@ capture_dlg_prep(gpointer parent_w) { n_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY); t_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY); - if (global_capture_opts.ifaces->len == 0) { + if (global_capture_opts.num_selected == 0) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "You didn't specify an interface on which to capture packets."); return FALSE; @@ -3678,263 +3404,51 @@ capture_dlg_prep(gpointer parent_w) { return TRUE; } -static void -make_and_fill_rows(void) -{ - GList *if_entry, *if_list; - if_info_t *if_info; - char *if_string=NULL; - gchar *descr; - if_capabilities_t *caps=NULL; - gint linktype_count; - cap_settings_t cap_settings; - GSList *curr_addr; - int ips = 0, err; - guint i; - if_addr_t *addr; - GList *lt_entry; - link_row *link = NULL; - data_link_info_t *data_link_info; - gchar *str, *err_str = NULL, *err_str_norfmon; - interface_row row; - interface_options interface_opts; - gboolean found = FALSE; - GString *ip_str; - - rows = g_array_new(TRUE, TRUE, sizeof(interface_row)); - /* Scan through the list and build a list of strings to display. */ - if_list = capture_interface_list(&err, &err_str); - if_list = g_list_sort (if_list, if_list_comparator_alph); - if (if_list == NULL && - (err == CANT_GET_INTERFACE_LIST || err == DONT_HAVE_PCAP)) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - return; - } else if (err_str) { - g_free(err_str); - } - for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) { - if_info = (if_info_t *)if_entry->data; - ip_str = g_string_new(""); - str = NULL; - ips = 0; - row.name = g_strdup(if_info->name); - /* Is this interface hidden and, if so, should we include it anyway? */ - if (!prefs_is_capture_device_hidden(if_info->name)) { - /* It's not hidden, or it is but we should include it in the list. */ - /* Do we have a user-supplied description? */ - descr = capture_dev_user_descr_find(if_info->name); - if (descr != NULL) { - /* Yes, we have a user-supplied description; use it. */ - if_string = g_strdup_printf("%s: %s", descr, if_info->name); - g_free(descr); - } else { - /* No, we don't have a user-supplied description; did we get - one from the OS or libpcap? */ - if (if_info->description != NULL) { - /* Yes - use it. */ - if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name); - } else { - /* No. */ - if_string = g_strdup(if_info->name); - } - } - if (if_info->loopback) { - row.display_name = g_strdup_printf("%s (loopback)", if_string); - } else { - row.display_name = g_strdup(if_string); - } - found = FALSE; - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - if (!interface_opts.name || strcmp(interface_opts.name, (char*)row.name)!=0) { - continue; - } else { - found = TRUE; - break; - } - } - if (found) { -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - row.buffer = interface_opts.buffer_size; -#endif - row.pmode = interface_opts.promisc_mode; - row.has_snaplen = interface_opts.has_snaplen; - row.snaplen = interface_opts.snaplen; - row.cfilter = g_strdup(interface_opts.cfilter); - } else { -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - row.buffer = global_capture_opts.default_options.buffer_size; -#endif - row.pmode = global_capture_opts.default_options.promisc_mode; - row.has_snaplen = global_capture_opts.default_options.has_snaplen; - row.snaplen = global_capture_opts.default_options.snaplen; - row.cfilter = g_strdup(global_capture_opts.default_options.cfilter); - } - cap_settings = capture_get_cap_settings(if_info->name); - caps = capture_get_if_capabilities(if_info->name, - cap_settings.monitor_mode, - &err_str); - if (caps == NULL) { - /* Error attempting to get interface capabilities. */ - if (cap_settings.monitor_mode) { - /* - * Perhaps this is the libpcap bug on Linux where - * attempting to set monitor mode with the Wireless - * Extensions ioctls doesn't work correctly. - * - * Try fetching the capabilities without monitor mode; - * if that succeeds, report the monitor-mode problem, - * and use the no-monitor-mode capabilities. If that - * fails, report that failure. In either case, force - * monitor mode off. - */ - cap_settings.monitor_mode = FALSE; - caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, - &err_str_norfmon); - if (caps == NULL) { - /* Epic fail. */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str_norfmon); - g_free(err_str_norfmon); - g_free(err_str); - } else { - /* - * OK, it's probably that bug. Suggest using airmon-ng, - * just in case the adapter has a mac80211 driver and - * libpcap was built without libnl so that it can't - * use the mac80211 features to create a monitor-mode - * device. - */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s\n\n" - "Try using airmon-ng, as suggested by CaptureSetup/WLAN in the Wireshark Wiki.", - err_str); - g_free(err_str); - } - } else { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - } - } - for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) { - if (ips != 0) { - g_string_append(ip_str, "\n"); - } - addr = (if_addr_t *)curr_addr->data; - switch (addr->ifat_type) { - case IF_AT_IPv4: - g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr)); - break; - case IF_AT_IPv6: - g_string_append(ip_str, ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr)); - break; - default: - /* In case we add non-IP addresses */ - break; - } - } - linktype_count = 0; - row.links = NULL; - if (caps != NULL) { -#ifdef HAVE_PCAP_CREATE - row.monitor_mode_enabled = cap_settings.monitor_mode; - row.monitor_mode_supported = caps->can_set_rfmon; -#endif - 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) { - str = g_strdup_printf("%s", data_link_info->description); - } else { - str = g_strdup_printf("%s (not supported)", data_link_info->name); - } - if (linktype_count == 0) { - row.active_dlt = data_link_info->dlt; - } - link = (link_row *)g_malloc(sizeof(link_row)); - link->dlt = data_link_info->dlt; - link->name = g_strdup(str); - row.links = g_list_append(row.links, link); - linktype_count++; - } - } else { - cap_settings.monitor_mode = FALSE; -#ifdef HAVE_PCAP_CREATE - row.monitor_mode_enabled = FALSE; - row.monitor_mode_supported = FALSE; -#endif - row.active_dlt = -1; - } - row.addresses = g_strdup(ip_str->str); - row.no_addresses = ips; - g_array_append_val(rows, row); - if (caps != NULL) { - free_if_capabilities(caps); - } - } - g_string_free(ip_str, TRUE); - } -} - GtkTreeModel *create_and_fill_model(GtkTreeView *view) { GtkListStore *store; GtkTreeIter iter; GList *list; - char *temp=NULL, *snaplen_string; - guint i, j; + char *temp="", *snaplen_string, *linkname=""; + guint i; link_row *link = NULL; - interface_row row; - interface_options interface_opts; - gboolean found = FALSE; + interface_t device; #if defined(HAVE_PCAP_CREATE) - store = gtk_list_store_new (8, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); + store = gtk_list_store_new (9, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); #elif defined(_WIN32) && !defined (HAVE_PCAP_CREATE) - store = gtk_list_store_new (7, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING); + store = gtk_list_store_new (8, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING); #else - store = gtk_list_store_new (6, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + store = gtk_list_store_new (7, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); #endif - if (!rows || rows->len == 0) { - make_and_fill_rows(); - } - if (rows && rows->len > 0) { - for (i = 0; i < rows->len; i++) { - row = g_array_index(rows, interface_row, i); - found = FALSE; - for (j = 0; j < global_capture_opts.ifaces->len; j++) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j); - if (!interface_opts.name || strcmp(interface_opts.name, (char*)row.name)!=0) { - continue; - } else { - found = TRUE; - num_selected++; - break; - } - } - if (row.no_addresses == 0) { - temp = g_strdup_printf("%s", row.display_name); + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (!device.hidden) { + if (device.no_addresses == 0) { + temp = g_strdup_printf("%s", device.display_name); } else { - temp = g_strdup_printf("%s\n%s", row.display_name, row.addresses); + temp = g_strdup_printf("%s\n%s", device.display_name, device.addresses); } - for (list = row.links; list != NULL; list = g_list_next(list)) { + for (list = device.links; list != NULL; list = g_list_next(list)) { link = (link_row*)(list->data); - if (link->dlt == row.active_dlt) { - break; + linkname = g_strdup(link->name); + if (link->dlt == device.active_dlt) { + break; } } - if (row.has_snaplen) { - snaplen_string = g_strdup_printf("%d", row.snaplen); + if (device.has_snaplen) { + snaplen_string = g_strdup_printf("%d", device.snaplen); } else { snaplen_string = g_strdup("default"); } gtk_list_store_append (store, &iter); #if defined(HAVE_PCAP_CREATE) - gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name, PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, MONITOR, row.monitor_mode_supported?(row.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, row.cfilter, -1); + gtk_list_store_set (store, &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname, PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, MONITOR, device.monitor_mode_supported?(device.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, device.cfilter, -1); #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE) - gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name, PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, FILTER, row.cfilter, -1); + gtk_list_store_set (store, &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname, PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, FILTER, device.cfilter, -1); #else - gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name, PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, row.cfilter, -1); + gtk_list_store_set (store, &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname, PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, device.cfilter, -1); #endif } } @@ -4021,13 +3535,13 @@ gboolean query_tooltip_tree_view_cb (GtkWidget *widget, void activate_monitor (GtkTreeViewColumn *tree_column _U_, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data _U_) { - interface_row row; + interface_t device; GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter); int index = atoi(gtk_tree_path_to_string(path)); - row = g_array_index(rows, interface_row, index); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, index); - if (row.monitor_mode_supported==TRUE) { + if (device.monitor_mode_supported==TRUE) { g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL); } else { g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); @@ -4083,83 +3597,37 @@ static void capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_) { GList *lt_entry; - gchar *if_string=NULL; + gchar *if_string=""; cap_settings_t cap_settings; - gchar *err_str, *err_str_norfmon; if_capabilities_t *caps=NULL; gint linktype_count = 0, i; data_link_info_t *data_link_info; - interface_row row; + interface_t device; link_row *link; GtkWidget *linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY); GtkWidget *linktype_lb = (GtkWidget *)g_object_get_data(G_OBJECT(linktype_combo_box), E_CAP_LT_CBX_LABEL_KEY); - row = g_array_index(rows, interface_row, marked_row); - rows = g_array_remove_index(rows, marked_row); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface); + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface); - if_string = g_strdup(row.name); + if_string = g_strdup(device.name); cap_settings = capture_get_cap_settings(if_string); cap_settings.monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor)); - caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, - &err_str); - if (caps == NULL) { - /* Error attempting to get interface capabilities. */ - if (cap_settings.monitor_mode) { - /* - * Perhaps this is the libpcap bug on Linux where - * attempting to set monitor mode with the Wireless - * Extensions ioctls doesn't work correctly. - * - * Try fetching the capabilities without monitor mode; - * if that succeeds, report the monitor-mode problem, - * and use the no-monitor-mode capabilities. If that - * fails, report that failure. In either case, force - * monitor mode off. - */ - cap_settings.monitor_mode = FALSE; - /* Set the monitor-mode checkbox to the new forced value */ - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor), - cap_settings.monitor_mode); - caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, - &err_str_norfmon); - if (caps == NULL) { - /* Epic fail. */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str_norfmon); - g_free(err_str_norfmon); - g_free(err_str); - } else { - /* - * OK, it's probably that bug. Suggest using airmon-ng, - * just in case the adapter has a mac80211 driver and - * libpcap was built without libnl so that it can't - * use the mac80211 features to create a monitor-mode - * device. - */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "%s\n\n" - "Try using airmon-ng, as suggested by CaptureSetup/WLAN in the Wireshark Wiki.", - err_str); - g_free(err_str); - } - } else { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - } - } + caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, NULL); if (caps != NULL) { g_signal_handlers_disconnect_by_func(linktype_combo_box, G_CALLBACK(select_link_type_cb), NULL ); ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box)); - for (i = (gint)g_list_length(row.links)-1; i >= 0; i--) { - GList* rem = g_list_nth(row.links, i); - row.links = g_list_remove_link(row.links, rem); + for (i = (gint)g_list_length(device.links)-1; i >= 0; i--) { + GList* rem = g_list_nth(device.links, i); + device.links = g_list_remove_link(device.links, rem); g_list_free_1(rem); } - row.active_dlt = -1; + device.active_dlt = -1; linktype_count = 0; - row.monitor_mode_supported = caps->can_set_rfmon; - row.monitor_mode_enabled = cap_settings.monitor_mode; + device.monitor_mode_supported = caps->can_set_rfmon; + device.monitor_mode_enabled = cap_settings.monitor_mode; for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) { link = (link_row *)g_malloc(sizeof(link_row)); data_link_info = (data_link_info_t *)lt_entry->data; @@ -4169,7 +3637,7 @@ capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_) GINT_TO_POINTER(data_link_info->dlt)); link->dlt = data_link_info->dlt; if (linktype_count == 0) { - row.active_dlt = data_link_info->dlt; + device.active_dlt = data_link_info->dlt; } link->name = g_strdup(data_link_info->description); } else { @@ -4185,7 +3653,7 @@ capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_) link->name = g_strdup(str); g_free(str); } - row.links = g_list_append(row.links, link); + device.links = g_list_append(device.links, link); linktype_count++; } free_if_capabilities(caps); @@ -4193,13 +3661,13 @@ capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_) /* We don't know whether this supports monitor mode or not; don't ask for monitor mode. */ cap_settings.monitor_mode = FALSE; - row.monitor_mode_enabled = FALSE; - row.monitor_mode_supported = FALSE; + device.monitor_mode_enabled = FALSE; + device.monitor_mode_supported = FALSE; } gtk_widget_set_sensitive(linktype_lb, linktype_count >= 2); gtk_widget_set_sensitive(linktype_combo_box, linktype_count >= 2); ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box),0); - g_array_insert_val(rows, marked_row, row); + g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device); } #endif diff --git a/ui/gtk/capture_dlg.h b/ui/gtk/capture_dlg.h index 70478a3cfd..602be8a8e3 100644 --- a/ui/gtk/capture_dlg.h +++ b/ui/gtk/capture_dlg.h @@ -32,60 +32,12 @@ * @ingroup dialog_group */ #include "capture_opts.h" - -#ifdef HAVE_PCAP_REMOTE -struct remote_host { - gchar *remote_host; /**< Host name or network address for remote capturing */ - gchar *remote_port; /**< TCP port of remote RPCAP server */ - gint auth_type; /**< Authentication type */ - gchar *auth_username; /**< Remote authentication parameters */ - gchar *auth_password; /**< Remote authentication parameters */ - gboolean datatx_udp; - gboolean nocap_rpcap; - gboolean nocap_local; -}; - -typedef struct remote_options_tag { - capture_source src_type; - struct remote_host remote_host_opts; -#ifdef HAVE_PCAP_SETSAMPLING - capture_sampling sampling_method; - int sampling_param; -#endif -} remote_options; -#endif /* HAVE_PCAP_REMOTE */ - -typedef struct row_options_tag { - gchar *name; - gchar *display_name; - gchar *addresses; - gint no_addresses; - gchar *cfilter; - GList *links; - gint active_dlt; - gboolean pmode; -#ifdef HAVE_PCAP_CREATE - gboolean monitor_mode_enabled; - gboolean monitor_mode_supported; -#endif - gboolean has_snaplen; - guint snaplen; -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - gint buffer; -#endif -#ifdef HAVE_PCAP_REMOTE - remote_options remote_opts; -#endif -} interface_row; - -typedef struct link_row_tag { - gchar *name; - gint dlt; -} link_row; +#include enum { CAPTURE = 0, + IFACE_HIDDEN_NAME, INTERFACE, LINK, PMODE, @@ -143,6 +95,7 @@ void capture_start_confirmed(void); void capture_air_cb(GtkWidget *widget, gpointer data); +#if 0 /* * We remember the capture settings for each interface when a capture * is started on it; the next time we select that interface we start @@ -163,6 +116,7 @@ typedef struct { */ cap_settings_t capture_get_cap_settings (gchar *if_name); +#endif GtkTreeModel* create_and_fill_model (GtkTreeView *view); @@ -183,9 +137,12 @@ gboolean dlg_window_present(void); void -enable_selected_interface(gchar *name, gboolean enable); +enable_selected_interface(gchar *name, gboolean selected); void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column _U_, gpointer userdata); +void +update_all_rows(void); + #endif /* capture_dlg.h */ diff --git a/ui/gtk/capture_if_dlg.c b/ui/gtk/capture_if_dlg.c index e67b57b79e..f6bf71c454 100644 --- a/ui/gtk/capture_if_dlg.c +++ b/ui/gtk/capture_if_dlg.c @@ -51,6 +51,7 @@ #ifdef _WIN32 #include "ui/gtk/capture_if_details_dlg_win32.h" +#include "../../capture-wpcap.h" #endif #include "ui/gtk/stock_icons.h" @@ -65,6 +66,7 @@ #include "ui/gtk/webbrowser.h" #include "ui/gtk/capture_globals.h" #include "ui/gtk/network_icons.h" +#include "ui/gtk/pipe_icon.h" #include "ui/gtk/main_welcome.h" #include "ui/gtk/menus.h" @@ -109,15 +111,13 @@ */ static GtkWidget *cap_if_w; -static GList *if_data_list = NULL; - static guint timer_id; static GtkWidget *stop_bt, *capture_bt, *options_bt; static GList *if_list; -static guint currently_selected = 0; +static GArray *gtk_list; static if_stat_cache_t *sc; @@ -129,6 +129,7 @@ static if_stat_cache_t *sc; /* the "runtime" data of one interface */ typedef struct if_dlg_data_s { + gchar *device; GtkWidget *device_lb; GtkWidget *descr_lb; GtkWidget *ip_lb; @@ -138,125 +139,62 @@ typedef struct if_dlg_data_s { #ifdef _WIN32 GtkWidget *details_bt; #endif - guint32 last_packets; - gchar *device; - if_info_t if_info; - gboolean selected; } if_dlg_data_t; static gboolean gbl_capture_in_progress = FALSE; void -update_selected_interface(gchar *name, gboolean activate) +update_selected_interface(gchar *name) { - guint ifs; - GList *curr; - if_dlg_data_t *temp; + guint i; + interface_t device; + if_dlg_data_t data; - for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) { - curr = g_list_nth(if_data_list, ifs); - temp = (if_dlg_data_t *)(curr->data); - if (strcmp(name, temp->if_info.name) == 0) { - if (activate) { - gtk_toggle_button_set_active((GtkToggleButton *)temp->choose_bt, TRUE); - } else { - gtk_toggle_button_set_active((GtkToggleButton *)temp->choose_bt, FALSE); - } + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + data = g_array_index(gtk_list, if_dlg_data_t, i); + if (strcmp(name, device.name) == 0) { + gtk_toggle_button_set_active((GtkToggleButton *)data.choose_bt, device.selected); break; } } } static void -store_selected(GtkWidget *choose_bt, gpointer if_data) +store_selected(GtkWidget *choose_bt, gpointer name) { - if_dlg_data_t *if_dlg_data = (if_dlg_data_t *)if_data, *temp; - GList *curr; - unsigned int ifs, i; + interface_t device; + guint i; gboolean found; - cap_settings_t cap_settings; - interface_options interface_opts; - - for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) { - curr = g_list_nth(if_data_list, ifs); - temp = (if_dlg_data_t *)(curr->data); + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); found = FALSE; - if (strcmp(if_dlg_data->if_info.name, temp->if_info.name) == 0) { - temp->selected ^=1; - if_data_list = g_list_remove(if_data_list, curr->data); - if_data_list = g_list_insert(if_data_list, temp, ifs); - - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, temp->if_info.name) == 0) { - found = TRUE; - if (!temp->selected) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i); - if (gtk_widget_is_focus(choose_bt) && get_welcome_window()) { - change_interface_selection(interface_opts.name, FALSE); - } - if (gtk_widget_is_focus(choose_bt) && dlg_window_present()) { - enable_selected_interface(interface_opts.name, FALSE); - } - g_free(interface_opts.name); - g_free(interface_opts.descr); - g_free(interface_opts.cfilter); -#ifdef HAVE_PCAP_REMOTE - g_free(interface_opts.remote_host); - g_free(interface_opts.remote_port); - g_free(interface_opts.auth_username); - g_free(interface_opts.auth_password); -#endif - break; - } + if (strcmp(name, device.if_info.name) == 0) { + found = TRUE; + if (!device.locked) { + device.selected ^= 1; + if (device.selected) { + global_capture_opts.num_selected++; + } else { + global_capture_opts.num_selected--; } - } - if (!found && temp->selected) { - interface_opts.name = g_strdup(temp->if_info.name); - interface_opts.descr = get_interface_descriptive_name(interface_opts.name); - interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name); - interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter); - interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen; - interface_opts.snaplen = global_capture_opts.default_options.snaplen; - cap_settings = capture_get_cap_settings (interface_opts.name);; - interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode; -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = global_capture_opts.default_options.buffer_size; -#endif - interface_opts.monitor_mode = cap_settings.monitor_mode; -#ifdef HAVE_PCAP_REMOTE - interface_opts.src_type = global_capture_opts.default_options.src_type; - interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - interface_opts.auth_type = global_capture_opts.default_options.auth_type; - interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; -#endif -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; - interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; -#endif - g_array_append_val(global_capture_opts.ifaces, interface_opts); - if (gtk_widget_is_focus(choose_bt) && get_welcome_window() != NULL) { - change_interface_selection(g_strdup(temp->if_info.name), TRUE); + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); + if (gtk_widget_is_focus(choose_bt) && get_welcome_window()) { + change_interface_selection(device.name, device.selected); } if (gtk_widget_is_focus(choose_bt) && dlg_window_present()) { - enable_selected_interface(interface_opts.name, TRUE); + enable_selected_interface(device.name, device.selected); } + device.locked = FALSE; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); } - - if (temp->selected) - currently_selected += 1; - else - currently_selected -= 1; break; } } if (cap_if_w) { - gtk_widget_set_sensitive(capture_bt, !gbl_capture_in_progress && (currently_selected > 0)); + gtk_widget_set_sensitive(capture_bt, !gbl_capture_in_progress && (global_capture_opts.num_selected > 0)); } } @@ -268,19 +206,18 @@ capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data) capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data _U_) #endif { - if_dlg_data_t *temp; - GList *curr; - int ifs; + if_dlg_data_t data; + guint ifs; + + for (ifs = 0; ifs < gtk_list->len; ifs++) { + data = g_array_index(gtk_list, if_dlg_data_t, ifs); + gtk_widget_set_sensitive(data.choose_bt, FALSE); + gtk_list = g_array_remove_index(gtk_list, ifs); + g_array_insert_val(gtk_list, ifs, data); #ifdef HAVE_AIRPCAP - if_dlg_data_t *if_dlg_data = if_data; - - airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, if_dlg_data->if_info.name); - airpcap_if_selected = airpcap_if_active; + airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, gtk_label_get_text(GTK_LABEL(data.device_lb))); + airpcap_if_selected = airpcap_if_active; #endif - - for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) { - temp = (if_dlg_data_t *)(curr->data); - gtk_widget_set_sensitive(temp->choose_bt, FALSE); } /* XXX - remove this? */ @@ -326,11 +263,14 @@ capture_details_cb(GtkWidget *details_bt _U_, gpointer if_data) /* update a single interface */ static void -update_if(if_dlg_data_t *if_dlg_data, if_stat_cache_t *sc) +update_if(gchar *name, if_stat_cache_t *sc) { struct pcap_stat stats; gchar *str; - guint diff; + guint diff, ifs; + interface_t device; + if_dlg_data_t data; + gboolean found = FALSE; /* @@ -341,23 +281,40 @@ update_if(if_dlg_data_t *if_dlg_data, if_stat_cache_t *sc) * That's a bug, and should be fixed; "pcap_stats()" is supposed * to work the same way on all platforms. */ + device.last_packets = 0; + data.curr_lb = NULL; + data.last_lb = NULL; if (sc) { - if (capture_stats(sc, if_dlg_data->device, &stats)) { - diff = stats.ps_recv - if_dlg_data->last_packets; - if_dlg_data->last_packets = stats.ps_recv; + for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs); + data = g_array_index(gtk_list, if_dlg_data_t, ifs); + if (!device.hidden && strcmp(name, device.name) == 0) { + found = TRUE; + break; + } + } + if (found) { + if (capture_stats(sc, name, &stats)) { + diff = stats.ps_recv - device.last_packets; + device.last_packets = stats.ps_recv; - str = g_strdup_printf("%u", if_dlg_data->last_packets); - gtk_label_set_text(GTK_LABEL(if_dlg_data->curr_lb), str); - g_free(str); - str = g_strdup_printf("%u", diff); - gtk_label_set_text(GTK_LABEL(if_dlg_data->last_lb), str); - g_free(str); + str = g_strdup_printf("%u", device.last_packets); + gtk_label_set_text(GTK_LABEL(data.curr_lb), str); + g_free(str); + str = g_strdup_printf("%u", diff); + gtk_label_set_text(GTK_LABEL(data.last_lb), str); + g_free(str); - gtk_widget_set_sensitive(if_dlg_data->curr_lb, diff); - gtk_widget_set_sensitive(if_dlg_data->last_lb, diff); - } else { - gtk_label_set_text(GTK_LABEL(if_dlg_data->curr_lb), "error"); - gtk_label_set_text(GTK_LABEL(if_dlg_data->last_lb), "error"); + gtk_widget_set_sensitive(data.curr_lb, diff); + gtk_widget_set_sensitive(data.last_lb, diff); + } else { + gtk_label_set_text(GTK_LABEL(data.curr_lb), "error"); + gtk_label_set_text(GTK_LABEL(data.last_lb), "error"); + } + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, ifs); + g_array_insert_val(global_capture_opts.all_ifaces, ifs, device); + gtk_list = g_array_remove_index(gtk_list, ifs); + g_array_insert_val(gtk_list, ifs, data); } } } @@ -366,19 +323,20 @@ update_if(if_dlg_data_t *if_dlg_data, if_stat_cache_t *sc) static gboolean update_all(gpointer data) { - GList *curr; - int ifs; - if_stat_cache_t *sc = (if_stat_cache_t *)data; + interface_t device; + guint ifs; + if_stat_cache_t *sc = data; - if (!cap_if_w) { - return FALSE; - } + if (!cap_if_w) { + return FALSE; + } - for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) { - update_if((if_dlg_data_t *)curr->data, sc); - } + for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs); + update_if(device.name, sc); + } - return TRUE; + return TRUE; } /* a live capture has started or stopped */ @@ -388,7 +346,7 @@ set_capture_if_dialog_for_capture_in_progress(gboolean capture_in_progress) gbl_capture_in_progress = capture_in_progress; if (cap_if_w) { gtk_widget_set_sensitive(stop_bt, capture_in_progress); - gtk_widget_set_sensitive(capture_bt, !capture_in_progress && (currently_selected > 0)); + gtk_widget_set_sensitive(capture_bt, !capture_in_progress && (global_capture_opts.num_selected > 0)); } } @@ -397,26 +355,17 @@ set_capture_if_dialog_for_capture_in_progress(gboolean capture_in_progress) static void capture_if_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_) { - GList *curr; - int ifs; + g_source_remove(timer_id); - g_source_remove(timer_id); + free_interface_list(if_list); - for (ifs = 0; (curr = g_list_nth(if_data_list, ifs)); ifs++) { - g_free(curr->data); - } + /* Note that we no longer have a "Capture Options" dialog box. */ + cap_if_w = NULL; - if_data_list = NULL; - - free_interface_list(if_list); - - /* Note that we no longer have a "Capture Options" dialog box. */ - cap_if_w = NULL; - - capture_stat_stop(sc); + capture_stat_stop(sc); #ifdef HAVE_AIRPCAP - airpcap_set_toolbar_stop_capture(airpcap_if_active); + airpcap_set_toolbar_stop_capture(airpcap_if_active); #endif } @@ -440,127 +389,38 @@ gint if_list_comparator_alph (const void *first_arg, const void *second_arg){ * Used to retrieve the interface icon. * This is hideously platform-dependent. */ -GtkWidget * capture_get_if_icon(const if_info_t* if_info) +GtkWidget * capture_get_if_icon(interface_t *device) { -#if defined(__linux__) - ws_statb64 statb; - char *wireless_path; -#endif - #ifdef HAVE_PCAP_REMOTE - if (if_info->description && strstr(if_info->description, "on remote node") != NULL ) { + if (!device->local) { return pixbuf_to_widget(remote_sat_pb_data); } #endif -#if defined(_WIN32) - /* - * Much digging failed to reveal any obvious way to get something such - * as the SNMP MIB-II ifType value for an interface: - * - * http://www.iana.org/assignments/ianaiftype-mib - * - * by making some NDIS request. - */ - if ( if_info->description && ( strstr(if_info->description,"generic dialup") != NULL || - strstr(if_info->description,"PPP/SLIP") != NULL ) ) { + switch (device->type) { +#ifdef _WIN32 + case IF_DIALUP: return xpm_to_widget(modem_16_xpm); - } - - if ( if_info->description && ( strstr(if_info->description,"Wireless") != NULL || - strstr(if_info->description,"802.11") != NULL || strstr(if_info->description,"AirPcap") != NULL ) ) { - return pixbuf_to_widget(network_wireless_pb_data); - } - - if ( strstr(if_info->name,"airpcap") != NULL ) { - return pixbuf_to_widget(network_wireless_pb_data); - } - - if ( if_info->description && strstr(if_info->description, "Bluetooth") != NULL ) { - return pixbuf_to_widget(network_bluetooth_pb_data); - } -#elif defined(__APPLE__) - /* - * XXX - yes, fetching all the network addresses for an interface - * gets you an AF_LINK address, of type "struct sockaddr_dl", and, - * yes, that includes an SNMP MIB-II ifType value. - * - * However, it's IFT_ETHER, i.e. Ethernet, for AirPort interfaces, - * not IFT_IEEE80211 (which isn't defined in OS X in any case). - * - * Perhaps some other BSD-flavored OSes won't make this mistake; - * however, FreeBSD 7.0 and OpenBSD 4.2, at least, appear to have - * made the same mistake, at least for my Belkin ZyDAS stick. - * - * On Mac OS X, one might be able to get the information one wants from - * IOKit. - */ - if ( strcmp(if_info->name, "en1") == 0) { - return pixbuf_to_widget(network_wireless_pb_data); - } - - /* - * XXX - PPP devices have names beginning with "ppp" and an IFT_ of - * IFT_PPP, but they could be dial-up, or PPPoE, or mobile phone modem, - * or VPN, or... devices. One might have to dive into the bowels of - * IOKit to find out. - */ - - /* - * XXX - there's currently no support for raw Bluetooth capture, - * and IP-over-Bluetooth devices just look like fake Ethernet - * devices. There's also Bluetooth modem support, but that'll - * probably just give you a device that looks like a PPP device. - */ -#elif defined(__linux__) - /* - * Look for /sys/class/net/{device}/wireless. - */ - wireless_path = g_strdup_printf("/sys/class/net/%s/wireless", if_info->name); - if (wireless_path != NULL) { - if (ws_stat64(wireless_path, &statb) == 0) { - g_free(wireless_path); - return pixbuf_to_widget(network_wireless_pb_data); - } - g_free(wireless_path); - } - - /* - * Bluetooth devices. - * - * XXX - this is for raw Bluetooth capture; what about IP-over-Bluetooth - * devices? - */ - if ( strstr(if_info->name,"bluetooth") != NULL) { - return pixbuf_to_widget(network_bluetooth_pb_data); - } - - /* - * USB devices. - */ - if ( strstr(if_info->name,"usbmon") != NULL ) { - return pixbuf_to_widget(network_usb_pb_data); - } #endif - - /* - * TODO: find a better icon! - * Bridge, NAT, or host-only interfaces on VMWare hosts have the name - * vmnet[0-9]+ or VMnet[0-9+ on Windows. Guests might use a native - * (LANCE or E1000) driver or the vmxnet driver. These devices have an - * IFT_ of IFT_ETHER, so we have to check the name. - */ - if ( g_ascii_strncasecmp(if_info->name, "vmnet", 5) == 0) { + case IF_WIRELESS: + return pixbuf_to_widget(network_wireless_pb_data); +#ifdef HAVE_AIRPCAP + case IF_AIRPCAP: + return xpm_to_widget(capture_airpcap_16_xpm); +#endif + case IF_BLUETOOTH: + return pixbuf_to_widget(network_bluetooth_pb_data); + case IF_USB: + return pixbuf_to_widget(network_usb_pb_data); + case IF_VIRTUAL: return xpm_to_widget(network_virtual_16_xpm); + case IF_WIRED: + return pixbuf_to_widget(network_wired_pb_data); + case IF_PIPE: + case IF_STDIN: + return pixbuf_to_widget(pipe_pb_data); + default: + printf("unknown device type\n"); } - - if ( g_ascii_strncasecmp(if_info->name, "vmxnet", 6) == 0) { - return xpm_to_widget(network_virtual_16_xpm); - } - - if ( if_info->description && strstr(if_info->description, "VMware") != NULL ) { - return xpm_to_widget(network_virtual_16_xpm); - } - return pixbuf_to_widget(network_wired_pb_data); } @@ -692,17 +552,40 @@ static void capture_if_stop_cb(GtkWidget *w _U_, gpointer d _U_) { guint ifs; - GList *curr; - if_dlg_data_t *if_data; + if_dlg_data_t data; - for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) { - curr = g_list_nth(if_data_list, ifs); - if_data = (if_dlg_data_t *)(curr->data); - gtk_widget_set_sensitive(if_data->choose_bt, TRUE); + for (ifs = 0; ifs < gtk_list->len; ifs++) { + data = g_array_index(gtk_list, if_dlg_data_t, ifs); + gtk_widget_set_sensitive(data.choose_bt, TRUE); + gtk_list = g_array_remove_index(gtk_list, ifs); + g_array_insert_val(gtk_list, ifs, data); } capture_stop_cb(NULL, NULL); } +static void +make_gtk_array(void) +{ + interface_t device; + if_dlg_data_t data; + guint i; + + gtk_list = g_array_new(FALSE, FALSE, sizeof(if_dlg_data_t)); + + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + data.device_lb = NULL; + data.descr_lb = NULL; + data.ip_lb = NULL; + data.curr_lb = NULL; + data.last_lb = NULL; + data.choose_bt = NULL; +#ifdef _WIN32 + data.details_bt = NULL; +#endif + g_array_append_val(gtk_list, data); + } +} /* start getting capture stats from all interfaces */ void @@ -712,75 +595,53 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_) *main_sw, *bbox, *close_bt, - *help_bt, - *icon; + *help_bt; #ifdef HAVE_AIRPCAP GtkWidget *decryption_cb; #endif - GtkWidget *if_tb; + GtkWidget *if_tb, *icon; GtkWidget *if_lb; GtkWidget *eb; - int err; - gchar *err_str; GtkRequisition requisition; int row, height; - if_dlg_data_t *if_dlg_data = NULL; - int ifs; - GList *curr; - if_info_t *if_info; + guint ifs; + interface_t device; GString *if_tool_str = g_string_new(""); const gchar *addr_str; gchar *user_descr; - int preselected = 0, i; - interface_options interface_opts; - gboolean found = FALSE; + if_dlg_data_t data; if (cap_if_w != NULL) { /* There's already a "Capture Interfaces" dialog box; reactivate it. */ reactivate_window(cap_if_w); return; } - - preselected = global_capture_opts.ifaces->len; - /* LOAD THE INTERFACES */ - if_list = capture_interface_list(&err, &err_str); - if_list = g_list_sort (if_list, if_list_comparator_alph); - if (if_list == NULL) { - switch (err) { - - case CANT_GET_INTERFACE_LIST: - case DONT_HAVE_PCAP: - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - break; - - case NO_INTERFACES_FOUND: - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "There are no interfaces on which a capture can be done."); - break; - } + + if (global_capture_opts.all_ifaces->len == 0) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "There are no interfaces on which a capture can be done."); return; } +#ifdef _WIN32 + /* Is WPcap loaded? */ + if (!has_wpcap) { + char *detailed_err; + + detailed_err = cant_load_winpcap_err("Wireshark"); + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", detailed_err); + g_free(detailed_err); + return; + } +#endif #ifdef HAVE_AIRPCAP /* LOAD AIRPCAP INTERFACES */ - airpcap_if_list = get_airpcap_interface_list(&err, &err_str); - if (airpcap_if_list == NULL) - airpcap_if_active = airpcap_if_selected = NULL; decryption_cb = g_object_get_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY); update_decryption_mode_list(decryption_cb); - if (airpcap_if_list == NULL && err == CANT_GET_AIRPCAP_INTERFACE_LIST) { -#if 0 - /* XXX - Do we need to show an error here? */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); -#endif - g_free(err_str); - } - /* If no airpcap interface is present, gray everything */ if (airpcap_if_active == NULL) { if (airpcap_if_list == NULL) { @@ -796,6 +657,7 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_) airpcap_set_toolbar_start_capture(airpcap_if_active); #endif + make_gtk_array(); cap_if_w = dlg_window_new("Wireshark: Capture Interfaces"); /* transient_for top_level */ gtk_window_set_destroy_with_parent (GTK_WINDOW(cap_if_w), TRUE); @@ -843,144 +705,111 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_) height += 30; /* Start gathering statistics (using dumpcap) */ - sc = capture_stat_start(if_list); + sc = capture_stat_start(&global_capture_opts); /* List the interfaces */ - currently_selected = 0; - for (ifs = 0; (curr = g_list_nth(if_list, ifs)); ifs++) { + for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs); + data = g_array_index(gtk_list, if_dlg_data_t, ifs); g_string_assign(if_tool_str, ""); - if_info = (if_info_t *)curr->data; - /* Continue if capture device is hidden */ - if (prefs_is_capture_device_hidden(if_info->name)) { + if (device.hidden) { continue; } - - if_dlg_data = g_new0(if_dlg_data_t,1); - - if (preselected > 0) { - found = FALSE; - for (i = 0; i < (gint)global_capture_opts.ifaces->len; i++) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - if ((interface_opts.name == NULL) || - (strcmp(interface_opts.name, (char*)if_info->name) != 0)) { - continue; - } else { - found = TRUE; - currently_selected++; - preselected--; - break; - } - } - if_dlg_data->selected = found; - } else { - if_dlg_data->selected = FALSE; - } - if_dlg_data->if_info = *if_info; - - if_dlg_data->choose_bt = gtk_check_button_new(); - gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->choose_bt, 0, 1, row, row+1); + data.choose_bt = gtk_check_button_new(); + gtk_table_attach_defaults(GTK_TABLE(if_tb), data.choose_bt, 0, 1, row, row+1); if (gbl_capture_in_progress) { - gtk_widget_set_sensitive(if_dlg_data->choose_bt, FALSE); + gtk_widget_set_sensitive(data.choose_bt, FALSE); } else { - gtk_widget_set_sensitive(if_dlg_data->choose_bt, TRUE); + gtk_widget_set_sensitive(data.choose_bt, TRUE); } - gtk_toggle_button_set_active((GtkToggleButton *)if_dlg_data->choose_bt, if_dlg_data->selected); - g_signal_connect(if_dlg_data->choose_bt, "toggled", G_CALLBACK(store_selected), if_dlg_data); - /* Kind of adaptor (icon) */ -#ifdef HAVE_AIRPCAP - if (get_airpcap_if_from_name(airpcap_if_list,if_info->name) != NULL) - icon = xpm_to_widget(capture_airpcap_16_xpm); - else - icon = capture_get_if_icon(if_info); -#else - icon = capture_get_if_icon(if_info); -#endif + gtk_toggle_button_set_active((GtkToggleButton *)data.choose_bt, device.selected); + g_signal_connect(data.choose_bt, "toggled", G_CALLBACK(store_selected), device.name); + /* Kind of adaptor (icon) */ + icon = capture_get_if_icon(&(device)); gtk_table_attach_defaults(GTK_TABLE(if_tb), icon, 1, 2, row, row+1); /* device name */ - if_dlg_data->device_lb = gtk_label_new(if_info->name); - if_dlg_data->device = if_info->name; + data.device_lb = gtk_label_new(device.name); #ifndef _WIN32 - gtk_misc_set_alignment(GTK_MISC(if_dlg_data->device_lb), 0.0f, 0.5f); - gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->device_lb, 2, 4, row, row+1); + gtk_misc_set_alignment(GTK_MISC(data.device_lb), 0.0f, 0.5f); + gtk_table_attach_defaults(GTK_TABLE(if_tb), data.device_lb, 2, 4, row, row+1); #endif g_string_append(if_tool_str, "Device: "); - g_string_append(if_tool_str, if_info->name); + g_string_append(if_tool_str, device.name); g_string_append(if_tool_str, "\n"); /* description */ - user_descr = capture_dev_user_descr_find(if_info->name); + user_descr = capture_dev_user_descr_find(device.name); if (user_descr) { - if_dlg_data->descr_lb = gtk_label_new(user_descr); + data.descr_lb = gtk_label_new(user_descr); g_free (user_descr); } else { - if (if_info->description) - if_dlg_data->descr_lb = gtk_label_new(if_info->description); + if (device.if_info.description) + data.descr_lb = gtk_label_new(device.if_info.description); else - if_dlg_data->descr_lb = gtk_label_new(""); + data.descr_lb = gtk_label_new(""); } - gtk_misc_set_alignment(GTK_MISC(if_dlg_data->descr_lb), 0.0f, 0.5f); - gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->descr_lb, 4, 5, row, row+1); - - if (if_info->description) { + gtk_misc_set_alignment(GTK_MISC(data.descr_lb), 0.0f, 0.5f); + gtk_table_attach_defaults(GTK_TABLE(if_tb), data.descr_lb, 4, 5, row, row+1); + if (device.if_info.description) { g_string_append(if_tool_str, "Description: "); - g_string_append(if_tool_str, if_info->description); + g_string_append(if_tool_str, device.if_info.description); g_string_append(if_tool_str, "\n"); } /* IP address */ /* Only one IP address will be shown, start with the first */ g_string_append(if_tool_str, "IP: "); - if_dlg_data->ip_lb = gtk_label_new(""); - addr_str = set_ip_addr_label (if_info->addrs, if_dlg_data->ip_lb, 0); + data.ip_lb = gtk_label_new(""); + addr_str = set_ip_addr_label (device.if_info.addrs, data.ip_lb, 0); if (addr_str) { - gtk_widget_set_sensitive(if_dlg_data->ip_lb, TRUE); + gtk_widget_set_sensitive(data.ip_lb, TRUE); g_string_append(if_tool_str, addr_str); } else { - gtk_widget_set_sensitive(if_dlg_data->ip_lb, FALSE); + gtk_widget_set_sensitive(data.ip_lb, FALSE); g_string_append(if_tool_str, "none"); } eb = gtk_event_box_new (); - gtk_container_add(GTK_CONTAINER(eb), if_dlg_data->ip_lb); + gtk_container_add(GTK_CONTAINER(eb), data.ip_lb); gtk_table_attach_defaults(GTK_TABLE(if_tb), eb, 5, 6, row, row+1); - if (get_ip_addr_count(if_info->addrs) > 1) { + if (get_ip_addr_count(device.if_info.addrs) > 1) { /* More than one IP address, make it possible to toggle */ - g_object_set_data(G_OBJECT(eb), CAPTURE_IF_IP_ADDR_LABEL, if_dlg_data->ip_lb); + g_object_set_data(G_OBJECT(eb), CAPTURE_IF_IP_ADDR_LABEL, data.ip_lb); g_signal_connect(eb, "enter-notify-event", G_CALLBACK(ip_label_enter_cb), NULL); g_signal_connect(eb, "leave-notify-event", G_CALLBACK(ip_label_leave_cb), NULL); - g_signal_connect(eb, "button-press-event", G_CALLBACK(ip_label_press_cb), if_info->addrs); + g_signal_connect(eb, "button-press-event", G_CALLBACK(ip_label_press_cb), device.if_info.addrs); } g_string_append(if_tool_str, "\n"); /* packets */ - if_dlg_data->curr_lb = gtk_label_new("-"); - gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->curr_lb, 6, 7, row, row+1); + data.curr_lb = gtk_label_new("-"); + gtk_table_attach_defaults(GTK_TABLE(if_tb), data.curr_lb, 6, 7, row, row+1); /* packets/s */ - if_dlg_data->last_lb = gtk_label_new("-"); - gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->last_lb, 7, 8, row, row+1); + data.last_lb = gtk_label_new("-"); + gtk_table_attach_defaults(GTK_TABLE(if_tb), data.last_lb, 7, 8, row, row+1); /* details button */ #ifdef _WIN32 - if_dlg_data->details_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_CAPTURE_DETAILS); - gtk_widget_set_tooltip_text(if_dlg_data->details_bt, "Open the capture details dialog of this interface."); - gtk_table_attach_defaults(GTK_TABLE(if_tb), if_dlg_data->details_bt, 8, 9, row, row+1); - if (capture_if_has_details(if_dlg_data->device)) { - g_signal_connect(if_dlg_data->details_bt, "clicked", G_CALLBACK(capture_details_cb), if_dlg_data); + data.details_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_CAPTURE_DETAILS); + gtk_widget_set_tooltip_text(data.details_bt, "Open the capture details dialog of this interface."); + gtk_table_attach_defaults(GTK_TABLE(if_tb), data.details_bt, 8, 9, row, row+1); + if (capture_if_has_details(device.name)) { + g_signal_connect(data.details_bt, "clicked", G_CALLBACK(capture_details_cb), device.name); } else { - gtk_widget_set_sensitive(if_dlg_data->details_bt, FALSE); + gtk_widget_set_sensitive(data.details_bt, FALSE); } #endif - - if_data_list = g_list_append(if_data_list, if_dlg_data); - + gtk_list = g_array_remove_index(gtk_list, ifs); + g_array_insert_val(gtk_list, ifs, data); + row++; if (row <= 10) { /* Lets add up 10 rows of interfaces, otherwise the window may become too high */ - gtk_widget_get_preferred_size(GTK_WIDGET(if_dlg_data->choose_bt), &requisition, NULL); + gtk_widget_get_preferred_size(GTK_WIDGET(data.choose_bt), &requisition, NULL); height += requisition.height; - } + } } g_string_free(if_tool_str, TRUE); @@ -998,9 +827,9 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_) window_set_cancel_button(cap_if_w, close_bt, window_cancel_button_cb); gtk_widget_set_tooltip_text(close_bt, "Close this window."); options_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_OPTIONS); - g_signal_connect(options_bt, "clicked", G_CALLBACK(capture_prepare_cb), if_dlg_data); + g_signal_connect(options_bt, "clicked", G_CALLBACK(capture_prepare_cb), device.name); capture_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_START); - g_signal_connect(capture_bt, "clicked", G_CALLBACK(capture_do_cb), if_dlg_data); + g_signal_connect(capture_bt, "clicked", G_CALLBACK(capture_do_cb), device.name); gtk_widget_get_preferred_size(GTK_WIDGET(close_bt), &requisition, NULL); /* height + static offset + what the GTK MS Windows Engine needs in addition per interface */ height += requisition.height + 40 + ifs; @@ -1031,17 +860,15 @@ void refresh_if_window(void) capture_if_cb(NULL, NULL); } -void select_all_interfaces(gboolean enable) +void select_all_interfaces(gboolean enable _U_) { - if_dlg_data_t *temp; guint ifs; - GList *curr; + interface_t device; - for (ifs = 0; ifs < g_list_length(if_data_list); ifs++) { - curr = g_list_nth(if_data_list, ifs); - temp = (if_dlg_data_t *)(curr->data); - update_selected_interface(temp->if_info.name, enable); - } + for (ifs = 0; ifs < global_capture_opts.all_ifaces->len; ifs++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, ifs); + update_selected_interface(device.if_info.name); + } } void destroy_if_window(void) diff --git a/ui/gtk/capture_if_dlg.h b/ui/gtk/capture_if_dlg.h index 3c2f2359d0..a100b4c52a 100644 --- a/ui/gtk/capture_if_dlg.h +++ b/ui/gtk/capture_if_dlg.h @@ -48,10 +48,10 @@ capture_if_cb(GtkWidget *widget, gpointer data); * Used to retrieve the interface icon */ GtkWidget * -capture_get_if_icon(const if_info_t* if_info); +capture_get_if_icon(interface_t *device); void -update_selected_interface(gchar *name, gboolean activate); +update_selected_interface(gchar *name); gboolean interfaces_dialog_window_present(void); @@ -65,6 +65,9 @@ select_all_interfaces(gboolean enable); void destroy_if_window(void); +gint +if_list_comparator_alph (const void *first_arg, const void *second_arg); + #endif /* HAVE_LIBPCAP */ #endif /* capture_if_dlg.h */ diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 4fc410154e..8c2f420a28 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -118,6 +118,7 @@ #include "../capture_ifinfo.h" #include "../capture.h" #include "../capture_sync.h" +extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg); #endif #ifdef _WIN32 @@ -515,16 +516,16 @@ selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_) static gboolean is_address_column (gint column) { - if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) || - (cfile.cinfo.col_fmt[column] == COL_RES_SRC) || - (cfile.cinfo.col_fmt[column] == COL_DEF_DST) || - (cfile.cinfo.col_fmt[column] == COL_RES_DST)) && - strlen(cfile.cinfo.col_expr.col_expr_val[column])) - { - return TRUE; - } + if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) || + (cfile.cinfo.col_fmt[column] == COL_RES_SRC) || + (cfile.cinfo.col_fmt[column] == COL_DEF_DST) || + (cfile.cinfo.col_fmt[column] == COL_RES_DST)) && + strlen(cfile.cinfo.col_expr.col_expr_val[column])) + { + return TRUE; + } - return FALSE; + return FALSE; } GList * @@ -550,17 +551,17 @@ get_ip_address_list_from_packet_list_row(gpointer data) epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo); epan_dissect_fill_in_columns(&edt, TRUE, TRUE); - /* First check selected column */ - if (is_address_column (column)) { - addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column])); + /* First check selected column */ + if (is_address_column (column)) { + addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column])); } - for (col = 0; col < cfile.cinfo.num_cols; col++) { - /* Then check all columns except the selected */ - if ((col != column) && (is_address_column (col))) { - addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col])); - } - } + for (col = 0; col < cfile.cinfo.num_cols; col++) { + /* Then check all columns except the selected */ + if ((col != column) && (is_address_column (col))) { + addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col])); + } + } epan_dissect_cleanup(&edt); } @@ -693,23 +694,23 @@ copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E acti /* mark as reference time frame */ void set_frame_reftime(gboolean set, frame_data *frame, gint row) { - if (row == -1) - return; - if (set) { - frame->flags.ref_time=1; - cfile.ref_time_count++; - } else { - frame->flags.ref_time=0; - cfile.ref_time_count--; - } - cf_reftime_packets(&cfile); - if (!frame->flags.ref_time && !frame->flags.passed_dfilter) { - new_packet_list_freeze(); - cfile.displayed_count--; - new_packet_list_recreate_visible_rows(); - new_packet_list_thaw(); - } - new_packet_list_queue_draw(); + if (row == -1) + return; + if (set) { + frame->flags.ref_time=1; + cfile.ref_time_count++; + } else { + frame->flags.ref_time=0; + cfile.ref_time_count--; + } + cf_reftime_packets(&cfile); + if (!frame->flags.ref_time && !frame->flags.passed_dfilter) { + new_packet_list_freeze(); + cfile.displayed_count--; + new_packet_list_recreate_visible_rows(); + new_packet_list_thaw(); + } + new_packet_list_queue_draw(); } @@ -719,8 +720,8 @@ static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_ case(ESD_BTN_YES): timestamp_set_type(TS_RELATIVE); recent.gui_time_format = TS_RELATIVE; - cf_timestamp_auto_precision(&cfile); - new_packet_list_queue_draw(); + cf_timestamp_auto_precision(&cfile); + new_packet_list_queue_draw(); break; case(ESD_BTN_NO): break; @@ -730,7 +731,7 @@ static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_ if (cfile.current_frame) { set_frame_reftime(!cfile.current_frame->flags.ref_time, - cfile.current_frame, cfile.current_row); + cfile.current_frame, cfile.current_row); } } @@ -738,31 +739,31 @@ static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_ void reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action) { - static GtkWidget *reftime_dialog = NULL; + static GtkWidget *reftime_dialog = NULL; - switch(action){ - case REFTIME_TOGGLE: - if (cfile.current_frame) { - if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) { - reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO, - "%sSwitch to the appropriate Time Display Format?%s\n\n" - "Time References don't work well with the currently selected Time Display Format.\n\n" - "Do you want to switch to \"Seconds Since Beginning of Capture\" now?", - simple_dialog_primary_start(), simple_dialog_primary_end()); - simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL); - } else { - set_frame_reftime(!cfile.current_frame->flags.ref_time, - cfile.current_frame, cfile.current_row); + switch(action){ + case REFTIME_TOGGLE: + if (cfile.current_frame) { + if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) { + reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO, + "%sSwitch to the appropriate Time Display Format?%s\n\n" + "Time References don't work well with the currently selected Time Display Format.\n\n" + "Do you want to switch to \"Seconds Since Beginning of Capture\" now?", + simple_dialog_primary_start(), simple_dialog_primary_end()); + simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL); + } else { + set_frame_reftime(!cfile.current_frame->flags.ref_time, + cfile.current_frame, cfile.current_row); + } } + break; + case REFTIME_FIND_NEXT: + cf_find_packet_time_reference(&cfile, SD_FORWARD); + break; + case REFTIME_FIND_PREV: + cf_find_packet_time_reference(&cfile, SD_BACKWARD); + break; } - break; - case REFTIME_FIND_NEXT: - cf_find_packet_time_reference(&cfile, SD_FORWARD); - break; - case REFTIME_FIND_PREV: - cf_find_packet_time_reference(&cfile, SD_BACKWARD); - break; - } } void @@ -875,47 +876,47 @@ tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_) } void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) { - if (cfile.edt->tree) - collapse_all_tree(cfile.edt->tree, tree_view_gbl); + if (cfile.edt->tree) + collapse_all_tree(cfile.edt->tree, tree_view_gbl); } void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) { - if (cfile.edt->tree) - expand_all_tree(cfile.edt->tree, tree_view_gbl); + if (cfile.edt->tree) + expand_all_tree(cfile.edt->tree, tree_view_gbl); } void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_) { - if (cfile.finfo_selected) { - column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name, - cfile.finfo_selected->hfinfo->abbrev,0); - /* Recreate the packet list according to new preferences */ - new_packet_list_recreate (); - if (!prefs.gui_use_pref_save) { - prefs_main_write(); + if (cfile.finfo_selected) { + column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name, + cfile.finfo_selected->hfinfo->abbrev,0); + /* Recreate the packet list according to new preferences */ + new_packet_list_recreate (); + if (!prefs.gui_use_pref_save) { + prefs_main_write(); + } + cfile.cinfo.columns_changed = FALSE; /* Reset value */ } - cfile.cinfo.columns_changed = FALSE; /* Reset value */ - } } void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) { - GtkTreePath *path; + GtkTreePath *path; - path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected); - if(path) { - /* the mouse position is at an entry, expand that one */ - gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE); - gtk_tree_path_free(path); - } + path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected); + if(path) { + /* the mouse position is at an entry, expand that one */ + gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE); + gtk_tree_path_free(path); + } } void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) { - if (cfile.edt->tree) { - guint32 tmp = gbl_resolv_flags; - gbl_resolv_flags = RESOLV_ALL; - proto_tree_draw(cfile.edt->tree, tree_view_gbl); - gbl_resolv_flags = tmp; - } + if (cfile.edt->tree) { + guint32 tmp = gbl_resolv_flags; + gbl_resolv_flags = RESOLV_ALL; + proto_tree_draw(cfile.edt->tree, tree_view_gbl); + gbl_resolv_flags = tmp; + } } static void @@ -929,100 +930,100 @@ main_set_for_capture_file(gboolean have_capture_file_in) gboolean main_do_quit(void) { - /* get the current geometry, before writing it to disk */ - main_save_window_geometry(top_level); + /* get the current geometry, before writing it to disk */ + main_save_window_geometry(top_level); - /* write user's recent file to disk - * It is no problem to write this file, even if we do not quit */ - write_profile_recent(); - write_recent(); + /* write user's recent file to disk + * It is no problem to write this file, even if we do not quit */ + write_profile_recent(); + write_recent(); - /* XXX - should we check whether the capture file is an - unsaved temporary file for a live capture and, if so, - pop up a "do you want to exit without saving the capture - file?" dialog, and then just return, leaving said dialog - box to forcibly quit if the user clicks "OK"? + /* XXX - should we check whether the capture file is an + unsaved temporary file for a live capture and, if so, + pop up a "do you want to exit without saving the capture + file?" dialog, and then just return, leaving said dialog + box to forcibly quit if the user clicks "OK"? - If so, note that this should be done in a subroutine that - returns TRUE if we do so, and FALSE otherwise, and if it - returns TRUE we should return TRUE without nuking anything. + If so, note that this should be done in a subroutine that + returns TRUE if we do so, and FALSE otherwise, and if it + returns TRUE we should return TRUE without nuking anything. - Note that, if we do that, we might also want to check if - an "Update list of packets in real time" capture is in - progress and, if so, ask whether they want to terminate - the capture and discard it, and return TRUE, before nuking - any child capture, if they say they don't want to do so. */ + Note that, if we do that, we might also want to check if + an "Update list of packets in real time" capture is in + progress and, if so, ask whether they want to terminate + the capture and discard it, and return TRUE, before nuking + any child capture, if they say they don't want to do so. */ #ifdef HAVE_LIBPCAP - /* Nuke any child capture in progress. */ - capture_kill_child(&global_capture_opts); + /* Nuke any child capture in progress. */ + capture_kill_child(&global_capture_opts); #endif - /* Are we in the middle of reading a capture? */ - if (cfile.state == FILE_READ_IN_PROGRESS) { - /* Yes, so we can't just close the file and quit, as - that may yank the rug out from under the read in - progress; instead, just set the state to - "FILE_READ_ABORTED" and return - the code doing the read - will check for that and, if it sees that, will clean - up and quit. */ - cfile.state = FILE_READ_ABORTED; + /* Are we in the middle of reading a capture? */ + if (cfile.state == FILE_READ_IN_PROGRESS) { + /* Yes, so we can't just close the file and quit, as + that may yank the rug out from under the read in + progress; instead, just set the state to + "FILE_READ_ABORTED" and return - the code doing the read + will check for that and, if it sees that, will clean + up and quit. */ + cfile.state = FILE_READ_ABORTED; - /* Say that the window should *not* be deleted; - that'll be done by the code that cleans up. */ - return TRUE; - } else { - /* Close any capture file we have open; on some OSes, you - can't unlink a temporary capture file if you have it - open. - "cf_close()" will unlink it after closing it if - it's a temporary file. + /* Say that the window should *not* be deleted; + that'll be done by the code that cleans up. */ + return TRUE; + } else { + /* Close any capture file we have open; on some OSes, you + can't unlink a temporary capture file if you have it + open. + "cf_close()" will unlink it after closing it if + it's a temporary file. - We do this here, rather than after the main loop returns, - as, after the main loop returns, the main window may have - been destroyed (if this is called due to a "destroy" - even on the main window rather than due to the user - selecting a menu item), and there may be a crash - or other problem when "cf_close()" tries to - clean up stuff in the main window. + We do this here, rather than after the main loop returns, + as, after the main loop returns, the main window may have + been destroyed (if this is called due to a "destroy" + even on the main window rather than due to the user + selecting a menu item), and there may be a crash + or other problem when "cf_close()" tries to + clean up stuff in the main window. - XXX - is there a better place to put this? - Or should we have a routine that *just* closes the - capture file, and doesn't do anything with the UI, - which we'd call here, and another routine that - calls that routine and also cleans up the UI, which - we'd call elsewhere? */ - cf_close(&cfile); + XXX - is there a better place to put this? + Or should we have a routine that *just* closes the + capture file, and doesn't do anything with the UI, + which we'd call here, and another routine that + calls that routine and also cleans up the UI, which + we'd call elsewhere? */ + cf_close(&cfile); - /* Exit by leaving the main loop, so that any quit functions - we registered get called. */ - gtk_main_quit(); + /* Exit by leaving the main loop, so that any quit functions + we registered get called. */ + gtk_main_quit(); - /* Say that the window should be deleted. */ - return FALSE; - } + /* Say that the window should be deleted. */ + return FALSE; + } } static gboolean main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_) { - gpointer dialog; + gpointer dialog; - if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) { - gtk_window_present(GTK_WINDOW(top_level)); - /* user didn't saved his current file, ask him */ - dialog = simple_dialog(ESD_TYPE_CONFIRMATION, - ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL), - "%sSave capture file before program quit?%s\n\n" - "If you quit the program without saving, your capture data will be discarded.", - simple_dialog_primary_start(), simple_dialog_primary_end()); - simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL); - return TRUE; - } else { - /* unchanged file, just exit */ - /* "main_do_quit()" indicates whether the main window should be deleted. */ - return main_do_quit(); - } + if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) { + gtk_window_present(GTK_WINDOW(top_level)); + /* user didn't saved his current file, ask him */ + dialog = simple_dialog(ESD_TYPE_CONFIRMATION, + ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL), + "%sSave capture file before program quit?%s\n\n" + "If you quit the program without saving, your capture data will be discarded.", + simple_dialog_primary_start(), simple_dialog_primary_end()); + simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL); + return TRUE; + } else { + /* unchanged file, just exit */ + /* "main_do_quit()" indicates whether the main window should be deleted. */ + return main_do_quit(); + } } @@ -1116,18 +1117,18 @@ file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) { gpointer dialog; - if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) { + if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) { /* user didn't saved his current file, ask him */ - dialog = simple_dialog(ESD_TYPE_CONFIRMATION, - ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL), - "%sSave capture file before program quit?%s\n\n" - "If you quit the program without saving, your capture data will be discarded.", - simple_dialog_primary_start(), simple_dialog_primary_end()); - simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL); - } else { - /* unchanged file, just exit */ - main_do_quit(); - } + dialog = simple_dialog(ESD_TYPE_CONFIRMATION, + ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL), + "%sSave capture file before program quit?%s\n\n" + "If you quit the program without saving, your capture data will be discarded.", + simple_dialog_primary_start(), simple_dialog_primary_end()); + simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL); + } else { + /* unchanged file, just exit */ + main_do_quit(); + } } static void @@ -1317,8 +1318,8 @@ cmdarg_err_cont(const char *fmt, ...) static gboolean tap_update_cb(gpointer data _U_) { - draw_tap_listeners(FALSE); - return TRUE; + draw_tap_listeners(FALSE); + return TRUE; } /* Restart the tap update display timer with new configured interval */ @@ -1331,18 +1332,18 @@ void reset_tap_update_timer(void) void protect_thread_critical_region(void) { - /* Threading support for TAP:s removed - * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html - * See the commit for removed code: - * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027 - */ + /* Threading support for TAP:s removed + * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html + * See the commit for removed code: + * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027 + */ } void unprotect_thread_critical_region(void) { - /* Threading support for TAP:s removed - * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html - */ + /* Threading support for TAP:s removed + * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html + */ } @@ -1357,9 +1358,9 @@ resolv_update_cb(gpointer data _U_) /* Anything new show up? */ if (host_name_lookup_process(NULL)) { if (gtk_widget_get_window(pkt_scrollw)) - gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE); + gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE); if (gtk_widget_get_window(tv_scrollw)) - gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE); + gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE); } /* Always check. Even if we don't do async lookups we could still get @@ -1402,6 +1403,9 @@ npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_) static void main_cf_cb_file_closing(capture_file *cf) { +#ifdef HAVE_LIBPCAP + int i; +#endif /* if we have more than 10000 packets, show a splash screen while closing */ /* XXX - don't know a better way to decide whether to show or not, @@ -1420,6 +1424,14 @@ main_cf_cb_file_closing(capture_file *cf) destroy_packet_wins(); file_save_as_destroy(); +#ifdef HAVE_LIBPCAP + if (global_capture_opts.ifaces && global_capture_opts.ifaces->len > 0) { + for (i = (int)global_capture_opts.ifaces->len-1; i >= 0; i--) { + global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i); + } + } +#endif + /* Restore the standard title bar message. */ set_main_window_name("The Wireshark Network Analyzer"); @@ -1466,7 +1478,7 @@ main_cf_cb_file_read_finished(capture_file *cf) add_menu_recent_capture_file(cf->filename); /* Remember folder for next Open dialog and save it in recent */ - dir_path = get_dirname(g_strdup(cf->filename)); + dir_path = get_dirname(g_strdup(cf->filename)); set_last_open_dir(dir_path); g_free(dir_path); } @@ -2035,6 +2047,7 @@ main(int argc, char *argv[]) char *gdp_path, *dp_path; int err; #ifdef HAVE_LIBPCAP + int error; gboolean start_capture = FALSE; gboolean list_link_layer_types = FALSE; GList *if_list; @@ -2352,28 +2365,28 @@ main(int argc, char *argv[]) /* We might want to have component specific log levels later ... */ log_flags = - G_LOG_LEVEL_ERROR| - G_LOG_LEVEL_CRITICAL| - G_LOG_LEVEL_WARNING| - G_LOG_LEVEL_MESSAGE| - G_LOG_LEVEL_INFO| - G_LOG_LEVEL_DEBUG| - G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION; + G_LOG_LEVEL_ERROR| + G_LOG_LEVEL_CRITICAL| + G_LOG_LEVEL_WARNING| + G_LOG_LEVEL_MESSAGE| + G_LOG_LEVEL_INFO| + G_LOG_LEVEL_DEBUG| + G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION; g_log_set_handler(NULL, - log_flags, - console_log_handler, NULL /* user_data */); + log_flags, + console_log_handler, NULL /* user_data */); g_log_set_handler(LOG_DOMAIN_MAIN, - log_flags, - console_log_handler, NULL /* user_data */); + log_flags, + console_log_handler, NULL /* user_data */); #ifdef HAVE_LIBPCAP g_log_set_handler(LOG_DOMAIN_CAPTURE, - log_flags, - console_log_handler, NULL /* user_data */); + log_flags, + console_log_handler, NULL /* user_data */); g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD, - log_flags, - console_log_handler, NULL /* user_data */); + log_flags, + console_log_handler, NULL /* user_data */); /* Set the initial values in the capture options. This might be overwritten by preference settings and then again by the command line parameters. */ @@ -2407,7 +2420,7 @@ main(int argc, char *argv[]) dissectors, and we must do it before we read the preferences, in case any dissectors register preferences. */ epan_init(register_all_protocols,register_all_protocol_handoffs, - splash_update, (gpointer) splash_win, + splash_update, (gpointer) splash_win, failure_alert_box,open_failure_alert_box,read_failure_alert_box, write_failure_alert_box); @@ -2417,8 +2430,8 @@ main(int argc, char *argv[]) as the "-z" argument can specify a registered tap. */ /* we register the plugin taps before the other taps because - stats_tree taps plugins will be registered as tap listeners - by stats_tree_stat.c and need to registered before that */ + stats_tree taps plugins will be registered as tap listeners + by stats_tree_stat.c and need to registered before that */ #ifdef HAVE_PLUGINS register_all_plugin_tap_listeners(); @@ -2447,6 +2460,11 @@ main(int argc, char *argv[]) /* Fill in capture options with values from the preferences */ prefs_to_capture_opts(); +/*#ifdef HAVE_LIBPCAP + if (global_capture_opts.all_ifaces->len == 0) { + scan_local_interfaces(&global_capture_opts, &error); + } +#endif*/ /* Now get our args */ while ((opt = getopt(argc, argv, optstring)) != -1) { switch (opt) { @@ -2457,7 +2475,6 @@ main(int argc, char *argv[]) case 'f': /* capture filter */ case 'k': /* Start capture immediately */ case 'H': /* Hide capture info dialog box */ - case 'i': /* Use interface xxx */ case 'p': /* Don't capture in promiscuous mode */ #ifdef HAVE_PCAP_CREATE case 'I': /* Capture in monitor mode, if available */ @@ -2487,13 +2504,25 @@ main(int argc, char *argv[]) break; #endif +#ifdef HAVE_LIBPCAP + case 'i': /* Use interface xxx */ + status = capture_opts_add_iface_opt(&global_capture_opts, optarg); + if (status != 0) { + exit(status); + } +#else + capture_option_specified = TRUE; + arg_error = TRUE; +#endif + break; + /*** all non capture option specific ***/ case 'C': /* Configuration profile settings were already processed just ignore them this time*/ - break; + break; case 'd': - dfilter = optarg; - break; + dfilter = optarg; + break; case 'j': /* Search backwards for a matching packet from filter in option J */ jump_backwards = TRUE; break; @@ -2532,7 +2561,7 @@ main(int argc, char *argv[]) badopt = string_to_name_resolve(optarg, &gbl_resolv_flags); if (badopt != '\0') { cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'", - badopt); + badopt); exit(1); } break; @@ -2557,7 +2586,7 @@ main(int argc, char *argv[]) case PREFS_SET_NO_SUCH_PREF: case PREFS_SET_OBSOLETE: cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value", - optarg); + optarg); exit(1); break; default: @@ -2566,7 +2595,7 @@ main(int argc, char *argv[]) break; case PREFS_SET_OBSOLETE: cmdarg_err("-o flag \"%s\" specifies obsolete preference", - optarg); + optarg); exit(1); break; default: @@ -2577,9 +2606,9 @@ main(int argc, char *argv[]) /* Path settings were already processed just ignore them this time*/ break; case 'r': /* Read capture file xxx */ - /* We may set "last_open_dir" to "cf_name", and if we change - "last_open_dir" later, we free the old value, so we have to - set "cf_name" to something that's been allocated. */ + /* We may set "last_open_dir" to "cf_name", and if we change + "last_open_dir" later, we free the old value, so we have to + set "cf_name" to something that's been allocated. */ cf_name = g_strdup(optarg); break; case 'R': /* Read file filter */ @@ -2630,11 +2659,11 @@ main(int argc, char *argv[]) part of a tap filter. Instead, we just add the argument to a list of stat arguments. */ if (!process_stat_cmd_arg(optarg)) { - cmdarg_err("Invalid -z argument."); - cmdarg_err_cont(" -z argument must be one of :"); - list_stat_cmd_args(); - exit(1); - } + cmdarg_err("Invalid -z argument."); + cmdarg_err_cont(" -z argument must be one of :"); + list_stat_cmd_args(); + exit(1); + } break; default: case '?': /* Bad flag - print usage message */ @@ -2687,7 +2716,12 @@ main(int argc, char *argv[]) print_usage(FALSE); exit(1); } - + +#ifdef HAVE_LIBPCAP + if (global_capture_opts.all_ifaces->len == 0) { + scan_local_interfaces(&global_capture_opts, &error); + } +#endif #ifdef HAVE_LIBPCAP if (start_capture && list_link_layer_types) { /* Specifying *both* is bogus. */ @@ -2721,23 +2755,18 @@ main(int argc, char *argv[]) sense? */ if (global_capture_opts.multi_files_on) { /* Ring buffer works only under certain conditions: - a) ring buffer does not work with temporary files; - b) real_time_mode and multi_files_on are mutually exclusive - - real_time_mode takes precedence; - c) it makes no sense to enable the ring buffer if the maximum - file size is set to "infinite". */ + a) ring buffer does not work with temporary files; + b) real_time_mode and multi_files_on are mutually exclusive - + real_time_mode takes precedence; + c) it makes no sense to enable the ring buffer if the maximum + file size is set to "infinite". */ if (global_capture_opts.save_file == NULL) { - cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file."); - global_capture_opts.multi_files_on = FALSE; + cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file."); + global_capture_opts.multi_files_on = FALSE; } -/* if (global_capture_opts.real_time_mode) { - cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done."); - global_capture_opts.multi_files_on = FALSE; - }*/ if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) { - cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified."); -/* XXX - this must be redesigned as the conditions changed */ -/* global_capture_opts.multi_files_on = FALSE;*/ + cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified."); + /* XXX - this must be redesigned as the conditions changed */ } } } @@ -2754,23 +2783,32 @@ main(int argc, char *argv[]) /* Get the list of link-layer types for the capture devices. */ if_capabilities_t *caps; guint i; - interface_options interface_opts; + interface_t device; + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - caps = capture_get_if_capabilities(interface_opts.name, interface_opts.monitor_mode, &err_str); - if (caps == NULL) { - cmdarg_err("%s", err_str); - g_free(err_str); - exit(2); + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (device.selected) { +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str); +#else + caps = capture_get_if_capabilities(device.name, FALSE, &err_str); +#endif + if (caps == NULL) { + cmdarg_err("%s", 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.", device.name); + exit(2); + } +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported); +#else + capture_opts_print_if_capabilities(caps, device.name, FALSE); +#endif + free_if_capabilities(caps); } - if (caps->data_link_types == NULL) { - cmdarg_err("The capture device \"%s\" has no data link types.", interface_opts.name); - exit(2); - } - capture_opts_print_if_capabilities(caps, interface_opts.name, interface_opts.monitor_mode); - free_if_capabilities(caps); } exit(0); } @@ -2785,53 +2823,20 @@ main(int argc, char *argv[]) prefs_apply_all(); #ifdef HAVE_LIBPCAP - if ((global_capture_opts.ifaces->len == 0) && + if ((global_capture_opts.num_selected == 0) && (prefs.capture_device != NULL)) { - GList *curr, *combo_list; - gboolean found = FALSE; - - if_list = capture_interface_list(&err, NULL); - if (g_list_length(if_list) > 0) { - combo_list = build_capture_combo_list(if_list, FALSE); - free_interface_list(if_list); - for (curr = combo_list; curr; curr = g_list_next(curr)) { - if (strcmp(curr->data, prefs.capture_device) == 0) { - found = TRUE; - break; - } + guint i; + interface_t device; + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) { + device.selected = TRUE; + global_capture_opts.num_selected++; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); + break; } } - if (found) { - interface_options interface_opts; - - interface_opts.name = g_strdup(get_if_name(prefs.capture_device)); - interface_opts.descr = get_interface_descriptive_name(interface_opts.name); - interface_opts.monitor_mode = prefs_capture_device_monitor_mode(interface_opts.name); - interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name); - interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter); - interface_opts.snaplen = global_capture_opts.default_options.snaplen; - interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen; - interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode; -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = global_capture_opts.default_options.buffer_size; -#endif -#ifdef HAVE_PCAP_REMOTE - interface_opts.src_type = global_capture_opts.default_options.src_type; - interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - interface_opts.auth_type = global_capture_opts.default_options.auth_type; - interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; - #endif - #ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; - interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; - #endif - g_array_insert_val(global_capture_opts.ifaces, 0, interface_opts); - } } #endif @@ -2873,8 +2878,8 @@ main(int argc, char *argv[]) recent_read_dynamic(&rf_path, &rf_open_errno); if (rf_path != NULL && rf_open_errno != 0) { simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, - "Could not open recent file\n\"%s\": %s.", - rf_path, g_strerror(rf_open_errno)); + "Could not open recent file\n\"%s\": %s.", + rf_path, g_strerror(rf_open_errno)); } color_filters_enable(recent.packet_list_colorize); @@ -2996,15 +3001,15 @@ main(int argc, char *argv[]) break; } - /* If the filename is not the absolute path, prepend the current dir. This happens - when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */ - if (!g_path_is_absolute(cf_name)) { - char *old_cf_name = cf_name; - char *pwd = g_get_current_dir(); - cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name); - g_free(old_cf_name); - g_free(pwd); - } + /* If the filename is not the absolute path, prepend the current dir. This happens + when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */ + if (!g_path_is_absolute(cf_name)) { + char *old_cf_name = cf_name; + char *pwd = g_get_current_dir(); + cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name); + g_free(old_cf_name); + g_free(pwd); + } /* Save the name of the containing directory specified in the path name, if any; we can write over cf_name, which is a @@ -3019,7 +3024,7 @@ main(int argc, char *argv[]) dfilter_free(rfcode); cfile.rfcode = NULL; show_main_window(FALSE); - /* Don't call check_and_warn_user_startup(): we did it above */ + /* Don't call check_and_warn_user_startup(): we did it above */ set_menus_for_capture_in_progress(FALSE); set_capture_if_dialog_for_capture_in_progress(FALSE); } @@ -3039,10 +3044,10 @@ main(int argc, char *argv[]) check_and_warn_user_startup(cf_name); if (capture_start(&global_capture_opts)) { /* The capture started. Open stat windows; we do so after creating - the main window, to avoid GTK warnings, and after successfully - opening the capture file, so we know we have something to compute - stats on, and after registering all dissectors, so that MATE will - have registered its field array and we can have a tap filter with + the main window, to avoid GTK warnings, and after successfully + opening the capture file, so we know we have something to compute + stats on, and after registering all dissectors, so that MATE will + have registered its field array and we can have a tap filter with one of MATE's late-registered fields as part of the filter. */ start_requested_stats(); } @@ -3121,9 +3126,9 @@ main(int argc, char *argv[]) int _stdcall WinMain (struct HINSTANCE__ *hInstance, - struct HINSTANCE__ *hPrevInstance, - char *lpszCmdLine, - int nCmdShow) + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) { INITCOMMONCONTROLSEX comm_ctrl; @@ -3224,7 +3229,7 @@ destroy_console(void) static void console_log_handler(const char *log_domain, GLogLevelFlags log_level, - const char *message, gpointer user_data _U_) + const char *message, gpointer user_data _U_) { time_t curr; struct tm *today; @@ -3548,7 +3553,6 @@ main_widgets_show_or_hide(void) if (!have_capture_file) { if(welcome_pane) { gtk_widget_show(welcome_pane); - select_ifaces(); } } else { gtk_widget_hide(welcome_pane); @@ -3581,11 +3585,11 @@ static gboolean top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_) { if (event->keyval == GDK_F8) { - new_packet_list_next(); - return TRUE; + new_packet_list_next(); + return TRUE; } else if (event->keyval == GDK_F7) { - new_packet_list_prev(); - return TRUE; + new_packet_list_prev(); + return TRUE; } else if (event->state & NO_SHIFT_MOD_MASK) { return FALSE; /* Skip control, alt, and other modifiers */ /* @@ -3595,12 +3599,12 @@ top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_dat * for values < 127. */ } else if (isascii(event->keyval) && isprint(event->keyval)) { - /* Forward the keypress on to the display filter entry */ - if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) { - gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget); + /* Forward the keypress on to the display filter entry */ + if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) { + gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget); gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1); - } - return FALSE; + } + return FALSE; } return FALSE; } @@ -3739,115 +3743,115 @@ prefs_to_capture_opts(void) static void copy_global_profile (const gchar *profile_name) { - char *pf_dir_path, *pf_dir_path2, *pf_filename; + char *pf_dir_path, *pf_dir_path2, *pf_filename; - if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Can't create directory\n\"%s\":\n%s.", - pf_dir_path, g_strerror(errno)); + if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Can't create directory\n\"%s\":\n%s.", + pf_dir_path, g_strerror(errno)); - g_free(pf_dir_path); - } + g_free(pf_dir_path); + } - if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename, - &pf_dir_path, &pf_dir_path2) == -1) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.", - pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno)); + if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename, + &pf_dir_path, &pf_dir_path2) == -1) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.", + pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno)); - g_free(pf_filename); - g_free(pf_dir_path); - g_free(pf_dir_path2); - } + g_free(pf_filename); + g_free(pf_dir_path); + g_free(pf_dir_path2); + } } /* Change configuration profile */ void change_configuration_profile (const gchar *profile_name) { - char *gdp_path, *dp_path; - char *rf_path; - int rf_open_errno; + char *gdp_path, *dp_path; + char *rf_path; + int rf_open_errno; - /* First check if profile exists */ - if (!profile_exists(profile_name, FALSE)) { - if (profile_exists(profile_name, TRUE)) { - /* Copy from global profile */ - copy_global_profile (profile_name); - } else { - /* No personal and no global profile exists */ - return; - } - } + /* First check if profile exists */ + if (!profile_exists(profile_name, FALSE)) { + if (profile_exists(profile_name, TRUE)) { + /* Copy from global profile */ + copy_global_profile (profile_name); + } else { + /* No personal and no global profile exists */ + return; + } + } - /* Then check if changing to another profile */ - if (profile_name && strcmp (profile_name, get_profile_name()) == 0) { - return; - } + /* Then check if changing to another profile */ + if (profile_name && strcmp (profile_name, get_profile_name()) == 0) { + return; + } - /* Get the current geometry, before writing it to disk */ - main_save_window_geometry(top_level); + /* Get the current geometry, before writing it to disk */ + main_save_window_geometry(top_level); - if (profile_exists(get_profile_name(), FALSE)) { - /* Write recent file for profile we are leaving, if it still exists */ - write_profile_recent(); - } + if (profile_exists(get_profile_name(), FALSE)) { + /* Write recent file for profile we are leaving, if it still exists */ + write_profile_recent(); + } - /* Set profile name and update the status bar */ - set_profile_name (profile_name); - profile_bar_update (); - filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY); + /* Set profile name and update the status bar */ + set_profile_name (profile_name); + profile_bar_update (); + filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY); - /* Reset current preferences and apply the new */ - prefs_reset(); - menu_prefs_reset(); + /* Reset current preferences and apply the new */ + prefs_reset(); + menu_prefs_reset(); - (void) read_configuration_files (&gdp_path, &dp_path); + (void) read_configuration_files (&gdp_path, &dp_path); - recent_read_profile_static(&rf_path, &rf_open_errno); - if (rf_path != NULL && rf_open_errno != 0) { - simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, - "Could not open common recent file\n\"%s\": %s.", - rf_path, g_strerror(rf_open_errno)); - } - if (recent.gui_fileopen_remembered_dir && - test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) { - set_last_open_dir(recent.gui_fileopen_remembered_dir); - } - timestamp_set_type (recent.gui_time_format); - timestamp_set_seconds_type (recent.gui_seconds_format); - color_filters_enable(recent.packet_list_colorize); + recent_read_profile_static(&rf_path, &rf_open_errno); + if (rf_path != NULL && rf_open_errno != 0) { + simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, + "Could not open common recent file\n\"%s\": %s.", + rf_path, g_strerror(rf_open_errno)); + } + if (recent.gui_fileopen_remembered_dir && + test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) { + set_last_open_dir(recent.gui_fileopen_remembered_dir); + } + timestamp_set_type (recent.gui_time_format); + timestamp_set_seconds_type (recent.gui_seconds_format); + color_filters_enable(recent.packet_list_colorize); - prefs_to_capture_opts(); - prefs_apply_all(); - macros_post_update(); + prefs_to_capture_opts(); + prefs_apply_all(); + macros_post_update(); - /* Update window view and redraw the toolbar */ - update_main_window_title(); - filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE); - toolbar_redraw_all(); + /* Update window view and redraw the toolbar */ + update_main_window_title(); + filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE); + toolbar_redraw_all(); - /* Enable all protocols and disable from the disabled list */ - proto_enable_all(); - if (gdp_path == NULL && dp_path == NULL) { - set_disabled_protos_list(); - } + /* Enable all protocols and disable from the disabled list */ + proto_enable_all(); + if (gdp_path == NULL && dp_path == NULL) { + set_disabled_protos_list(); + } - /* Reload color filters */ - color_filters_reload(); + /* Reload color filters */ + color_filters_reload(); - /* Reload list of interfaces on welcome page */ - welcome_if_panel_reload(); + /* Reload list of interfaces on welcome page */ + welcome_if_panel_reload(); - /* Recreate the packet list according to new preferences */ - new_packet_list_recreate (); - cfile.cinfo.columns_changed = FALSE; /* Reset value */ - user_font_apply(); + /* Recreate the packet list according to new preferences */ + new_packet_list_recreate (); + cfile.cinfo.columns_changed = FALSE; /* Reset value */ + user_font_apply(); - /* Update menus with new recent values */ - menu_recent_read_finished(); + /* Update menus with new recent values */ + menu_recent_read_finished(); - /* Reload pane geometry, must be done after recreating the list */ - main_pane_load_window_geometry(); + /* Reload pane geometry, must be done after recreating the list */ + main_pane_load_window_geometry(); } /** redissect packets and update UI */ @@ -3856,3 +3860,373 @@ void redissect_packets(void) cf_redissect_packets(&cfile); status_expert_update(); } + +#ifdef HAVE_LIBPCAP +guint get_interface_type(gchar *name, gchar *description) +{ +#if defined(__linux__) + ws_statb64 statb; + char *wireless_path; +#endif +#if defined(_WIN32) + /* + * Much digging failed to reveal any obvious way to get something such + * as the SNMP MIB-II ifType value for an interface: + * + * http://www.iana.org/assignments/ianaiftype-mib + * + * by making some NDIS request. + */ + if (description && (strstr(description,"generic dialup") != NULL || + strstr(description,"PPP/SLIP") != NULL )) { + return IF_DIALUP; + } else if (description && (strstr(description,"Wireless") != NULL || + strstr(description,"802.11") != NULL)) { + return IF_WIRELESS; + } else if (description && strstr(description,"AirPcap") != NULL || + strstr(name,"airpcap")) { + return IF_AIRPCAP; + } else if (description && strstr(description, "Bluetooth") != NULL ) { + return IF_BLUETOOTH; + } +#elif defined(__APPLE__) + /* + * XXX - yes, fetching all the network addresses for an interface + * gets you an AF_LINK address, of type "struct sockaddr_dl", and, + * yes, that includes an SNMP MIB-II ifType value. + * + * However, it's IFT_ETHER, i.e. Ethernet, for AirPort interfaces, + * not IFT_IEEE80211 (which isn't defined in OS X in any case). + * + * Perhaps some other BSD-flavored OSes won't make this mistake; + * however, FreeBSD 7.0 and OpenBSD 4.2, at least, appear to have + * made the same mistake, at least for my Belkin ZyDAS stick. + * + * On Mac OS X, one might be able to get the information one wants from + * IOKit. + */ + if (strcmp(name, "en1") == 0) { + return IF_WIRELESS; + } + /* + * XXX - PPP devices have names beginning with "ppp" and an IFT_ of + * IFT_PPP, but they could be dial-up, or PPPoE, or mobile phone modem, + * or VPN, or... devices. One might have to dive into the bowels of + * IOKit to find out. + */ + + /* + * XXX - there's currently no support for raw Bluetooth capture, + * and IP-over-Bluetooth devices just look like fake Ethernet + * devices. There's also Bluetooth modem support, but that'll + * probably just give you a device that looks like a PPP device. + */ +#elif defined(__linux__) + /* + * Look for /sys/class/net/{device}/wireless. + */ + wireless_path = g_strdup_printf("/sys/class/net/%s/wireless", name); + if (wireless_path != NULL) { + if (ws_stat64(wireless_path, &statb) == 0) { + g_free(wireless_path); + return IF_WIRELESS; + } + } + /* + * Bluetooth devices. + * + * XXX - this is for raw Bluetooth capture; what about IP-over-Bluetooth + * devices? + */ + if ( strstr(name,"bluetooth") != NULL) { + return IF_BLUETOOTH; + } + + /* + * USB devices. + */ + if ( strstr(name,"usbmon") != NULL ) { + return IF_USB; + } +#endif + /* + * Bridge, NAT, or host-only interfaces on VMWare hosts have the name + * vmnet[0-9]+ or VMnet[0-9+ on Windows. Guests might use a native + * (LANCE or E1000) driver or the vmxnet driver. These devices have an + * IFT_ of IFT_ETHER, so we have to check the name. + */ + if ( g_ascii_strncasecmp(name, "vmnet", 5) == 0) { + return IF_VIRTUAL; + } + + if ( g_ascii_strncasecmp(name, "vmxnet", 6) == 0) { + return IF_VIRTUAL; + } + + if (description && strstr(description, "VMware") != NULL ) { + return IF_VIRTUAL; + } + + return IF_WIRED; +} + +void +scan_local_interfaces(capture_options* capture_opts, int *error) +{ + GList *if_entry, *lt_entry, *if_list; + if_info_t *if_info, *temp; + char *if_string=""; + gchar *descr, *str, *err_str = NULL; + if_capabilities_t *caps=NULL; + gint linktype_count; + cap_settings_t cap_settings; + GSList *curr_addr; + int ips = 0, i, err; + guint count = 0, j; + if_addr_t *addr, *temp_addr; + link_row *link = NULL; + data_link_info_t *data_link_info; + interface_t device; + GString *ip_str; + interface_options interface_opts; + gboolean found = FALSE; + + + if (capture_opts->all_ifaces->len > 0) { + for (i = (int)capture_opts->all_ifaces->len-1; i >= 0; i--) { + device = g_array_index(capture_opts->all_ifaces, interface_t, i); + if (device.local) { + capture_opts->all_ifaces = g_array_remove_index(capture_opts->all_ifaces, i); + } + } + } + /* Scan through the list and build a list of strings to display. */ + if_list = capture_interface_list(&err, &err_str); + *error = err; + count = 0; + for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) { + if_info = if_entry->data; + ip_str = g_string_new(""); + str = ""; + ips = 0; + device.name = g_strdup(if_info->name); + device.hidden = FALSE; + device.locked = FALSE; + temp = g_malloc0(sizeof(if_info_t)); + temp->name = g_strdup(if_info->name); + temp->description = g_strdup(if_info->description); + temp->loopback = if_info->loopback; + /* Is this interface hidden and, if so, should we include it anyway? */ + + /* Do we have a user-supplied description? */ + descr = capture_dev_user_descr_find(if_info->name); + if (descr != NULL) { + /* Yes, we have a user-supplied description; use it. */ + if_string = g_strdup_printf("%s: %s", descr, if_info->name); + g_free(descr); + } else { + /* No, we don't have a user-supplied description; did we get + one from the OS or libpcap? */ + if (if_info->description != NULL) { + /* Yes - use it. */ + if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name); + } else { + /* No. */ + if_string = g_strdup(if_info->name); + } + } + if (if_info->loopback) { + device.display_name = g_strdup_printf("%s (loopback)", if_string); + } else { + device.display_name = g_strdup(if_string); + } + device.selected = FALSE; + if (prefs_is_capture_device_hidden(if_info->name)) { + device.hidden = TRUE; + } + device.type = get_interface_type(if_info->name, if_info->description); + cap_settings = capture_get_cap_settings(if_info->name); + caps = capture_get_if_capabilities(if_info->name, cap_settings.monitor_mode, NULL); + for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) { + temp_addr = g_malloc0(sizeof(if_addr_t)); + if (ips != 0) { + g_string_append(ip_str, "\n"); + } + addr = (if_addr_t *)curr_addr->data; + if (addr) { + temp_addr->ifat_type = addr->ifat_type; + switch (addr->ifat_type) { + case IF_AT_IPv4: + temp_addr->addr.ip4_addr = addr->addr.ip4_addr; + g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr)); + break; + case IF_AT_IPv6: + memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr)); + g_string_append(ip_str, ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr)); + break; + default: + /* In case we add non-IP addresses */ + break; + } + } else { + g_free(temp_addr); + temp_addr = NULL; + } + if (temp_addr) { + temp->addrs = g_slist_append(temp->addrs, temp_addr); + } + } +#ifdef HAVE_PCAP_REMOTE + device.remote_opts.src_type = CAPTURE_IFLOCAL; +#endif + linktype_count = 0; + device.links = NULL; + if (caps != NULL) { +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + device.monitor_mode_enabled = cap_settings.monitor_mode; + device.monitor_mode_supported = caps->can_set_rfmon; +#endif + 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) { + str = g_strdup_printf("%s", data_link_info->description); + } else { + str = g_strdup_printf("%s (not supported)", data_link_info->name); + } + if (linktype_count == 0) { + device.active_dlt = data_link_info->dlt; + } + link = (link_row *)g_malloc(sizeof(link_row)); + link->dlt = data_link_info->dlt; + link->name = g_strdup(str); + device.links = g_list_append(device.links, link); + linktype_count++; + } + } else { + cap_settings.monitor_mode = FALSE; +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + device.monitor_mode_enabled = FALSE; + device.monitor_mode_supported = FALSE; +#endif + device.active_dlt = -1; + } + device.addresses = g_strdup(ip_str->str); + device.no_addresses = ips; + device.local = TRUE; + device.if_info = *temp; + device.last_packets = 0; + device.pmode = capture_opts->default_options.promisc_mode; + device.has_snaplen = capture_opts->default_options.has_snaplen; + device.snaplen = capture_opts->default_options.snaplen; + device.cfilter = g_strdup(capture_opts->default_options.cfilter); +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + device.buffer = 1; +#endif + + if (capture_opts->ifaces->len > 0) { + for (j = 0; j < capture_opts->ifaces->len; j++) { + interface_opts = g_array_index(capture_opts->ifaces, interface_options, j); + if (strcmp(interface_opts.name, device.name) == 0) { +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + device.buffer = interface_opts.buffer_size; + device.monitor_mode_enabled = interface_opts.monitor_mode; +#endif + device.pmode = interface_opts.promisc_mode; + device.has_snaplen = interface_opts.has_snaplen; + device.snaplen = interface_opts.snaplen; + device.cfilter = g_strdup(interface_opts.cfilter); + device.active_dlt = interface_opts.linktype; + device.selected = TRUE; + capture_opts->num_selected++; + break; + } + } + } + if (capture_opts->all_ifaces->len <= count) { + g_array_append_val(capture_opts->all_ifaces, device); + count = capture_opts->all_ifaces->len; + } else { + g_array_insert_val(capture_opts->all_ifaces, count, device); + } + if (caps != NULL) { + free_if_capabilities(caps); + } + + g_string_free(ip_str, TRUE); + count++; + } + free_interface_list(if_list); + /* see whether there are additional interfaces in ifaces */ + for (j = 0; j < capture_opts->ifaces->len; j++) { + interface_opts = g_array_index(capture_opts->ifaces, interface_options, j); + found = FALSE; + for (i = 0; i < (int)capture_opts->all_ifaces->len; i++) { + device = g_array_index(capture_opts->all_ifaces, interface_t, i); + if (strcmp(device.name, interface_opts.name) == 0) { + found = TRUE; + break; + } + } + if (!found) { /* new interface, maybe a pipe */ + device.name = g_strdup(interface_opts.name); + device.display_name = g_strdup_printf("%s", device.name); + device.hidden = FALSE; + device.selected = TRUE; + device.type = IF_PIPE; +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + device.buffer = interface_opts.buffer_size; + device.monitor_mode_enabled = interface_opts.monitor_mode; + device.monitor_mode_supported = FALSE; +#endif + device.pmode = interface_opts.promisc_mode; + device.has_snaplen = interface_opts.has_snaplen; + device.snaplen = interface_opts.snaplen; + device.cfilter = g_strdup(interface_opts.cfilter); + device.active_dlt = interface_opts.linktype; + device.addresses = NULL; + device.no_addresses = 0; + device.last_packets = 0; + device.links = NULL; + device.local = TRUE; + device.locked = FALSE; + + g_array_append_val(capture_opts->all_ifaces, device); + capture_opts->num_selected++; + } + } +} + +void hide_interface(gchar* new_hide) +{ + gchar *tok; + guint i; + interface_t device; + gboolean found = FALSE; + GList *hidden_devices = NULL, *entry; + if (new_hide != NULL) { + for (tok = strtok (new_hide, ","); tok; tok = strtok(NULL, ",")) { + hidden_devices = g_list_append(hidden_devices, tok); + } + } + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + found = FALSE; + for (entry = hidden_devices; entry != NULL; entry = g_list_next(entry)) { + if (strcmp(entry->data, device.name)==0) { + device.hidden = TRUE; + if (device.selected) { + device.selected = FALSE; + global_capture_opts.num_selected--; + } + found = TRUE; + break; + } + } + if (!found) { + device.hidden = FALSE; + } + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); + } +} +#endif diff --git a/ui/gtk/main.h b/ui/gtk/main.h index 47a6599b06..e86d1c0f0f 100644 --- a/ui/gtk/main.h +++ b/ui/gtk/main.h @@ -26,6 +26,7 @@ #define __MAIN_H__ #include "globals.h" +#include "capture_opts.h" /** @defgroup main_window_group Main window * The main window has the following submodules: @@ -332,10 +333,10 @@ extern gboolean main_filter_packets(capture_file *cf, const gchar *dftext, #ifdef _WIN32 /** Win32 only: Create a console. Beware: cannot be closed again. */ extern void create_console(void); -#endif /** Restart the tap update display timer with new configured interval */ extern void reset_tap_update_timer(void); +#endif /** Fill in capture options with values from the preferences */ extern void prefs_to_capture_opts(void); @@ -351,4 +352,7 @@ extern GList *get_ip_address_list_from_packet_list_row(gpointer data); extern GtkWidget *pkt_scrollw; +void hide_interface(gchar* new_hide); + + #endif /* __MAIN_H__ */ diff --git a/ui/gtk/main_welcome.c b/ui/gtk/main_welcome.c index 1983a874b8..166e1b9cb6 100644 --- a/ui/gtk/main_welcome.c +++ b/ui/gtk/main_welcome.c @@ -86,8 +86,6 @@ #endif /* XXX */ -extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg); - static GtkWidget *welcome_hb = NULL; static GtkWidget *header_lb = NULL; /* Foreground colors are set using Pango markup */ @@ -108,10 +106,8 @@ static GdkColor topic_item_entered_bg = { 0, 0xd3d3, 0xd8d8, 0xdada }; #endif static GtkWidget *welcome_file_panel_vb = NULL; #ifdef HAVE_LIBPCAP -static GtkWidget *welcome_if_panel_vb = NULL; static GtkWidget *if_view = NULL; static GtkWidget *swindow; -static GArray *interfaces = NULL; #endif static GSList *status_messages = NULL; @@ -214,9 +210,9 @@ static gboolean welcome_item_enter_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_) { #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_entered_bg); + gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_entered_bg); #else - gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_entered_bg); + gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_entered_bg); #endif return FALSE; } @@ -227,7 +223,7 @@ static gboolean welcome_item_leave_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_) { #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg); + gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg); #else gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg); #endif @@ -254,12 +250,12 @@ welcome_button(const gchar *stock_item, eb = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(eb), item_hb); #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg); + gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg); #else gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg); #endif if(tooltip != NULL) { - gtk_widget_set_tooltip_text(eb, tooltip); + gtk_widget_set_tooltip_text(eb, tooltip); } g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), NULL); @@ -352,7 +348,7 @@ welcome_header_new(void) eb = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(eb), item_vb); #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_header_bar_bg); + gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_header_bar_bg); #else gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &header_bar_bg); #endif @@ -360,7 +356,7 @@ welcome_header_new(void) gtk_box_pack_start(GTK_BOX(item_vb), item_hb, FALSE, FALSE, 10); /*icon = xpm_to_widget_from_parent(top_level, wssplash_xpm);*/ - icon = xpm_to_widget(wssplash_xpm); + icon = xpm_to_widget(wssplash_xpm); gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 10); header_lb = gtk_label_new(NULL); @@ -426,7 +422,7 @@ welcome_topic_header_new(const char *header) eb = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(eb), w); #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_header_bg); + gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_header_bg); #else gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_header_bg); #endif @@ -457,7 +453,7 @@ welcome_topic_new(const char *header, GtkWidget **to_fill) topic_eb = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(topic_eb), topic_vb); #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(topic_eb, GTK_STATE_NORMAL, &rgba_topic_content_bg); + gtk_widget_override_background_color(topic_eb, GTK_STATE_NORMAL, &rgba_topic_content_bg); #else gtk_widget_modify_bg(topic_eb, GTK_STATE_NORMAL, &topic_content_bg); #endif @@ -572,16 +568,16 @@ static void welcome_filename_destroy_cb(GtkWidget *w _U_, gpointer data) { g_mutex_lock(recent_mtx); if (ri_stat->timer) { - g_source_remove(ri_stat->timer); - ri_stat->timer = 0; + g_source_remove(ri_stat->timer); + ri_stat->timer = 0; } g_object_unref(ri_stat->menu_item); if (ri_stat->stat_done) { - g_free(ri_stat->filename); - g_string_free(ri_stat->str, TRUE); - g_free(ri_stat); + g_free(ri_stat->filename); + g_string_free(ri_stat->str, TRUE); + g_free(ri_stat); } else { ri_stat->label = NULL; } @@ -709,22 +705,22 @@ static gboolean select_current_ifaces(GtkTreeModel *model, { guint i; gchar *if_name; - gboolean found = FALSE; + interface_t device; GtkTreeSelection *selection = (GtkTreeSelection *)userdata; + device.name = NULL; gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1); - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) { - if (!gtk_tree_selection_path_is_selected(selection, path)) { - gtk_tree_selection_select_iter(selection, iter); + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (strcmp(device.name, if_name) == 0) { + if (device.selected && !gtk_tree_selection_path_is_selected(selection, path)) { + gtk_tree_selection_select_iter(selection, iter); + } else { + gtk_tree_selection_unselect_iter(selection, iter); } - found = TRUE; break; } } - if (!found) { - gtk_tree_selection_unselect_iter(selection, iter); - } return FALSE; } @@ -736,127 +732,69 @@ gboolean on_selection_changed(GtkTreeSelection *selection _U_, { GtkTreeIter iter; gchar *if_name; - interface_options interface_opts; - guint i, j; - cap_settings_t cap_settings; - gboolean found = FALSE; - displayed_interface d_interface; - - d_interface.name = NULL; - d_interface.descr = NULL; + guint i; + interface_t device; + gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, IFACE_NAME, &if_name, -1); - if (global_capture_opts.ifaces->len > 0) { - for (i = 0; i < global_capture_opts.ifaces->len; i++) { - if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) { - found = TRUE; + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (strcmp(device.name, if_name) == 0) { + if (!device.locked) { if (path_currently_selected) { - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); - global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i); - if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && interfaces_dialog_window_present()) { - update_selected_interface(g_strdup(interface_opts.name), FALSE); + if (device.selected) { + device.selected = FALSE; + device.locked = TRUE; + global_capture_opts.num_selected--; } - if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && dlg_window_present()) { - enable_selected_interface(interface_opts.name, FALSE); - } - g_free(interface_opts.name); - g_free(interface_opts.descr); - g_free(interface_opts.cfilter); -#ifdef HAVE_PCAP_REMOTE - g_free(interface_opts.remote_host); - g_free(interface_opts.remote_port); - g_free(interface_opts.auth_username); - g_free(interface_opts.auth_password); -#endif - break; - } - } - } - } - if (!found && !path_currently_selected) { - for (j = 0; j < interfaces->len; j++) { - d_interface = g_array_index(interfaces, displayed_interface, j); - if (strcmp(d_interface.name, if_name) == 0) { - interface_opts.name = g_strdup(d_interface.name); - interface_opts.descr = g_strdup(d_interface.descr); - interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name); - interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter); - interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen; - interface_opts.snaplen = global_capture_opts.default_options.snaplen; - cap_settings = capture_get_cap_settings (interface_opts.name);; - interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode; -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = global_capture_opts.default_options.buffer_size; -#endif - interface_opts.monitor_mode = cap_settings.monitor_mode; -#ifdef HAVE_PCAP_REMOTE - if (d_interface.remote_opts.src_type == CAPTURE_IFREMOTE) { - interface_opts.src_type = d_interface.remote_opts.src_type; - interface_opts.remote_host = g_strdup(d_interface.remote_opts.remote_host_opts.remote_host); - interface_opts.remote_port = g_strdup(d_interface.remote_opts.remote_host_opts.remote_port); - interface_opts.auth_type = d_interface.remote_opts.remote_host_opts.auth_type; - interface_opts.auth_username = g_strdup(d_interface.remote_opts.remote_host_opts.auth_username); - interface_opts.auth_password = g_strdup(d_interface.remote_opts.remote_host_opts.auth_password); - interface_opts.datatx_udp = d_interface.remote_opts.remote_host_opts.datatx_udp; - interface_opts.nocap_rpcap = d_interface.remote_opts.remote_host_opts.nocap_rpcap; - interface_opts.nocap_local = d_interface.remote_opts.remote_host_opts.nocap_local; -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = d_interface.remote_opts.sampling_method; - interface_opts.sampling_param = d_interface.remote_opts.sampling_param; -#endif } else { - interface_opts.src_type = global_capture_opts.default_options.src_type; - interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); - interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); - interface_opts.auth_type = global_capture_opts.default_options.auth_type; - interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); - interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); - interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; - interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; - interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; - interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; -#endif + if (!device.selected) { + device.selected = TRUE; + device.locked = TRUE; + global_capture_opts.num_selected++; + } } -#endif + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); - g_array_append_val(global_capture_opts.ifaces, interface_opts); - if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && interfaces_dialog_window_present()) { - update_selected_interface(g_strdup(interface_opts.name), TRUE); + if (dlg_window_present()) { + enable_selected_interface(g_strdup(if_name), device.selected); } - if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && dlg_window_present()) { - enable_selected_interface(interface_opts.name, TRUE); + if (interfaces_dialog_window_present()) { + update_selected_interface(g_strdup(if_name)); } - break; + device.locked = FALSE; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); } + break; } } return TRUE; } static gboolean activate_ifaces(GtkTreeModel *model, - GtkTreePath *path _U_, - GtkTreeIter *iter, - gpointer userdata) + GtkTreePath *path _U_, + GtkTreeIter *iter, + gpointer userdata) { - gchar *if_name; - GtkWidget *view; - GtkTreeSelection *selection; - selected_name_t *entry = (selected_name_t *)userdata; + gchar *if_name; + GtkWidget *view; + GtkTreeSelection *selection; + selected_name_t *entry = (selected_name_t *)userdata; - view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); - gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1); - if (strcmp(if_name, entry->name) == 0) { - if (entry->activate) { - gtk_tree_selection_select_iter(selection, iter); - } else { - gtk_tree_selection_unselect_iter(selection, iter); + view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1); + if (strcmp(if_name, entry->name) == 0) { + if (entry->activate) { + gtk_tree_selection_select_iter(selection, iter); + } else { + gtk_tree_selection_unselect_iter(selection, iter); + } + return TRUE; } - return TRUE; - } - return FALSE; + return FALSE; } void change_interface_selection(gchar* name, gboolean activate) @@ -874,13 +812,11 @@ void change_interface_selection(gchar* name, gboolean activate) void change_selection_for_all(gboolean enable) { - guint i; + guint i; - if (interfaces) { - for (i = 0; i < interfaces->len; i++) { - change_interface_selection(g_array_index(interfaces, displayed_interface, i).name, enable); + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + change_interface_selection(g_array_index(global_capture_opts.all_ifaces, interface_t, i).name, enable); } - } } #endif @@ -892,7 +828,7 @@ select_ifaces(void) GtkTreeModel *model; GtkTreeSelection *entry; - if (global_capture_opts.ifaces->len > 0 && swindow) { + if (global_capture_opts.num_selected > 0 && swindow) { view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); @@ -904,40 +840,24 @@ select_ifaces(void) #ifdef HAVE_PCAP_REMOTE void -add_interface_to_list(gchar *name, gchar *descr, remote_options *remote_opts) +add_interface_to_list(guint index) { GtkWidget *view, *icon; GtkTreeModel *model; GtkTreeIter iter; gint size; gchar *lines; - displayed_interface d_interface; + interface_t device; - d_interface.name = g_strdup(name); - d_interface.descr = g_strdup(descr); - d_interface.remote_opts.src_type = remote_opts->src_type; - d_interface.remote_opts.remote_host_opts.remote_host = g_strdup(remote_opts->remote_host_opts.remote_host); - d_interface.remote_opts.remote_host_opts.remote_port = g_strdup(remote_opts->remote_host_opts.remote_port); - d_interface.remote_opts.remote_host_opts.auth_type = remote_opts->remote_host_opts.auth_type; - d_interface.remote_opts.remote_host_opts.auth_username = g_strdup(remote_opts->remote_host_opts.auth_username); - d_interface.remote_opts.remote_host_opts.auth_password = g_strdup(remote_opts->remote_host_opts.auth_password); - d_interface.remote_opts.remote_host_opts.datatx_udp = remote_opts->remote_host_opts.datatx_udp; - d_interface.remote_opts.remote_host_opts.nocap_rpcap = remote_opts->remote_host_opts.nocap_rpcap; - d_interface.remote_opts.remote_host_opts.nocap_local = remote_opts->remote_host_opts.nocap_local; -#ifdef HAVE_PCAP_SETSAMPLING - d_interface.remote_opts.sampling_method = remote_opts->sampling_method; - d_interface.remote_opts.sampling_param = remote_opts->sampling_param; -#endif + device = g_array_index(global_capture_opts.all_ifaces, interface_t, index); icon = pixbuf_to_widget(remote_sat_pb_data); - d_interface.icon = icon; view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); size = gtk_tree_model_iter_n_children(model, NULL); lines = g_strdup_printf("%d", size-1); - g_array_append_val(interfaces, d_interface); if (gtk_tree_model_get_iter_from_string(model, &iter, lines)) { gtk_list_store_append (GTK_LIST_STORE(model), &iter); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, descr, IFACE_NAME, name, -1); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, device.display_name, IFACE_NAME, device.name, -1); } } #endif @@ -947,92 +867,41 @@ void welcome_if_tree_load(void) { #ifdef HAVE_LIBPCAP - if_info_t *if_info; - GList *if_list; - int err; guint i; - gchar *err_str = NULL; - GList *curr; - gchar *user_descr; GtkListStore *store = NULL; GtkTreeIter iter; - GtkWidget *icon, *view; + GtkWidget *view; GtkTreeSelection *entry; - displayed_interface d_interface; + interface_t device; + gboolean changed = FALSE; + int error; view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); gtk_tree_selection_unselect_all(entry); store = gtk_list_store_new(NUMCOLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + gtk_list_store_clear(store); + gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store)); /* LOAD THE INTERFACES */ - if (interfaces && interfaces->len > 0) { - for (i = 0; i < interfaces->len; i++) { - d_interface = g_array_index(interfaces, displayed_interface, i); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, ICON, d_interface.icon, IFACE_DESCR, d_interface.descr, IFACE_NAME, d_interface.name, -1); - } + if (global_capture_opts.all_ifaces->len == 0) { + scan_local_interfaces(&global_capture_opts, &error); } else { - interfaces = g_array_new(TRUE, TRUE, sizeof(displayed_interface)); - if_list = capture_interface_list(&err, &err_str); - if_list = g_list_sort (if_list, if_list_comparator_alph); - if (if_list == NULL && - (err == CANT_GET_INTERFACE_LIST || err == DONT_HAVE_PCAP)) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - return; - } else if (err_str) { - g_free(err_str); - } - if (g_list_length(if_list) > 0) { - /* List the interfaces */ - for (curr = g_list_first(if_list); curr; curr = g_list_next(curr)) { - if_info = curr->data; - /* Continue if capture device is hidden */ - if (prefs_is_capture_device_hidden(if_info->name)) { - continue; - } + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + if (!device.hidden) { gtk_list_store_append (store, &iter); - d_interface.name = g_strdup(if_info->name); -#ifdef HAVE_PCAP_REMOTE - d_interface.remote_opts.src_type = CAPTURE_IFLOCAL; -#endif -#ifdef HAVE_AIRPCAP - if (get_airpcap_if_from_name(airpcap_if_list,if_info->name) != NULL) - icon = xpm_to_widget(capture_airpcap_16_xpm); - else - icon = capture_get_if_icon(if_info); -#else - icon = capture_get_if_icon(if_info); -#endif - d_interface.icon = icon; - user_descr = capture_dev_user_descr_find(if_info->name); - if (user_descr) { -#ifndef _WIN32 - gchar *comment = user_descr; - user_descr = g_strdup_printf("%s (%s)", comment, if_info->name); - g_free (comment); -#endif - gtk_list_store_set(store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, user_descr, IFACE_NAME, if_info->name, -1); - d_interface.descr = g_strdup(user_descr); - g_free (user_descr); - } else if (if_info->description) { - gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, if_info->description, IFACE_NAME, if_info->name, -1); - d_interface.descr = g_strdup(if_info->description); - } else { - gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, if_info->name, IFACE_NAME, if_info->name, -1); - d_interface.descr = g_strdup(if_info->name); + gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(capture_get_if_icon(&device))), IFACE_DESCR, device.display_name, IFACE_NAME, device.name, -1); + if (device.selected) { + gtk_tree_selection_select_iter(entry, &iter); } - g_array_append_val(interfaces, d_interface); - } + } } - free_interface_list(if_list); - gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store)); - if (global_capture_opts.ifaces->len > 0) { - gtk_tree_model_foreach(GTK_TREE_MODEL(store), select_current_ifaces, (gpointer) entry); - gtk_widget_grab_focus(view); - } - gtk_tree_selection_set_select_function(entry, on_selection_changed, NULL, NULL); + changed = TRUE; + } + gtk_tree_selection_set_select_function(entry, on_selection_changed, (gpointer)&changed, NULL); + if (gtk_widget_is_focus(view) && dlg_window_present()) { + update_all_rows(); } #endif /* HAVE_LIBPCAP */ } @@ -1043,23 +912,9 @@ void welcome_if_panel_reload(void) { #ifdef HAVE_LIBPCAP - GtkWidget *child_box; - GList* child_list; - GList* child_list_item; - - if(welcome_if_panel_vb) { - child_box = scroll_box_dynamic_reset(welcome_if_panel_vb); - child_list = gtk_container_get_children(GTK_CONTAINER(child_box)); - child_list_item = child_list; - - while(child_list_item) { - gtk_container_remove(GTK_CONTAINER(child_box), child_list_item->data); - child_list_item = g_list_next(child_list_item); - } - - g_list_free(child_list); + if (welcome_hb) { welcome_if_tree_load(); - gtk_widget_show_all(welcome_if_panel_vb); + gtk_widget_show_all(welcome_hb); } #endif /* HAVE_LIBPCAP */ } @@ -1068,27 +923,32 @@ welcome_if_panel_reload(void) static void capture_if_start(GtkWidget *w _U_, gpointer data _U_) { #ifdef HAVE_AIRPCAP - interface_options interface_opts; + interface_t device; + guint i; #endif + if (global_capture_opts.num_selected == 0) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "You didn't specify an interface on which to capture packets."); + return; + } - if (global_capture_opts.ifaces->len == 0) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "You didn't specify an interface on which to capture packets."); - return; - } - - /* XXX - remove this? */ - if (global_capture_opts.save_file) { - g_free(global_capture_opts.save_file); - global_capture_opts.save_file = NULL; - } -#ifdef HAVE_AIRPCAP - interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, 0); - airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, interface_opts.name); - airpcap_if_selected = airpcap_if_active; - airpcap_set_toolbar_start_capture(airpcap_if_active); + /* XXX - remove this? */ + if (global_capture_opts.save_file) { + g_free(global_capture_opts.save_file); + global_capture_opts.save_file = NULL; + } +#ifdef HAVE_AIRPCAP /* TODO: don't let it depend on interface_opts */ + for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, device.name); + airpcap_if_selected = airpcap_if_active; + if (airpcap_if_selected) { + break; + } + } + airpcap_set_toolbar_start_capture(airpcap_if_active); #endif - capture_start_cb(NULL, NULL); + capture_start_cb(NULL, NULL); } #endif @@ -1097,7 +957,7 @@ static void capture_if_start(GtkWidget *w _U_, gpointer data _U_) static gboolean activate_link_cb(GtkLabel *label _U_, gchar *uri, gpointer user_data _U_) { - return browser_open_url(uri); + return browser_open_url(uri); } #endif #endif @@ -1116,7 +976,8 @@ welcome_new(void) GtkWidget *topic_vb; GtkWidget *topic_to_fill; GtkWidget *file_child_box; - gchar *label_text; + gchar *label_text; + int error; #ifdef _WIN32 LONG reg_ret; DWORD chimney_enabled = 0; @@ -1126,9 +987,6 @@ welcome_new(void) GtkTreeSelection *selection; GtkCellRenderer *renderer; GtkTreeViewColumn *column; - GList *if_list; - int err; - gchar *err_str = NULL; #endif /* prepare colors */ @@ -1153,7 +1011,7 @@ welcome_new(void) topic_item_idle_bg = topic_content_bg; #endif #if 0 - /* Allocating collor isn't necessary? */ + /* Allocating collor isn't necessary? */ /* topic item entered color */ get_color(&topic_item_entered_bg); #endif @@ -1164,9 +1022,9 @@ welcome_new(void) welcome_eb = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(welcome_eb), welcome_vb); #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(welcome_eb, GTK_STATE_NORMAL, &rgba_welcome_bg); + gtk_widget_override_background_color(welcome_eb, GTK_STATE_NORMAL, &rgba_welcome_bg); #else - gtk_widget_modify_bg(welcome_eb, GTK_STATE_NORMAL, &welcome_bg); + gtk_widget_modify_bg(welcome_eb, GTK_STATE_NORMAL, &welcome_bg); #endif /* header */ header = welcome_header_new(); @@ -1181,7 +1039,7 @@ welcome_new(void) /* column capture */ column_vb = gtk_vbox_new(FALSE, 10); #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_background_color(column_vb, GTK_STATE_NORMAL, &rgba_welcome_bg); + gtk_widget_override_background_color(column_vb, GTK_STATE_NORMAL, &rgba_welcome_bg); #else gtk_widget_modify_bg(column_vb, GTK_STATE_NORMAL, &welcome_bg); #endif @@ -1192,8 +1050,10 @@ welcome_new(void) gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0); #ifdef HAVE_LIBPCAP - if_list = capture_interface_list(&err, &err_str); - if (g_list_length(if_list) > 0) { + if (global_capture_opts.all_ifaces->len == 0) { + scan_local_interfaces(&global_capture_opts, &error); + } + if (global_capture_opts.all_ifaces->len > 0) { item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_INTERFACES, "Interface List", "Live list of the capture interfaces\n(counts incoming packets)", @@ -1210,17 +1070,13 @@ welcome_new(void) g_object_set(G_OBJECT(if_view), "headers-visible", FALSE, NULL); g_signal_connect(if_view, "row-activated", G_CALLBACK(options_interface_cb), (gpointer)welcome_hb); g_object_set_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES, if_view); + column = gtk_tree_view_column_new(); renderer = gtk_cell_renderer_pixbuf_new(); - column = gtk_tree_view_column_new_with_attributes ("", - GTK_CELL_RENDERER(renderer), - "pixbuf", ICON, - NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column); + gtk_tree_view_column_pack_start(column, renderer, FALSE); + gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", ICON, NULL); renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes ("", - GTK_CELL_RENDERER(renderer), - "text", IFACE_DESCR, - NULL); + gtk_tree_view_column_pack_start(column, renderer, TRUE); + gtk_tree_view_column_set_attributes(column, renderer, "text", IFACE_DESCR, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column); gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(if_view), 0), TRUE); renderer = gtk_cell_renderer_text_new(); @@ -1263,9 +1119,8 @@ welcome_new(void) } #endif /* _WIN32 */ } else { - if (if_list == NULL && err != NO_INTERFACES_FOUND) { - g_free(err_str); - if (err == CANT_GET_INTERFACE_LIST) { + if (error != NO_INTERFACES_FOUND) { + if (error == CANT_GET_INTERFACE_LIST) { label_text = g_strdup("No interface can be used for capturing in " "this system with the current configuration.\n" "\n" @@ -1318,8 +1173,6 @@ welcome_new(void) #endif } - free_interface_list(if_list); - /* capture help topic */ topic_vb = welcome_topic_new("Capture Help", &topic_to_fill); gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0); @@ -1460,12 +1313,7 @@ welcome_new(void) GtkWidget* get_welcome_window(void) { - return welcome_hb; + return welcome_hb; } -#ifdef HAVE_LIBPCAP -displayed_interface get_interface_data(gint index) -{ - return g_array_index(interfaces, displayed_interface, index); -} -#endif + diff --git a/ui/gtk/main_welcome.h b/ui/gtk/main_welcome.h index 23996e3723..296a53796d 100644 --- a/ui/gtk/main_welcome.h +++ b/ui/gtk/main_welcome.h @@ -40,15 +40,6 @@ typedef struct selected_name_s { gboolean activate; } selected_name_t; -typedef struct displayed_interface_s { - gchar *name; - gchar *descr; - GtkWidget *icon; -#ifdef HAVE_PCAP_REMOTE - remote_options remote_opts; -#endif -} displayed_interface; - GtkWidget *welcome_new(void); /* reset the list of recently used files */ @@ -60,6 +51,8 @@ void main_welcome_add_recent_capture_file(const char *widget_cf_name, GObject *m /* reload the list of interfaces */ void welcome_if_panel_reload(void); +void welcome_if_tree_load(void); + /** Push a status message into the welcome screen header similar to * statusbar_push_*_msg(). This hides everything under the header. * If msg is dynamically allocated, it is up to the caller to free @@ -85,10 +78,10 @@ void change_interface_selection(gchar* name, gboolean activate); void change_selection_for_all(gboolean enable); +void update_welcome_list(void); + #ifdef HAVE_PCAP_REMOTE -void add_interface_to_list(gchar *name, gchar *descr, remote_options *remote_opts); +void add_interface_to_list(guint index); #endif -displayed_interface get_interface_data(gint index); - #endif /* __MAIN_WELCOME_H__ */ diff --git a/ui/gtk/prefs_capture.c b/ui/gtk/prefs_capture.c index 07e8dbfa44..9553aed30c 100644 --- a/ui/gtk/prefs_capture.c +++ b/ui/gtk/prefs_capture.c @@ -1424,6 +1424,7 @@ ifopts_write_new_hide(void) g_free(new_hide); prefs.capture_devices_hide = NULL; } + hide_interface(g_strdup(new_hide)); } } diff --git a/ui/gtk/prefs_taps.c b/ui/gtk/prefs_taps.c index d3eba4718e..321e928301 100644 --- a/ui/gtk/prefs_taps.c +++ b/ui/gtk/prefs_taps.c @@ -124,7 +124,9 @@ stats_prefs_fetch(GtkWidget *w _U_) void stats_prefs_apply(GtkWidget *w _U_) { +#if defined(_WIN32) reset_tap_update_timer(); +#endif } void