diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | capture-pcap-util.c | 11 | ||||
-rw-r--r-- | capture_ifinfo.c | 10 | ||||
-rw-r--r-- | capture_ifinfo.h | 3 | ||||
-rw-r--r-- | capture_opts.c | 220 | ||||
-rw-r--r-- | capture_opts.h | 4 | ||||
-rw-r--r-- | capture_ui_utils.c | 5 | ||||
-rw-r--r-- | capture_win_ifnames.c | 319 | ||||
-rw-r--r-- | capture_win_ifnames.h | 31 | ||||
-rw-r--r-- | dumpcap.c | 53 | ||||
-rw-r--r-- | tshark.c | 3 | ||||
-rw-r--r-- | ui/gtk/capture_dlg.c | 144 | ||||
-rw-r--r-- | ui/gtk/capture_if_details_dlg_win32.c | 14 | ||||
-rw-r--r-- | ui/gtk/capture_if_dlg.c | 36 | ||||
-rw-r--r-- | ui/gtk/main_welcome.c | 61 | ||||
-rw-r--r-- | ui/iface_lists.c | 18 |
17 files changed, 728 insertions, 208 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index cd4cd021c3..bf42e44620 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -592,7 +592,7 @@ endif() if(WIN32) set(PLATFORM_SRC - capture-wpcap.c capture_wpcap_packet.c + capture-wpcap.c capture_wpcap_packet.c capture_win_ifnames.c ) endif() diff --git a/Makefile.am b/Makefile.am index 6dd55d7218..23172d3989 100644 --- a/Makefile.am +++ b/Makefile.am @@ -585,6 +585,8 @@ EXTRA_DIST = \ adns_dll.rc \ autogen.sh \ capinfos.c \ + capture_win_ifnames.c \ + capture_win_ifnames.h \ capture-wpcap.c \ capture-wpcap.h \ capture_wpcap_packet.c \ diff --git a/capture-pcap-util.c b/capture-pcap-util.c index 4ed06b38ad..3658513b0e 100644 --- a/capture-pcap-util.c +++ b/capture-pcap-util.c @@ -52,6 +52,10 @@ #include <netinet/in.h> #endif +#ifdef _WIN32 +#include "capture_win_ifnames.h" /* windows friendly interface names */ +#endif + if_info_t * if_info_new(char *name, char *description) { @@ -63,6 +67,13 @@ if_info_new(char *name, char *description) if_info->description = NULL; else if_info->description = g_strdup(description); + +#ifdef _WIN32 + get_windows_interface_friendlyname(name, &if_info->friendly_name); +#else + if_info->friendly_name = NULL; +#endif + if_info->addrs = NULL; if_info->loopback = FALSE; return if_info; diff --git a/capture_ifinfo.c b/capture_ifinfo.c index fc7a76e7d5..314a01ad1e 100644 --- a/capture_ifinfo.c +++ b/capture_ifinfo.c @@ -140,9 +140,9 @@ capture_interface_list(int *err, char **err_str) g_free(data); for (i = 0; raw_list[i] != NULL; i++) { - if_parts = g_strsplit(raw_list[i], "\t", 4); + if_parts = g_strsplit(raw_list[i], "\t", 5); if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL || - if_parts[3] == NULL) { + if_parts[3] == NULL || if_parts[4] == NULL) { g_strfreev(if_parts); continue; } @@ -160,7 +160,9 @@ capture_interface_list(int *err, char **err_str) if_info->name = g_strdup(name); if (strlen(if_parts[1]) > 0) if_info->description = g_strdup(if_parts[1]); - addr_parts = g_strsplit(if_parts[2], ",", 0); + if (strlen(if_parts[2]) > 0) + if_info->friendly_name = g_strdup(if_parts[2]); + addr_parts = g_strsplit(if_parts[3], ",", 0); for (j = 0; addr_parts[j] != NULL; j++) { if_addr = g_malloc0(sizeof(if_addr_t)); if (inet_pton(AF_INET, addr_parts[j], &if_addr->addr.ip4_addr)) { @@ -176,7 +178,7 @@ capture_interface_list(int *err, char **err_str) if_info->addrs = g_slist_append(if_info->addrs, if_addr); } } - if (strcmp(if_parts[3], "loopback") == 0) + if (strcmp(if_parts[4], "loopback") == 0) if_info->loopback = TRUE; g_strfreev(if_parts); g_strfreev(addr_parts); diff --git a/capture_ifinfo.h b/capture_ifinfo.h index 03b836f345..3ec2e51160 100644 --- a/capture_ifinfo.h +++ b/capture_ifinfo.h @@ -35,7 +35,8 @@ extern "C" { */ typedef struct { char *name; /* e.g. "eth0" */ - char *description; /* from OS, e.g. "Local Area Connection" or NULL */ + char *description; /* vendor description from libpcap, e.g. "Realtek PCIe GBE Family Controller" or NULL */ + char *friendly_name; /* from OS, e.g. "Local Area Connection" */ GSList *addrs; /* containing address values of if_addr_t */ gboolean loopback; /* TRUE if loopback, FALSE otherwise */ } if_info_t; diff --git a/capture_opts.c b/capture_opts.c index 5f32a4286d..7d39c10b1c 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -50,6 +50,10 @@ #include "capture-pcap-util.h" #include <wsutil/file_util.h> +#ifdef _WIN32 +#include "capture_win_ifnames.h" /* windows friendly interface names */ +#endif + static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe); @@ -142,6 +146,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio interface_opts = g_array_index(capture_opts->ifaces, interface_options, i); g_log(log_domain, log_level, "Interface name[%02d] : %s", i, interface_opts.name ? interface_opts.name : "(unspecified)"); g_log(log_domain, log_level, "Interface Descr[%02d] : %s", i, interface_opts.descr ? interface_opts.descr : "(unspecified)"); + g_log(log_domain, log_level, "Con display name[%02d]: %s", i, interface_opts.console_display_name ? interface_opts.console_display_name : "(unspecified)"); g_log(log_domain, log_level, "Capture filter[%02d] : %s", i, interface_opts.cfilter ? interface_opts.cfilter : "(unspecified)"); g_log(log_domain, log_level, "Snap length[%02d] (%u) : %d", i, interface_opts.has_snaplen, interface_opts.snaplen); g_log(log_domain, log_level, "Link Type[%02d] : %d", i, interface_opts.linktype); @@ -445,7 +450,25 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str gchar *err_str; interface_options interface_opts; + /* retrieve the interface list to compare the option specfied against */ + if_list = capture_interface_list(&err, &err_str); + if (if_list == NULL) { + switch (err) { + + case CANT_GET_INTERFACE_LIST: + case DONT_HAVE_PCAP: + cmdarg_err("%s", err_str); + g_free(err_str); + break; + + case NO_INTERFACES_FOUND: + cmdarg_err("There are no interfaces on which a capture can be done"); + break; + } + return 2; + } + /* * If the argument is a number, treat it as an index into the list * of adapters, as printed by "tshark -D". @@ -469,36 +492,85 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str cmdarg_err("There is no interface with that adapter index"); return 1; } - if_list = capture_interface_list(&err, &err_str); - if (if_list == NULL) { - switch (err) { - - case CANT_GET_INTERFACE_LIST: - case DONT_HAVE_PCAP: - cmdarg_err("%s", err_str); - g_free(err_str); - break; - - case NO_INTERFACES_FOUND: - cmdarg_err("There are no interfaces on which a capture can be done"); - break; - } - return 2; - } if_info = (if_info_t *)g_list_nth_data(if_list, adapter_index - 1); if (if_info == NULL) { cmdarg_err("There is no interface with that adapter index"); return 1; } interface_opts.name = g_strdup(if_info->name); - /* We don't set iface_descr here because doing so requires - * capture_ui_utils.c which requires epan/prefs.c which is - * probably a bit too much dependency for here... - */ - free_interface_list(if_list); + if(if_info->friendly_name!=NULL){ + /* we know the friendlyname, so display that instead of the interface name/guid */ + interface_opts.console_display_name = g_strdup(if_info->friendly_name); + }else{ + /* fallback to the interface name */ + interface_opts.console_display_name = g_strdup(if_info->name); + } } else { - interface_opts.name = g_strdup(optarg_str_p); + /* try and do an exact match (case insensitive) */ + GList *if_entry; + gboolean matched; + + matched=FALSE; + for (if_entry = g_list_first(if_list); if_entry != NULL; + if_entry = g_list_next(if_entry)) + { + if_info = (if_info_t *)if_entry->data; + /* exact name check */ + if(g_ascii_strcasecmp(if_info->name, optarg_str_p)==0){ + /* exact match on the interface name, use that for displaying etc */ + interface_opts.name = g_strdup(if_info->name); + + if(if_info->friendly_name!=NULL){ + /* if we know a friendly_name, use that for console_display_name, as + * it is the basis for the auto generated temp filename */ + interface_opts.console_display_name = g_strdup(if_info->friendly_name); + }else{ + interface_opts.console_display_name = g_strdup(if_info->name); + } + matched=TRUE; + break; + } + + /* exact friendlyname check */ + if(if_info->friendly_name!=NULL && g_ascii_strcasecmp(if_info->friendly_name, optarg_str_p)==0){ + /* exact match - use the friendly name for display */ + interface_opts.name = g_strdup(if_info->name); + interface_opts.console_display_name = g_strdup(if_info->friendly_name); + matched=TRUE; + break; + } + } + + /* didn't find, attempt a case insensitive prefix match of the friendly name*/ + if(!matched){ + int prefix_length; + prefix_length=strlen(optarg_str_p); + for (if_entry = g_list_first(if_list); if_entry != NULL; + if_entry = g_list_next(if_entry)) + { + if_info = (if_info_t *)if_entry->data; + + if(if_info->friendly_name!=NULL && g_ascii_strncasecmp(if_info->friendly_name, optarg_str_p, prefix_length)==0){ + /* prefix match - use the friendly name for display */ + interface_opts.name = g_strdup(if_info->name); + interface_opts.console_display_name = g_strdup(if_info->friendly_name); + matched=TRUE; + break; + } + } + } + if (!matched) { + cmdarg_err("Failed to match interface '%s'", optarg_str_p); + return 1; + } + } + free_interface_list(if_list); + + /* We don't set iface_descr here because doing so requires + * capture_ui_utils.c which requires epan/prefs.c which is + * probably a bit too much dependency for here... + */ interface_opts.descr = g_strdup(capture_opts->default_options.descr); interface_opts.cfilter = g_strdup(capture_opts->default_options.cfilter); interface_opts.snaplen = capture_opts->default_options.snaplen; @@ -772,9 +844,14 @@ capture_opts_print_interfaces(GList *if_list) if_info = (if_info_t *)if_entry->data; fprintf_stderr("%d. %s", i++, if_info->name); - /* Print the description if it exists */ - if (if_info->description != NULL) - fprintf_stderr(" (%s)", if_info->description); + /* print the interface friendly name if known, if not fall back to vendor description */ + if (if_info->friendly_name != NULL){ + fprintf_stderr(" (%s)", if_info->friendly_name); + }else{ + /* Print the description if it exists */ + if (if_info->description != NULL) + fprintf_stderr(" (%s)", if_info->description); + } fprintf_stderr("\n"); } } @@ -823,82 +900,29 @@ void capture_opts_trim_ring_num_files(capture_options *capture_opts) gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capture_device) { - GList *if_list; - if_info_t *if_info; - int err; - gchar *err_str; - interface_options interface_opts; - + int status; /* Did the user specify an interface to use? */ - 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. */ - interface_opts.name = g_strdup(capture_device); - /* We don't set iface_descr here because doing so requires - * capture_ui_utils.c which requires epan/prefs.c which is - * probably a bit too much dependency for here... - */ - } else { - /* No - pick the first one from the list of interfaces. */ - if_list = capture_interface_list(&err, &err_str); - if (if_list == NULL) { - switch (err) { - - case CANT_GET_INTERFACE_LIST: - case DONT_HAVE_PCAP: - cmdarg_err("%s", err_str); - g_free(err_str); - break; + if (capture_opts->num_selected != 0 || capture_opts->ifaces->len != 0) { + /* yes they did, exit immediately nothing further to do here */ + return TRUE; + } - case NO_INTERFACES_FOUND: - cmdarg_err("There are no interfaces on which a capture can be done"); - break; - } - return FALSE; - } - if_info = (if_info_t *)if_list->data; /* first interface */ - interface_opts.name = g_strdup(if_info->name); - /* We don't set iface_descr here because doing so requires - * capture_ui_utils.c which requires epan/prefs.c which is - * probably a bit too much dependency for here... - */ - free_interface_list(if_list); + /* No - is a default specified in the preferences file? */ + if (capture_device != NULL) { + /* Yes - use it. */ + status=capture_opts_add_iface_opt(capture_opts, capture_device); + if(status==0){ + return TRUE; /* interface found */ } - if (capture_opts->default_options.descr) { - interface_opts.descr = g_strdup(capture_opts->default_options.descr); - } else { - interface_opts.descr = NULL; - } - interface_opts.cfilter = g_strdup(capture_opts->default_options.cfilter); - interface_opts.snaplen = capture_opts->default_options.snaplen; - interface_opts.has_snaplen = capture_opts->default_options.has_snaplen; - interface_opts.linktype = capture_opts->default_options.linktype; - interface_opts.promisc_mode = capture_opts->default_options.promisc_mode; -#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - interface_opts.buffer_size = capture_opts->default_options.buffer_size; -#endif - interface_opts.monitor_mode = capture_opts->default_options.monitor_mode; -#ifdef HAVE_PCAP_REMOTE - interface_opts.src_type = capture_opts->default_options.src_type; - interface_opts.remote_host = g_strdup(capture_opts->default_options.remote_host); - interface_opts.remote_port = g_strdup(capture_opts->default_options.remote_port); - interface_opts.auth_type = capture_opts->default_options.auth_type; - interface_opts.auth_username = g_strdup(capture_opts->default_options.auth_username); - interface_opts.auth_password = g_strdup(capture_opts->default_options.auth_password); - interface_opts.datatx_udp = capture_opts->default_options.datatx_udp; - interface_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap; - interface_opts.nocap_local = capture_opts->default_options.nocap_local; -#endif -#ifdef HAVE_PCAP_SETSAMPLING - interface_opts.sampling_method = capture_opts->default_options.sampling_method; - interface_opts.sampling_param = capture_opts->default_options.sampling_param; -#endif - g_array_append_val(capture_opts->ifaces, interface_opts); + return FALSE; /* some kind of error finding interface */ } - - return TRUE; + /* No default in preferences file, just pick the first interface from the list of interfaces. */ + status=capture_opts_add_iface_opt(capture_opts, "1"); + if(status==0){ + return TRUE; /* success */ + } + return FALSE; /* some kind of error finding the first interface */ } @@ -979,6 +1003,9 @@ collect_ifaces(capture_options *capture_opts) interface_opts = g_array_index(capture_opts->ifaces, interface_options, i - 1); g_free(interface_opts.name); g_free(interface_opts.descr); + if(interface_opts.console_display_name!=NULL){ + g_free(interface_opts.console_display_name); + } g_free(interface_opts.cfilter); #ifdef HAVE_PCAP_REMOTE if (interface_opts.src_type == CAPTURE_IFREMOTE) { @@ -997,6 +1024,7 @@ collect_ifaces(capture_options *capture_opts) if (!device.hidden && device.selected) { interface_opts.name = g_strdup(device.name); interface_opts.descr = g_strdup(device.display_name); + interface_opts.console_display_name = g_strdup(device.name); interface_opts.linktype = device.active_dlt; interface_opts.cfilter = g_strdup(device.cfilter); interface_opts.snaplen = device.snaplen; diff --git a/capture_opts.h b/capture_opts.h index 9d3ecdc383..a962492a1b 100644 --- a/capture_opts.h +++ b/capture_opts.h @@ -114,6 +114,7 @@ typedef struct remote_options_tag { typedef struct interface_tag { gchar *name; gchar *display_name; + gchar *friendly_name; guint type; gchar *addresses; gint no_addresses; @@ -147,8 +148,9 @@ typedef struct link_row_tag { } link_row; typedef struct interface_options_tag { - gchar *name; + gchar *name; /* the name of the interface provided to winpcap/libpcap to specify the interface */ gchar *descr; + gchar *console_display_name; /* the name displayed in the console, also the basis for autonamed pcap filenames */ gchar *cfilter; gboolean has_snaplen; int snaplen; diff --git a/capture_ui_utils.c b/capture_ui_utils.c index 9c019711ad..d8aa25c617 100644 --- a/capture_ui_utils.c +++ b/capture_ui_utils.c @@ -180,7 +180,10 @@ get_interface_descriptive_name(const char *if_name) do { if_info = if_entry->data; if (strcmp(if_info->name, if_name) == 0) { - if (if_info->description != NULL) { + if (if_info->friendly_name!= NULL) { + /* use the friendly name */ + descr = g_strdup(if_info->friendly_name); + }else if (if_info->description != NULL) { /* Return a copy of that - when we free the interface list, that'll also free up the strings to which it refers. */ diff --git a/capture_win_ifnames.c b/capture_win_ifnames.c new file mode 100644 index 0000000000..d4b5ad0d03 --- /dev/null +++ b/capture_win_ifnames.c @@ -0,0 +1,319 @@ +/* capture_win_ifnames.c +* Routines supporting the use of Windows friendly interface names within Wireshark +* Copyright 2011-2012, Mike Garratt <wireshark@evn.co.nz> +* +* $Id$ +* +* Wireshark - Network traffic analyzer +* By Gerald Combs <gerald@wireshark.org> +* Copyright 1998 Gerald Combs +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _WIN32 + +#include <windows.h> +#include <objbase.h> /* for CLSIDFromString() to convert guid text to a GUID */ +#include <tchar.h> +#include <winsock2.h> +#include <iphlpapi.h> +#include <stdio.h> +#include <stdlib.h> + +#include <wtap.h> +#include <libpcap.h> +#include <glib.h> + +#include <ntddndis.h> + +#include "log.h" + +#include "capture_ifinfo.h" +#include "capture_win_ifnames.h" +#include "wsutil/file_util.h" + +/* Link with ole32.lib - provides CLSIDFromString() to convert guid text to a GUID */ +#pragma comment(lib, "ole32.lib") + +/**********************************************************************************/ +gboolean IsWindowsVistaOrLater() +{ + OSVERSIONINFO osvi; + + SecureZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if(GetVersionEx(&osvi)){ + return osvi.dwMajorVersion >= 6; + } + return FALSE; +} +/**********************************************************************************/ +/* The wireshark gui doesn't appear at this stage to support having logging messages +* returned using g_log() before the interface list. +* Below is a generic logging function that can be easily ripped out or configured to +* redirect to g_log() if the behaviour changes in the future. +*/ +static void ifnames_log(const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...) +{ + char buf[16384]; + va_list args; + + if(log_level!=G_LOG_LEVEL_ERROR){ + return; + } + + va_start(args, format); + vsnprintf(buf, 16383, format, args); + va_end(args); + + fprintf(stderr,"%s\r\n",buf); + +} + +#define g_log ifnames_log +/**********************************************************************************/ +/* Get the Connection Name for the given GUID */ +static int GetInterfaceFriendlyNameFromDeviceGuid(__in GUID *guid, __out char **Name) +{ + HMODULE hIPHlpApi; + HRESULT status; + WCHAR wName[NDIS_IF_MAX_STRING_SIZE + 1]; + HRESULT hr; + gboolean fallbackToUnpublishedApi=TRUE; + gboolean haveInterfaceFriendlyName=FALSE; + + /* check we have a parameter */ + if(Name==NULL){ + return -1; + } + + /* Load the ip helper api DLL */ + hIPHlpApi = LoadLibrary(TEXT("iphlpapi.dll")); + if (hIPHlpApi == NULL) { + /* Load failed - DLL should always be available in XP+*/ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed to load iphlpapi.dll library for interface name lookups, errorcode=0x%08x\n", GetLastError()); + return -1; + } + + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Loaded iphlpapi.dll library for interface friendly name lookups"); + + /* Need to convert an Interface GUID to the interface friendly name (e.g. "Local Area Connection") + * The functions required to do this all reside within iphlpapi.dll + * - The preferred approach is to use published API functions (Available since Windows Vista) + * - We do however fallback to trying undocumented API if the published API is not available (Windows XP/2k3 scenario) + */ + + if(IsWindowsVistaOrLater()){ + /* Published API function prototypes (for Windows Vista/Windows Server 2008+) */ + typedef NETIO_STATUS (WINAPI *ProcAddr_CIG2L) (__in CONST GUID *InterfaceGuid, __out PNET_LUID InterfaceLuid); + typedef NETIO_STATUS (WINAPI *ProcAddr_CIL2A) ( __in CONST NET_LUID *InterfaceLuid,__out_ecount(Length) PWSTR InterfaceAlias, __in SIZE_T Length); + + /* Attempt to do the conversion using Published API functions */ + ProcAddr_CIG2L proc_ConvertInterfaceGuidToLuid=(ProcAddr_CIG2L) GetProcAddress(hIPHlpApi, "ConvertInterfaceGuidToLuid"); + if(proc_ConvertInterfaceGuidToLuid!=NULL){ + ProcAddr_CIL2A Proc_ConvertInterfaceLuidToAlias=(ProcAddr_CIL2A) GetProcAddress(hIPHlpApi, "ConvertInterfaceLuidToAlias"); + if(Proc_ConvertInterfaceLuidToAlias!=NULL){ + /* we have our functions ready to go, attempt to convert interface guid->luid->friendlyname */ + NET_LUID InterfaceLuid; + hr = proc_ConvertInterfaceGuidToLuid(guid, &InterfaceLuid); + if(hr==NO_ERROR){ + /* guid->luid success */ + hr = Proc_ConvertInterfaceLuidToAlias(&InterfaceLuid, wName, NDIS_IF_MAX_STRING_SIZE+1); + + if(hr==NO_ERROR){ + /* luid->friendly name success */ + haveInterfaceFriendlyName=TRUE; /* success */ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, + "converted interface guid to friendly name."); + }else{ + /* luid->friendly name failed */ + fallbackToUnpublishedApi=FALSE; + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, + "ConvertInterfaceLuidToAlias failed to convert interface luid to a friendly name, LastErrorCode=0x%08x.", GetLastError()); + } + }else{ + fallbackToUnpublishedApi=FALSE; + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, + "ConvertInterfaceGuidToLuid failed to convert interface guid to a luid, LastErrorCode=0x%08x.", GetLastError()); + } + + }else{ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed to find address of ConvertInterfaceLuidToAlias in iphlpapi.dll, LastErrorCode=0x%08x.", GetLastError()); + } + }else{ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed to find address of ConvertInterfaceGuidToLuid in iphlpapi.dll, LastErrorCode=0x%08x.", GetLastError()); + } + } + + + if(fallbackToUnpublishedApi && !haveInterfaceFriendlyName){ + /* Didn't manage to get the friendly name using published api functions + * (most likely cause wireshark is running on Windows XP/Server 2003) + * Retry using nhGetInterfaceNameFromGuid (an older unpublished API function) */ + typedef HRESULT (WINAPI *ProcAddr_nhGINFG) (__in GUID *InterfaceGuid, __out PCWSTR InterfaceAlias, __inout DWORD *LengthAddress, wchar_t *a4, wchar_t *a5); + + ProcAddr_nhGINFG Proc_nhGetInterfaceNameFromGuid = NULL; + Proc_nhGetInterfaceNameFromGuid = (ProcAddr_nhGINFG) GetProcAddress(hIPHlpApi, "NhGetInterfaceNameFromGuid"); + if (Proc_nhGetInterfaceNameFromGuid!= NULL) { + wchar_t *p4=NULL, *p5=NULL; + DWORD NameSize; + + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, + "Unpublished NhGetInterfaceNameFromGuid function located in iphlpapi.dll, looking up friendly name from guid"); + + /* testing of nhGetInterfaceNameFromGuid indicates the unpublished API function expects the 3rd parameter + * to be the available space in bytes (as compared to wchar's) available in the second parameter buffer + * to receive the friendly name (in unicode format) including the space for the nul termination.*/ + NameSize = sizeof(wName); + + /* do the guid->friendlyname lookup */ + status = Proc_nhGetInterfaceNameFromGuid(guid, wName, &NameSize, p4, p5); + + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, + "nhGetInterfaceNameFromGuidProc status =%d, p4=%d, p5=%d, namesize=%d\n", status, (int)p4, (int)p5, NameSize); + if(status==0){ + haveInterfaceFriendlyName=TRUE; /* success */ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, + "Converted interface guid to friendly name."); + } + + }else{ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed to locate unpublished NhGetInterfaceNameFromGuid function located in iphlpapi.dll, " + "for looking up interface friendly name, LastErrorCode=0x%08x.", GetLastError()); + } + + } + + /* we have finished with iphlpapi.dll - release it */ + FreeLibrary(hIPHlpApi); + + if(!haveInterfaceFriendlyName){ + /* failed to get the friendly name, nothing further to do */ + return -1; + } + + /* Get the required buffer size, and then convert the string */ + { + int size = WideCharToMultiByte(CP_UTF8, 0, wName, -1, NULL, 0, NULL, NULL); + char *name = (char *) g_malloc(size); + if (name == NULL){ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed to allocate memory to convert format of interface friendly name, LastErrorCode=0x%08x.", GetLastError()); + return -1; + } + size=WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, size, NULL, NULL); + if(size==0){ + /* bytes written == 0, indicating some form of error*/ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Error converting format of interface friendly name, LastErrorCode=0x%08x.", GetLastError()); + g_free(name); + return -1; + } + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Friendly name is '%s'", name); + + *Name = name; + } + return 0; +} + + +/**********************************************************************************/ +/* returns the interface friendly name for a device name, if it is unable to +* resolve the name, "" is returned */ +void get_windows_interface_friendlyname(/* IN */ char *interface_devicename, /* OUT */char **interface_friendlyname) +{ + const char* guid_text; + GUID guid; + + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "test, 1,2,3"); + + /* ensure we can return a result */ + if(interface_friendlyname==NULL){ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "open_raw_pipe sdfsd"); + fflush(stderr); + fflush(stdout); + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "invalid interface_friendlyname parameter to get_windows_interface_friendlyname() function."); + return; + } + /* start on the basis we know nothing */ + *interface_friendlyname=NULL; + + /* Extract the guid text from the interface device name */ + if(strncmp("\\Device\\NPF_", interface_devicename, 12)==0){ + guid_text=interface_devicename+12; /* skip over the '\Device\NPF_' prefix, assume the rest is the guid text */ + }else{ + guid_text=interface_devicename; + } + + /*** Convert the guid text the GUID structure */ + { + /* Part 1: guid_text to unicode, dynamically allocating sufficent memory for conversion*/ + WCHAR wGuidText[39]; + HRESULT hr; + int size=39; /* a guid should always been 38 unicode characters in length (+1 for null termination) */ + size=MultiByteToWideChar(CP_ACP, 0, guid_text, -1, wGuidText, size); + if(size!=39){ + /* guid text to unicode conversion failed */ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed the extract guid from interface devicename, unicode convert result=%d, guid input ='%s', LastErrorCode=0x%08x.", + size, guid_text, GetLastError()); + return; + } + /* Part 2: unicode guid text to GUID structure */ + hr = CLSIDFromString(wGuidText, (LPCLSID)&guid); + if (hr != S_OK){ + /* guid text to unicode conversion failed */ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed to convert interface devicename guid to GUID structure, convert result=0x%08x, guid input ='%s', LastErrorCode=0x%08x.", + hr, guid_text, GetLastError()); + return; + } + } + + /* guid okay, get the interface friendly name associated with the guid */ + { + int r=GetInterfaceFriendlyNameFromDeviceGuid(&guid, interface_friendlyname); + if(r!=NO_ERROR){ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, + "Failed to retrieve interface friendly name associated with interface '%s', LastErrorCode=0x%08x.", + interface_devicename, GetLastError()); + *interface_friendlyname=NULL; /* failed to get friendly name, ensure the ultimate result is NULL */ + return; + } + } + + /* success */ + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, + "\nInterface %s => '%s'\n\n\n", interface_devicename, *interface_friendlyname); + + return; +} + +#undef g_log + +/**************************************************************************************/ +#endif + diff --git a/capture_win_ifnames.h b/capture_win_ifnames.h new file mode 100644 index 0000000000..1b4553e2c3 --- /dev/null +++ b/capture_win_ifnames.h @@ -0,0 +1,31 @@ +/* capture_win_ifnames.h + * Routines supporting the use of Windows friendly interface names within Wireshark + * Copyright 2011-2012, Mike Garratt <wireshark@evn.co.nz> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef CAPTURE_WIN_IFNAMES_H +#define CAPTURE_WIN_IFNAMES_H + +void get_windows_interface_friendlyname(/* IN */ char *interface_devicename, /* OUT */char **interface_friendlyname); + +#endif @@ -1275,6 +1275,11 @@ get_if_capabilities(const char *devname, gboolean monitor_mode } #define ADDRSTRLEN 46 /* Covers IPv4 & IPv6 */ +/* + * Output a machine readable list of the interfaces + * This list is retrieved by the sync_interface_list_open() function + * The actual output of this function can be viewed with the command "dumpcap -D -Z none" + */ static void print_machine_readable_interfaces(GList *if_list) { @@ -1306,6 +1311,11 @@ print_machine_readable_interfaces(GList *if_list) printf("\t%s\t", if_info->description); else printf("\t\t"); + + if (if_info->friendly_name != NULL) + printf("%s\t", if_info->friendly_name); + else + printf("\t"); for(addr = g_slist_nth(if_info->addrs, 0); addr != NULL; addr = g_slist_next(addr)) { @@ -3211,15 +3221,27 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd, prefix = g_strdup_printf("wireshark_%d_interfaces", global_capture_opts.ifaces->len); } else { gchar *basename; + basename = g_path_get_basename(g_array_index(global_capture_opts.ifaces, interface_options, 0).console_display_name); #ifdef _WIN32 - GString *iface; - iface = isolate_uuid(g_array_index(global_capture_opts.ifaces, interface_options, 0).name); - basename = g_path_get_basename(iface->str); - g_string_free(iface, TRUE); -#else - basename = g_path_get_basename(g_array_index(global_capture_opts.ifaces, interface_options, 0).name); + /* use the generic portion of the interface guid to form the basis of the filename */ + if(strncmp("NPF_{", basename, 5)==0) + { + /* we have a windows guid style device name, extract the guid digits as the basis of the filename */ + GString *iface; + iface = isolate_uuid(basename); + g_free(basename); + basename = g_strdup(iface->str); + g_string_free(iface, TRUE); + } #endif - prefix = g_strconcat("wireshark_", basename, NULL); + /* generate the temp file name prefix... + * It would be nice if we could specify a pcapng/pcap filename suffix, + * create_tempfile() however currently uses mkstemp() which doesn't allow this - one day perhaps*/ + if (capture_opts->use_pcapng) { + prefix = g_strconcat("wireshark_pcapng_", basename, NULL); + }else{ + prefix = g_strconcat("wireshark_pcap_", basename, NULL); + } g_free(basename); } *save_file_fd = create_tempfile(&tmpname, prefix); @@ -3815,7 +3837,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct report_capture_error(errmsg, please_report); } } - report_packet_drops(received, dropped, interface_opts.name); + report_packet_drops(received, dropped, interface_opts.console_display_name); } /* close the input file (pcap or capture pipe) */ @@ -4657,7 +4679,6 @@ main(int argc, char *argv[]) } /* Let the user know what interfaces were chosen. */ - /* get_interface_descriptive_name() is not available! */ if (capture_child) { for (j = 0; j < global_capture_opts.ifaces->len; j++) { interface_options interface_opts; @@ -4669,10 +4690,11 @@ main(int argc, char *argv[]) } else { str = g_string_new(""); #ifdef _WIN32 - if (global_capture_opts.ifaces->len < 2) { + if (global_capture_opts.ifaces->len < 2) #else - if (global_capture_opts.ifaces->len < 4) { + if (global_capture_opts.ifaces->len < 4) #endif + { for (j = 0; j < global_capture_opts.ifaces->len; j++) { interface_options interface_opts; @@ -4685,8 +4707,8 @@ main(int argc, char *argv[]) if (j == global_capture_opts.ifaces->len - 1) { g_string_append_printf(str, "and "); } - } - g_string_append_printf(str, "%s", interface_opts.name); + } + g_string_append_printf(str, "'%s'", interface_opts.console_display_name); } } else { g_string_append_printf(str, "%u interfaces", global_capture_opts.ifaces->len); @@ -4744,6 +4766,9 @@ main(int argc, char *argv[]) /* We're supposed to do a capture. Process the ring buffer arguments. */ capture_opts_trim_ring_num_files(&global_capture_opts); + /* flush stderr prior to starting the main capture loop */ + fflush(stderr); + /* Now start the capture. */ if(capture_loop_start(&global_capture_opts, &stats_known, &stats) == TRUE) { @@ -4956,7 +4981,7 @@ report_packet_drops(guint32 received, guint32 drops, gchar *name) pipe_write_block(2, SP_DROPS, tmp); } else { fprintf(stderr, - "Packets received/dropped on interface %s: %u/%u (%.1f%%)\n", + "Packets received/dropped on interface '%s': %u/%u (%.1f%%)\n", name, received, drops, received ? 100.0 * received / (received + drops) : 0.0); /* stderr could be line buffered */ @@ -2191,12 +2191,13 @@ capture(void) g_string_append_printf(str, "and "); } } - g_string_append_printf(str, "%s", interface_opts.descr); + g_string_append_printf(str, "'%s'", interface_opts.descr); } } else { g_string_append_printf(str, "%u interfaces", global_capture_opts.ifaces->len); } fprintf(stderr, "Capturing on %s\n", str->str); + fflush(stderr); g_string_free(str, TRUE); ret = sync_pipe_start(&global_capture_opts); diff --git a/ui/gtk/capture_dlg.c b/ui/gtk/capture_dlg.c index 38751298b1..0a2f9fd1f2 100644 --- a/ui/gtk/capture_dlg.c +++ b/ui/gtk/capture_dlg.c @@ -108,6 +108,12 @@ enum INAME }; +#ifdef _WIN32 + #define LOCAL_OFFSET 1 +#else + #define LOCAL_OFFSET 0 +#endif + /* Capture callback data keys */ #define E_CAP_IFACE_KEY "cap_iface" #define E_CAP_IFACE_IP_KEY "cap_iface_ip" @@ -213,7 +219,7 @@ enum * Also: Capture:Start obtains info from the "Capture Options" window * if it exists and if its creation is complete. */ -static GtkWidget *cap_open_w = NULL, *opt_edit_w = NULL, *ok_bt, *new_interfaces_w = NULL; +static GtkWidget *cap_open_w = NULL, *opt_edit_w = NULL, *ok_bt, *interface_management_w = NULL; #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE) static GtkWidget *compile_bpf_w = NULL; #endif @@ -1357,7 +1363,7 @@ update_interface_list(void) if (cap_open_w == NULL) return; - iftype_cbx = (GtkWidget *)g_object_get_data(G_OBJECT(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_DIALOG_PTR_KEY)), E_REMOTE_HOST_TE_KEY); + iftype_cbx = (GtkWidget *)g_object_get_data(G_OBJECT(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY)), E_REMOTE_HOST_TE_KEY); iftype = CAPTURE_IFREMOTE; if (iftype >= CAPTURE_IFREMOTE) { if_r_list = get_remote_interface_list(global_remote_opts.remote_host_opts.remote_host, @@ -1419,7 +1425,7 @@ capture_remote_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w) static void capture_remote_destroy_cb(GtkWidget *win, gpointer user_data _U_) { - g_object_set_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_DIALOG_PTR_KEY, NULL); + g_object_set_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY, NULL); } /* user requested to accept remote interface options */ @@ -1497,7 +1503,7 @@ select_if_type_cb(GtkComboBox *iftype_cbx, gpointer data _U_) while (num_remote--) { /* Remove separator lines and "Clear" item */ gtk_combo_box_text_remove (GTK_COMBO_BOX_TEXT(iftype_cbx), num_remote); } - remote_w = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_DIALOG_PTR_KEY); + remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY); window_destroy(GTK_WIDGET(remote_w)); capture_remote_cb(GTK_WIDGET(iftype_cbx), FALSE); } else { @@ -1505,7 +1511,7 @@ select_if_type_cb(GtkComboBox *iftype_cbx, gpointer data _U_) rh = g_hash_table_lookup (remote_host_list, string); g_free (string); if (rh) { - remote_w = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_DIALOG_PTR_KEY); + remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY); port_te = g_object_get_data(G_OBJECT(remote_w), E_REMOTE_PORT_TE_KEY); gtk_entry_set_text(GTK_ENTRY(port_te), rh->remote_port); auth_rb = g_object_get_data(G_OBJECT(remote_w), E_REMOTE_AUTH_PASSWD_KEY); @@ -1538,8 +1544,8 @@ capture_remote_cb(GtkWidget *w, gboolean focus_username) title = create_user_window_title("Wireshark: Remote Interface"); remote_w = dlg_window_new(title); - g_object_set_data(G_OBJECT(remote_w), E_CAP_REMOTE_CALLER_PTR_KEY, new_interfaces_w); - g_object_set_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_DIALOG_PTR_KEY, remote_w); + g_object_set_data(G_OBJECT(remote_w), E_CAP_REMOTE_CALLER_PTR_KEY, interface_management_w); + g_object_set_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY, remote_w); g_free(title); main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); @@ -3197,8 +3203,8 @@ static void change_pipe_name_cb(gpointer dialog _U_, gint btn, gpointer data) simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "%sA pipe with this name already exists.%s", simple_dialog_primary_start(), simple_dialog_primary_end()); - if_cb = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_L_KEY)); - pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY); + if_cb = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY)); + pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY); model = gtk_tree_view_get_model(if_cb); if (gtk_tree_model_get_iter_first (model, &iter)) { do { @@ -3267,8 +3273,8 @@ static void change_pipe_name_cb(gpointer dialog _U_, gint btn, gpointer data) } break; case(ESD_BTN_CANCEL): { - if_cb = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_L_KEY)); - pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY); + if_cb = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY)); + pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY); model = gtk_tree_view_get_model(if_cb); if (gtk_tree_model_get_iter_first (model, &iter)) { @@ -3304,7 +3310,7 @@ add_pipe_cb(gpointer w _U_) guint i; gpointer dialog; - pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY); + pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY); g_save_file = gtk_entry_get_text(GTK_ENTRY(pipe_te)); name = g_strdup(g_save_file); if (strcmp(name, "New pipe") == 0 || strcmp(name, "") == 0) { @@ -3401,8 +3407,8 @@ add_pipe_cb(gpointer w _U_) static void pipe_new_bt_clicked_cb(GtkWidget *w _U_, gpointer data _U_) { - GtkWidget *name_te = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY); - GtkTreeView *pipe_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_L_KEY)); + GtkWidget *name_te = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY); + GtkTreeView *pipe_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY)); GtkListStore *store; GtkTreeIter iter; @@ -3425,8 +3431,8 @@ pipe_new_bt_clicked_cb(GtkWidget *w _U_, gpointer data _U_) static void pipe_del_bt_clicked_cb(GtkWidget *w _U_, gpointer data _U_) { - GtkWidget *pipe_l = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_L_KEY); - GtkWidget *name_te = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY); + GtkWidget *pipe_l = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY); + GtkWidget *name_te = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY); GtkTreeSelection *sel; GtkTreeModel *model, *optmodel; GtkTreeIter iter, optiter; @@ -3479,8 +3485,8 @@ pipe_del_bt_clicked_cb(GtkWidget *w _U_, gpointer data _U_) static void pipe_name_te_changed_cb(GtkWidget *w _U_, gpointer data _U_) { - GtkWidget *name_te = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY); - GtkWidget *pipe_l = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_L_KEY); + GtkWidget *name_te = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY); + GtkWidget *pipe_l = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY); const gchar *name = ""; GtkTreeSelection *sel; GtkTreeModel *model; @@ -3501,7 +3507,7 @@ fill_pipe_list(void) guint i; interface_t device; GtkTreeIter iter; - GtkTreeView *pipe_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_L_KEY)); + GtkTreeView *pipe_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY)); GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(pipe_l)); for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { @@ -3521,8 +3527,8 @@ pipe_sel_list_cb(GtkTreeSelection *sel, gpointer data _U_) /* GtkWidget *pipe_l = GTK_WIDGET(gtk_tree_selection_get_tree_view(sel));*/ GtkTreeModel *model; GtkTreeIter iter; - GtkWidget *name_te = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY); - GtkWidget *del_bt = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_DEL_KEY); + GtkWidget *name_te = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY); + GtkWidget *del_bt = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_DEL_KEY); gchar *name = NULL; if (gtk_tree_selection_get_selected(sel, &model, &iter)) { @@ -3545,7 +3551,7 @@ pipe_sel_list_cb(GtkTreeSelection *sel, gpointer data _U_) static void cancel_pipe_cb (gpointer w _U_) { - window_destroy(GTK_WIDGET(new_interfaces_w)); + window_destroy(GTK_WIDGET(interface_management_w)); } static void @@ -3555,15 +3561,24 @@ fill_local_list(void) interface_t device; GtkTreeIter iter; GtkListStore *store; - GtkTreeView *local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_LOCAL_L_KEY)); - + GtkTreeView *local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY)); + +#ifdef _WIN32 + store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); +#else store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); +#endif 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.local && device.type != IF_PIPE && device.type != IF_STDIN) { gtk_list_store_append(store, &iter); + +#ifdef _WIN32 + gtk_list_store_set(store, &iter, 0, device.friendly_name, 1, device.name, 2, device.hidden, -1); +#else gtk_list_store_set(store, &iter, 0, device.name, 1, device.hidden, -1); +#endif } else { continue; } @@ -3580,11 +3595,11 @@ static void local_hide_cb(GtkCellRendererToggle *cell _U_, GtkTreeModel *model; GtkTreeIter iter; GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - GtkTreeView *local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_LOCAL_L_KEY)); + GtkTreeView *local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY)); model = gtk_tree_view_get_model(local_l); gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, 0, &name, 1, &hide, -1); + gtk_tree_model_get (model, &iter, 0+LOCAL_OFFSET, &name, 1+LOCAL_OFFSET, &hide, -1); /* See if this is the currently selected capturing device */ if ((prefs.capture_device != NULL) && (*prefs.capture_device != '\0')) { @@ -3603,9 +3618,9 @@ static void local_hide_cb(GtkCellRendererToggle *cell _U_, if (hide_enabled) { if (hide) { - gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, FALSE, -1); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1+LOCAL_OFFSET, FALSE, -1); } else { - gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, TRUE, -1); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1+LOCAL_OFFSET, TRUE, -1); } } else { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Default interface cannot be hidden"); @@ -3623,14 +3638,14 @@ apply_local_cb(GtkWidget *win _U_, gpointer *data _U_) GtkTreeView *local_l; if (global_capture_opts.all_ifaces->len > 0) { - local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_LOCAL_L_KEY)); + local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY)); model = gtk_tree_view_get_model(local_l); new_hide = g_malloc0(MAX_VAL_LEN); if (gtk_tree_model_get_iter_first (model, &iter)) { do { - gtk_tree_model_get(model, &iter, 0, &name, 1, &hide, -1); + gtk_tree_model_get(model, &iter, 0+LOCAL_OFFSET, &name, 1+LOCAL_OFFSET, &hide, -1); if (!hide) { continue; } else { @@ -3647,11 +3662,16 @@ apply_local_cb(GtkWidget *win _U_, gpointer *data _U_) g_free(prefs.capture_devices_hide); prefs.capture_devices_hide = new_hide; hide_interface(g_strdup(new_hide)); - + /* Refresh all places that are displaying an interface list that includes local interfaces. */ refresh_local_interface_lists(); - } + + /* save changes to the preferences file */ + if (!prefs.gui_use_pref_save) { + prefs_main_write(); + } + } } void @@ -3686,8 +3706,8 @@ fill_remote_list(void) GtkWidget *host_te, *remote_w; num_selected = 0; - gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(new_interfaces_w), E_REMOTE_DEL_BT_KEY), FALSE); - remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_L_KEY)); + gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY), FALSE); + remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY)); store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING); for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); @@ -3696,7 +3716,7 @@ fill_remote_list(void) } else { /* fill the store */ if (strcmp(host, device.remote_opts.remote_host_opts.remote_host) != 0) { - remote_w = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_DIALOG_PTR_KEY); + remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY); host_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_HOST_TE_KEY); iftype_combo_box_add (host_te, &device); host = g_strdup(device.remote_opts.remote_host_opts.remote_host); @@ -3736,7 +3756,7 @@ static void remote_hide_cb(GtkCellRendererToggle *cell _U_, GtkTreeModel *model; GtkTreeIter iter; GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - GtkTreeView *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_L_KEY)); + GtkTreeView *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY)); model = gtk_tree_view_get_model(remote_l); gtk_tree_model_get_iter (model, &iter, path); @@ -3758,7 +3778,7 @@ ok_remote_cb(GtkWidget *win _U_, gpointer *data _U_) gboolean hide; gint first_if = TRUE; - GtkTreeView *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_L_KEY)); + GtkTreeView *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY)); model = gtk_tree_view_get_model(remote_l); new_hide = g_malloc0(MAX_VAL_LEN); @@ -3803,7 +3823,7 @@ select_host_cb(GtkTreeSelection *selection _U_, gtk_tree_model_get_iter (model, &iter, path); if (gtk_tree_model_iter_has_child(model, &iter)) { num_selected++; - gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(new_interfaces_w), E_REMOTE_DEL_BT_KEY), TRUE); + gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY), TRUE); return TRUE; } else { return FALSE; @@ -3818,7 +3838,7 @@ remove_remote_host(GtkWidget *w _U_, gpointer data _U_) gchar *host; gint num_children, i; interface_t device; - GtkTreeView *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_L_KEY)); + GtkTreeView *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY)); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(remote_l)); model = gtk_tree_view_get_model(remote_l); @@ -3833,7 +3853,7 @@ remove_remote_host(GtkWidget *w _U_, gpointer data _U_) } gtk_tree_store_remove(GTK_TREE_STORE(model), &iter); if (--num_selected == 0) { - gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(new_interfaces_w), E_REMOTE_DEL_BT_KEY), FALSE); + gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY), FALSE); } for (i = global_capture_opts.all_ifaces->len-1; i >= 0; i--) { device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); @@ -3875,12 +3895,12 @@ show_add_interfaces_dialog(void) GtkWidget *button_hbox, *help_hbox; GtkTreeSelection *selection; #endif - new_interfaces_w = dlg_window_new("Add new interfaces"); /* transient_for top_level */ - gtk_window_set_destroy_with_parent (GTK_WINDOW(new_interfaces_w), TRUE); - gtk_window_set_default_size(GTK_WINDOW(new_interfaces_w), 550, 200); + interface_management_w = dlg_window_new("Interface Management"); /* transient_for top_level */ + gtk_window_set_destroy_with_parent (GTK_WINDOW(interface_management_w), TRUE); + gtk_window_set_default_size(GTK_WINDOW(interface_management_w), 600, 200); vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_add(GTK_CONTAINER(new_interfaces_w), vbox); + gtk_container_add(GTK_CONTAINER(interface_management_w), vbox); gtk_container_set_border_width(GTK_CONTAINER(vbox), 12); main_nb = gtk_notebook_new(); @@ -3932,7 +3952,7 @@ show_add_interfaces_dialog(void) gtk_widget_set_sensitive(del_bt, FALSE); gtk_box_pack_start (GTK_BOX (list_bb), del_bt, FALSE, FALSE, 0); gtk_widget_set_tooltip_text (del_bt, "Remove the selected pipe from the list"); - g_object_set_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_DEL_KEY, del_bt); + g_object_set_data(G_OBJECT(interface_management_w), E_CAP_PIPE_DEL_KEY, del_bt); pipe_fr = gtk_frame_new("Pipes"); gtk_box_pack_start(GTK_BOX(top_hb), pipe_fr, TRUE, TRUE, 0); @@ -3959,7 +3979,7 @@ show_add_interfaces_dialog(void) sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(pipe_l)); gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); - g_object_set_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_L_KEY, pipe_l); + g_object_set_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY, pipe_l); g_signal_connect(sel, "changed", G_CALLBACK(pipe_sel_list_cb), pipe_vb); gtk_container_add(GTK_CONTAINER(pipe_sc), pipe_l); gtk_widget_show(pipe_l); @@ -4002,17 +4022,17 @@ show_add_interfaces_dialog(void) gtk_box_pack_start(GTK_BOX(temp_page), bbox, TRUE, FALSE, 5); add_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE); - g_signal_connect(add_bt, "clicked", G_CALLBACK(add_pipe_cb), new_interfaces_w); + g_signal_connect(add_bt, "clicked", G_CALLBACK(add_pipe_cb), interface_management_w); gtk_widget_set_tooltip_text(GTK_WIDGET(add_bt), "Add pipe to the list of interfaces."); cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE); - g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), new_interfaces_w); + g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), interface_management_w); gtk_widget_set_tooltip_text(GTK_WIDGET(cancel_bt), "Cancel and exit dialog."); gtk_widget_show(bbox); gtk_widget_show(temp_page); - g_object_set_data(G_OBJECT(new_interfaces_w), E_CAP_PIPE_TE_KEY, pipe_te); + g_object_set_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY, pipe_te); /* Local interfaces */ temp_page = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE); @@ -4042,19 +4062,27 @@ show_add_interfaces_dialog(void) local_l = gtk_tree_view_new(); +#ifdef _WIN32 renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", 0, NULL); + column = gtk_tree_view_column_new_with_attributes("Friendly Name", renderer, "text", 0, NULL); gtk_tree_view_column_set_expand(column, TRUE); gtk_tree_view_column_set_sort_column_id(column, 0); gtk_tree_view_append_column(GTK_TREE_VIEW(local_l), column); +#endif + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("Interface Name", renderer, "text", 0+LOCAL_OFFSET, NULL); + gtk_tree_view_column_set_expand(column, TRUE); + gtk_tree_view_column_set_sort_column_id(column, 0+LOCAL_OFFSET); + gtk_tree_view_append_column(GTK_TREE_VIEW(local_l), column); + toggle_renderer = gtk_cell_renderer_toggle_new(); - column = gtk_tree_view_column_new_with_attributes("Hide", GTK_CELL_RENDERER(toggle_renderer), "active", 1, NULL); + column = gtk_tree_view_column_new_with_attributes("Hide", GTK_CELL_RENDERER(toggle_renderer), "active", 1+LOCAL_OFFSET, NULL); g_signal_connect (G_OBJECT(toggle_renderer), "toggled", G_CALLBACK (local_hide_cb), NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(local_l), column); gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(toggle_renderer), TRUE); - g_object_set_data(G_OBJECT(new_interfaces_w), E_CAP_LOCAL_L_KEY, local_l); + g_object_set_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY, local_l); gtk_container_add(GTK_CONTAINER(local_sc), local_l); gtk_widget_show(local_l); @@ -4068,7 +4096,7 @@ show_add_interfaces_dialog(void) gtk_widget_set_tooltip_text(GTK_WIDGET(refresh_bt), "Rescan the local interfaces and refresh the list"); cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE); - g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), new_interfaces_w); + g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), interface_management_w); gtk_widget_set_tooltip_text(GTK_WIDGET(cancel_bt), "Cancel and exit dialog."); apply_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_APPLY); @@ -4135,7 +4163,7 @@ show_add_interfaces_dialog(void) selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(remote_l)); gtk_tree_selection_set_select_function(selection, select_host_cb, NULL, FALSE); - g_object_set_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_L_KEY, remote_l); + g_object_set_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY, remote_l); gtk_container_add(GTK_CONTAINER(remote_sc), remote_l); gtk_widget_show(remote_l); @@ -4168,7 +4196,7 @@ show_add_interfaces_dialog(void) g_signal_connect(delete_bt, "clicked", G_CALLBACK(remove_remote_host), NULL); gtk_widget_set_tooltip_text(GTK_WIDGET(delete_bt), "Remove a remote host from the list"); gtk_widget_set_sensitive(GTK_WIDGET(delete_bt), FALSE); - g_object_set_data(G_OBJECT(new_interfaces_w), E_REMOTE_DEL_BT_KEY, delete_bt); + g_object_set_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY, delete_bt); gtk_widget_show(delete_bt); ok_but = gtk_button_new_from_stock(GTK_STOCK_APPLY); @@ -4179,14 +4207,14 @@ show_add_interfaces_dialog(void) cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CLOSE); gtk_box_pack_end(GTK_BOX(button_hbox), cancel_bt, FALSE, FALSE, 0); - g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), new_interfaces_w); + g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), interface_management_w); gtk_widget_set_tooltip_text(GTK_WIDGET(cancel_bt), "Cancel and exit dialog."); gtk_widget_show(cancel_bt); gtk_widget_show(temp_page); #endif - gtk_widget_show_all(new_interfaces_w); + gtk_widget_show_all(interface_management_w); } /* show capture prepare (options) dialog */ @@ -5508,7 +5536,7 @@ capture_prep_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_) #endif #ifdef HAVE_PCAP_REMOTE - remote_w = g_object_get_data(G_OBJECT(new_interfaces_w), E_CAP_REMOTE_DIALOG_PTR_KEY); + remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY); if (remote_w != NULL) window_destroy(remote_w); #endif diff --git a/ui/gtk/capture_if_details_dlg_win32.c b/ui/gtk/capture_if_details_dlg_win32.c index 58a45f7836..da57975aca 100644 --- a/ui/gtk/capture_if_details_dlg_win32.c +++ b/ui/gtk/capture_if_details_dlg_win32.c @@ -58,6 +58,8 @@ #include <Ntddndis.h> #endif +#include "capture_win_ifnames.h" + #include "../capture_wpcap_packet.h" /* packet32.h requires sockaddr_storage @@ -1777,6 +1779,7 @@ capture_if_details_task_offload(GtkWidget *table, GtkWidget *main_vb, guint *row static int capture_if_details_general(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter, gchar *iface) { + gchar *interface_friendlyname; gchar string_buff[DETAILS_STR_MAX]; const gchar *manuf_name; unsigned int uint_value; @@ -1796,7 +1799,14 @@ capture_if_details_general(GtkWidget *table, GtkWidget *main_vb, guint *row, LPA /* general */ add_string_to_table(table, row, "Characteristics", ""); - /* Vendor description */ + /* OS friendly name - look it up from iface ("\Device\NPF_{11111111-2222-3333-4444-555555555555}") */ + get_windows_interface_friendlyname(/* IN */ iface, /* OUT */&interface_friendlyname); + if(interface_friendlyname!=NULL){ + add_string_to_table(table, row, "OS Friendly name", interface_friendlyname); + g_free(interface_friendlyname); + } + + /* Vendor description */ length = sizeof(values); if (wpcap_packet_request(adapter, OID_GEN_VENDOR_DESCRIPTION, FALSE /* !set */, values, &length)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%s", values); @@ -1816,7 +1826,7 @@ capture_if_details_general(GtkWidget *table, GtkWidget *main_vb, guint *row, LPA } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } - add_string_to_table(table, row, "Friendly name", string_buff); + add_string_to_table(table, row, "NDIS Friendly name", string_buff); /* Interface */ add_string_to_table(table, row, "Interface", iface); diff --git a/ui/gtk/capture_if_dlg.c b/ui/gtk/capture_if_dlg.c index 8afdd60bcb..c8f299f3ed 100644 --- a/ui/gtk/capture_if_dlg.c +++ b/ui/gtk/capture_if_dlg.c @@ -676,15 +676,9 @@ capture_if_refresh_if_list(void) if_lb = gtk_label_new(""); gtk_table_attach_defaults(GTK_TABLE(if_tb), if_lb, 0, 1, row, row+1); -#ifndef _WIN32 - /* - * On Windows, device names are generally not meaningful - NT 5 - * uses long blobs with GUIDs in them, for example - so we don't - * bother showing them. - */ if_lb = gtk_label_new("Device"); gtk_table_attach_defaults(GTK_TABLE(if_tb), if_lb, 1, 4, row, row+1); -#endif + if_lb = gtk_label_new("Description"); gtk_table_attach_defaults(GTK_TABLE(if_tb), if_lb, 4, 5, row, row+1); @@ -692,7 +686,7 @@ capture_if_refresh_if_list(void) gtk_table_attach_defaults(GTK_TABLE(if_tb), if_lb, 5, 6, row, row+1); if_lb = gtk_label_new("Packets"); - gtk_table_attach_defaults(GTK_TABLE(if_tb), if_lb, 6, 7, row, row+1); + gtk_table_attach_defaults(GTK_TABLE(if_tb), if_lb, 6, 7, row, row+1); if_lb = gtk_label_new(" Packets/s "); gtk_table_attach_defaults(GTK_TABLE(if_tb), if_lb, 7, 8, row, row+1); @@ -727,12 +721,20 @@ capture_if_refresh_if_list(void) icon = capture_get_if_icon(&(device)); gtk_table_attach_defaults(GTK_TABLE(if_tb), icon, 1, 2, row, row+1); - /* device name */ + /* device name */ +#ifdef _WIN32 + /* + * On Windows, device names are generally not meaningful - NT 5 + * uses long blobs with GUIDs in them, for example - so instead we use + * the display name which should match that shown in ncpa.cpl + */ + data.device_lb = gtk_label_new(device.display_name); +#else data.device_lb = gtk_label_new(device.name); -#ifndef _WIN32 +#endif 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, device.name); g_string_append(if_tool_str, "\n"); @@ -805,8 +807,12 @@ capture_if_refresh_if_list(void) row++; if (row <= 20) { /* Lets add up 20 rows of interfaces, otherwise the window may become too high */ +#ifdef _WIN32 + gtk_widget_get_preferred_size(GTK_WIDGET(data.details_bt), &requisition, NULL); +#else gtk_widget_get_preferred_size(GTK_WIDGET(data.choose_bt), &requisition, NULL); - height += requisition.height; +#endif + height += requisition.height; } } @@ -816,7 +822,13 @@ capture_if_refresh_if_list(void) if (cap_if_w) { gtk_window_get_size(GTK_WINDOW(cap_if_w), &curr_width, &curr_height); +#ifndef _WIN32 if (curr_height < height) + /* On windows, resetting the size regardless works around what appears to be a windows gtk bug + * with multiple nic's where the resulting dialog box is much smaller than it should be. + * note: the actual height calculation is not correct on Windows with varying + * number of interfaces but fine at this point in time. */ +#endif gtk_window_resize(GTK_WINDOW(cap_if_w), curr_width, height); } else diff --git a/ui/gtk/main_welcome.c b/ui/gtk/main_welcome.c index 4bd3b90569..33557a8bea 100644 --- a/ui/gtk/main_welcome.c +++ b/ui/gtk/main_welcome.c @@ -102,8 +102,8 @@ static GdkColor topic_item_entered_bg = { 0, 0xd3d3, 0xd8d8, 0xdada }; #endif static GtkWidget *welcome_file_panel_vb = NULL; #ifdef HAVE_LIBPCAP -static GtkWidget *if_view = NULL; -static GtkWidget *swindow; +static GtkWidget *if_view = NULL; /* contains a view (list) of all the interfaces */ +static GtkWidget *if_scrolled_window; /* a scrolled window that contains the if_view */ #endif static GSList *status_messages = NULL; @@ -834,7 +834,7 @@ select_ifaces(void) GtkTreeModel *model; GtkTreeSelection *entry; - if (global_capture_opts.num_selected > 0 && swindow) { + if (global_capture_opts.num_selected > 0 && if_scrolled_window) { 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)); @@ -922,13 +922,42 @@ clear_capture_box(void) if (item_hb) { gtk_widget_destroy(item_hb); } - if (swindow) { - gtk_widget_destroy(swindow); - swindow = NULL; + if (if_scrolled_window) { + gtk_widget_destroy(if_scrolled_window); + if_scrolled_window = NULL; if_view = NULL; } } +static void update_interface_scrolled_window_height(void) +{ + /* set the height of the scroll window that shows the interfaces + * based on the number of visible interfaces - up to a maximum of 10 interfaces */ + guint i; + interface_t device; + int visible_interface_count=0; + + if(if_scrolled_window==NULL){ + return; + } + + 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) { + visible_interface_count++; + } + } + if(visible_interface_count>10){ + /* up to 10 interfaces will be visible at one time */ + visible_interface_count=10; + } + if(visible_interface_count<2){ + /* minimum space for two interfaces */ + visible_interface_count=2; + } + gtk_widget_set_size_request(if_scrolled_window, FALSE, visible_interface_count*21+4); +} + static void update_capture_box(void) { @@ -943,7 +972,7 @@ update_capture_box(void) gtk_tree_selection_unselect_all(GTK_TREE_SELECTION(entry)); store = gtk_list_store_new(NUMCOLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); - gtk_list_store_clear(store); + gtk_list_store_clear(store); gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store)); for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); @@ -955,6 +984,7 @@ update_capture_box(void) } } } + update_interface_scrolled_window_height(); changed = TRUE; gtk_tree_selection_set_select_function(GTK_TREE_SELECTION(entry), on_selection_changed, (gpointer)&changed, NULL); } @@ -993,10 +1023,10 @@ static void fill_capture_box(void) "Same as Capture/Interfaces menu or toolbar item", welcome_button_callback_helper, capture_if_cb); gtk_box_pack_start(GTK_BOX(box_to_fill), item_hb_interface_list, FALSE, FALSE, 5); - swindow = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_set_size_request(swindow, FALSE, 100); - 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); + if_scrolled_window = gtk_scrolled_window_new (NULL, NULL); + update_interface_scrolled_window_height(); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(if_scrolled_window), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(if_scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); g_object_set_data(G_OBJECT(welcome_hb), CAPTURE_HB_BOX_INTERFACE_LIST, item_hb_interface_list); if_view = gtk_tree_view_new (); @@ -1028,8 +1058,8 @@ static void fill_capture_box(void) (welcome_button_callback_t)capture_if_start, (gpointer)if_view); gtk_box_pack_start(GTK_BOX(box_to_fill), item_hb_start, FALSE, FALSE, 5); update_capture_box(); - gtk_container_add (GTK_CONTAINER (swindow), if_view); - gtk_container_add(GTK_CONTAINER(box_to_fill), swindow); + gtk_container_add (GTK_CONTAINER (if_scrolled_window), if_view); + gtk_container_add(GTK_CONTAINER(box_to_fill), if_scrolled_window); g_object_set_data(G_OBJECT(welcome_hb), CAPTURE_HB_BOX_START, item_hb_start); item_hb_capture = welcome_button(WIRESHARK_STOCK_CAPTURE_OPTIONS, @@ -1057,6 +1087,9 @@ static void fill_capture_box(void) if (if_view) { clear_capture_box(); } + + /* run capture_interface_list(), not to get the interfaces, but to detect + * any errors, if there is an error, display an appropriate message in the gui */ capture_interface_list(&error, &err_str); switch (error) { @@ -1148,7 +1181,7 @@ welcome_if_panel_reload(void) list is non-empty, just update the interface list. Otherwise, create it (as we didn't have it) or destroy it (as we won't have it). */ - if (if_view && swindow && global_capture_opts.all_ifaces->len > 0) { + if (if_view && if_scrolled_window && global_capture_opts.all_ifaces->len > 0) { update_capture_box(); } else { GtkWidget *item_hb; diff --git a/ui/iface_lists.c b/ui/iface_lists.c index bb147c98f8..fa66e8551a 100644 --- a/ui/iface_lists.c +++ b/ui/iface_lists.c @@ -104,6 +104,11 @@ scan_local_interfaces(void) continue; } device.name = g_strdup(if_info->name); + if (if_info->friendly_name != NULL) { + device.friendly_name = g_strdup(if_info->friendly_name); + }else{ + device.friendly_name = NULL; + } device.hidden = FALSE; device.locked = FALSE; temp = g_malloc0(sizeof(if_info_t)); @@ -121,9 +126,16 @@ scan_local_interfaces(void) } 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); + if (if_info->friendly_name != NULL) { + /* We have a friendly name from the OS, use it */ +#ifdef _WIN32 + /* on windows, if known only show the interface friendly name - don't show the device guid */ + if_string = g_strdup_printf("%s", if_info->friendly_name); +#else + if_string = g_strdup_printf("%s: %s", if_info->friendly_name, if_info->name); +#endif + } else if (if_info->description != NULL) { + /* We have a device description from libpcap - use it. */ if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name); } else { /* No. */ if_string = g_strdup(if_info->name); |