/* capture_if_details_dlg.c * Routines for capture interface details window (only Win32!) * * Wireshark - Network traffic analyzer * By Gerald Combs * 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. */ #include "config.h" #if defined HAVE_LIBPCAP && defined _WIN32 #include #include #include #include #include #include #include "../file.h" #include "../capture.h" #include "ui/simple_dialog.h" #include "ui/gtk/main.h" #include "ui/gtk/dlg_utils.h" #include "ui/gtk/gui_utils.h" #include "ui/gtk/help_dlg.h" #include "ui/gtk/capture_if_details_dlg_win32.h" #include /* Needed here to force a definition of WINVER */ /* for some (all ?) Microsoft compilers newer than vc6. */ /* (If windows.h were used instead, there might be */ /* issues re winsock.h included before winsock2.h ) */ #include #ifdef HAVE_NTDDNDIS_H #include #endif #include "capture_win_ifnames.h" #include "../capture_wpcap_packet.h" /* packet32.h requires sockaddr_storage * whether sockaddr_storage is defined or not depends on the Platform SDK * version installed. The only one not defining it is the SDK that comes * with MSVC 6.0 (WINVER 0x0400). * * copied from RFC2553 (and slightly modified because of datatypes) ... * XXX - defined more than once, move this to a header file */ #ifndef WINVER #error WINVER not defined ... #endif #if (WINVER <= 0x0400) && defined(_MSC_VER) typedef unsigned short eth_sa_family_t; /* * Desired design of maximum size and alignment */ #define ETH_SS_MAXSIZE 128 /* Implementation specific max size */ #define ETH_SS_ALIGNSIZE (sizeof (gint64 /*int64_t*/)) /* Implementation specific desired alignment */ /* * Definitions used for sockaddr_storage structure paddings design. */ #define ETH_SS_PAD1SIZE (ETH_SS_ALIGNSIZE - sizeof (eth_sa_family_t)) #define ETH_SS_PAD2SIZE (ETH_SS_MAXSIZE - (sizeof (eth_sa_family_t) + \ ETH_SS_PAD1SIZE + ETH_SS_ALIGNSIZE)) struct sockaddr_storage { eth_sa_family_t __ss_family; /* address family */ /* Following fields are implementation specific */ char __ss_pad1[ETH_SS_PAD1SIZE]; /* 6 byte pad, this is to make implementation */ /* specific pad up to alignment field that */ /* follows explicit in the data structure */ gint64 /*int64_t*/ __ss_align; /* field to force desired structure */ /* storage alignment */ char __ss_pad2[ETH_SS_PAD2SIZE]; /* 112 byte pad to achieve desired size, */ /* _SS_MAXSIZE value minus size of ss_family */ /* __ss_pad1, __ss_align fields is 112 */ }; /* ... copied from RFC2553 */ #endif /* WINVER */ #include #define DETAILS_STR_MAX 1024 /* The informations and definitions used here are coming from various places on the web: * * ndiswrapper (various NDIS related definitions) * http://cvs.sourceforge.net/viewcvs.py/ndiswrapper/ndiswrapper/driver/ * * ReactOS (various NDIS related definitions) * http://www.reactos.org/generated/doxygen/d2/d6d/ndis_8h-source.html * * IEEE802.11 "Detailed NDIS OID Log for a 802.11b Miniport" * http://www.ndis.com/papers/ieee802_11_log.htm * * FreeBSD (various NDIS related definitions) * http://lists.freebsd.org/pipermail/p4-projects/2004-January/003433.html * * MS WHDC "Network Drivers and Windows" * http://www.microsoft.com/whdc/archive/netdrv_up.mspx * * IEEE "Get IEEE 802" (the various 802.11 docs) * http://standards.ieee.org/getieee802/802.11.html * * MS MSDN "Network Devices: Windows Driver Kit" * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/NetXP_r/hh/NetXP_r/netref_4c297a96-2ba5-41ed-ab21-b7a9cfaa9b4d.xml.asp * * MS MSDN "Microsoft Windows CE .NET 4.2 Network Driver Reference" * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxgrfNetworkDriverReference.asp * * MS MSDN (some explanations of a special MS 802.11 Information Element) * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp * * "WLANINFO fuer Windows XP" * http://www-pc.uni-regensburg.de/systemsw/TOOLS/wlaninfo.htm */ /********************************************************************************/ /* definitions that would usually come from the windows DDK (device driver kit) */ /* and are not part of the ntddndis.h file delivered with WinPcap */ /* Required OIDs */ #define OID_GEN_VLAN_ID 0x0001021C /* Optional OIDs */ #define OID_GEN_MEDIA_CAPABILITIES 0x00010201 #define OID_GEN_PHYSICAL_MEDIUM 0x00010202 /* Optional OIDs */ #define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 #define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 /* Currently associated SSID (OID_802_11_SSID) */ #define NDIS_ESSID_MAX_SIZE 32 struct ndis_essid { ULONG length; UCHAR essid[NDIS_ESSID_MAX_SIZE+1]; }; /* some definitions needed for the following structs */ #define NDIS_MAX_RATES_EX 16 typedef UCHAR mac_address[/* ETH_ALEN */ 6]; typedef UCHAR ndis_rates[NDIS_MAX_RATES_EX]; /* configuration, e.g. frequency (OID_802_11_CONFIGURATION / OID_802_11_BSSID_LIST) */ struct /*packed*/ ndis_configuration { ULONG length; ULONG beacon_period; ULONG atim_window; ULONG ds_config; struct ndis_configuration_fh { ULONG length; ULONG hop_pattern; ULONG hop_set; ULONG dwell_time; } fh_config; }; /* bssid list item (OID_802_11_BSSID_LIST) */ struct ndis_ssid_item { ULONG length; mac_address mac; UCHAR reserved[2]; struct ndis_essid ssid; ULONG privacy; LONG rssi; UINT net_type; struct ndis_configuration config; UINT mode; ndis_rates rates; ULONG ie_length; UCHAR ies[1]; }; /* bssid list (OID_802_11_BSSID_LIST) */ struct ndis_bssid_list { ULONG num_items; struct ndis_ssid_item items[1]; }; /******************************************************************************/ /* OID_TCP_TASK_OFFLOAD specific definitions that would usually come from the */ /* windows DDK (device driver kit) and are not part of the ntddndis.h file */ /* delivered with WinPcap */ /* optional OID */ #define OID_TCP_TASK_OFFLOAD 0xFC010201 /* task id's */ typedef enum _NDIS_TASK { TcpIpChecksumNdisTask, IpSecNdisTask, TcpLargeSendNdisTask, MaxNdisTask } NDIS_TASK, *PNDIS_TASK; /* TaskBuffer content on TcpIpChecksumNdisTask */ typedef struct _NDIS_TASK_TCP_IP_CHECKSUM { struct { ULONG IpOptionsSupported:1; ULONG TcpOptionsSupported:1; ULONG TcpChecksum:1; ULONG UdpChecksum:1; ULONG IpChecksum:1; } V4Transmit; struct { ULONG IpOptionsSupported:1; ULONG TcpOptionsSupported:1; ULONG TcpChecksum:1; ULONG UdpChecksum:1; ULONG IpChecksum:1; } V4Receive; struct { ULONG IpOptionsSupported:1; ULONG TcpOptionsSupported:1; ULONG TcpChecksum:1; ULONG UdpChecksum:1; } V6Transmit; struct { ULONG IpOptionsSupported:1; ULONG TcpOptionsSupported:1; ULONG TcpChecksum:1; ULONG UdpChecksum:1; } V6Receive; } NDIS_TASK_TCP_IP_CHECKSUM, *PNDIS_TASK_TCP_IP_CHECKSUM; /* TaskBuffer content on TcpLargeSendNdisTask */ typedef struct _NDIS_TASK_TCP_LARGE_SEND { ULONG Version; ULONG MaxOffLoadSize; ULONG MinSegmentCount; BOOLEAN TcpOptions; BOOLEAN IpOptions; } NDIS_TASK_TCP_LARGE_SEND, *PNDIS_TASK_TCP_LARGE_SEND; /* Encapsulations */ typedef enum _NDIS_ENCAPSULATION { UNSPECIFIED_Encapsulation, NULL_Encapsulation, IEEE_802_3_Encapsulation, IEEE_802_5_Encapsulation, LLC_SNAP_ROUTED_Encapsulation, LLC_SNAP_BRIDGED_Encapsulation } NDIS_ENCAPSULATION; /* Encapsulation format */ typedef struct _NDIS_ENCAPSULATION_FORMAT { NDIS_ENCAPSULATION Encapsulation; struct { ULONG FixedHeaderSize : 1; ULONG Reserved : 31; } Flags; ULONG EncapsulationHeaderSize; } NDIS_ENCAPSULATION_FORMAT, *PNDIS_ENCAPSULATION_FORMAT; /* request struct */ typedef struct _NDIS_TASK_OFFLOAD_HEADER { ULONG Version; ULONG Size; ULONG Reserved; UCHAR OffsetFirstTask; NDIS_ENCAPSULATION_FORMAT EncapsulationFormat; } NDIS_TASK_OFFLOAD_HEADER, *PNDIS_TASK_OFFLOAD_HEADER; /* response struct */ #define NDIS_TASK_OFFLOAD_VERSION 1 typedef struct _NDIS_TASK_OFFLOAD { ULONG Version; ULONG Size; NDIS_TASK Task; ULONG OffsetNextTask; ULONG TaskBufferLength; UCHAR TaskBuffer[1]; } NDIS_TASK_OFFLOAD, *PNDIS_TASK_OFFLOAD; /***********************************************************************/ /* value_string's for info functions */ /* NDIS driver medium (OID_GEN_MEDIA_SUPPORTED / OID_GEN_MEDIA_IN_USE) */ static const value_string win32_802_3_medium_vals[] = { { NdisMedium802_3, "802.3 (Ethernet)" }, /* might as well be WLAN,... (see NDIS_PHYSICAL_MEDIUM)*/ { NdisMedium802_5, "802.5 (Token Ring)" }, { NdisMediumFddi, "FDDI" }, { NdisMediumWan, "WAN" }, { NdisMediumLocalTalk, "Local Talk" }, { NdisMediumDix, "Dix" }, { NdisMediumArcnetRaw, "Arcnet Raw" }, { NdisMediumArcnet878_2, "Arcnet 878_2" }, { NdisMediumAtm, "ATM" }, { NdisMediumWirelessWan, "Wireless WAN" }, { NdisMediumIrda, "Irda" }, { 0, NULL } }; /* NDIS physical driver medium (OID_GEN_PHYSICAL_MEDIUM) */ static const value_string win32_802_3_physical_medium_vals[] = { { NdisPhysicalMediumUnspecified, "Unspecified" }, { NdisPhysicalMediumWirelessLan, "Wireless LAN" }, { NdisPhysicalMediumCableModem, "Cable Modem (DOCSIS)" }, { NdisPhysicalMediumPhoneLine, "Phone Line" }, { NdisPhysicalMediumPowerLine, "Power Line" }, { NdisPhysicalMediumDSL, "DSL" }, { NdisPhysicalMediumFibreChannel, "Fibre Channel" }, { NdisPhysicalMedium1394, "IEEE 1394" }, { NdisPhysicalMediumWirelessWan, "Wireless WAN" }, { 0, NULL } }; static const value_string win32_802_11_infra_mode_vals[] = { { Ndis802_11IBSS, "Ad Hoc" }, { Ndis802_11Infrastructure, "Access Point" }, { Ndis802_11AutoUnknown, "Auto or unknown" }, { 0, NULL } }; static const value_string win32_802_11_auth_mode_vals[] = { { Ndis802_11AuthModeOpen, "Open System" }, { Ndis802_11AuthModeShared, "Shared Key" }, { Ndis802_11AuthModeAutoSwitch, "Auto Switch" }, { Ndis802_11AuthModeWPA, "WPA" }, { Ndis802_11AuthModeWPAPSK, "WPA-PSK (pre shared key)" }, { Ndis802_11AuthModeWPANone, "WPA (ad hoc)" }, #if (_MSC_VER != 1400) /* These are not defined in Ntddndis.h in MSVC2005/MSVC2005EE PSDK */ { Ndis802_11AuthModeWPA2, "WPA2" }, { Ndis802_11AuthModeWPA2PSK, "WPA2-PSK (pre shared key)" }, #endif { 0, NULL } }; static const value_string win32_802_11_network_type_vals[] = { { Ndis802_11FH, "FH (frequency-hopping spread-spectrum)" }, { Ndis802_11DS, "DS (direct-sequence spread-spectrum)" }, { Ndis802_11OFDM5, "5-GHz OFDM" }, { Ndis802_11OFDM24, "2.4-GHz OFDM" }, #if (_MSC_VER != 1400) /* These are not defined in Ntddndis.h in MSVC2005/MSVC2005EE PSDK */ { Ndis802_11Automode, "Auto" }, #endif { 0, NULL } }; static const value_string win32_802_11_encryption_status_vals[] = { { Ndis802_11Encryption1Enabled, "WEP enabled, TKIP & AES disabled, transmit key available" }, { Ndis802_11EncryptionDisabled, "WEP & TKIP & AES disabled, transmit key available" }, { Ndis802_11Encryption1KeyAbsent, "WEP enabled, TKIP & AES disabled, transmit key unavailable" }, { Ndis802_11EncryptionNotSupported, "WEP & TKIP & AES not supported" }, { Ndis802_11Encryption2Enabled, "WEP & TKIP enabled, AES disabled, transmit key available" }, { Ndis802_11Encryption2KeyAbsent, "WEP & TKIP enabled, AES disabled, transmit key unavailable" }, { Ndis802_11Encryption3Enabled, "WEP & TKIP & AES enabled, transmit key available" }, { Ndis802_11Encryption3KeyAbsent, "WEP & TKIP & AES enabled, transmit key unavailable" }, { 0, NULL } }; /* frequency to channel mapping (OID_802_11_CONFIGURATION) */ static const value_string win32_802_11_channel_freq_vals[] = { { 2412000, "1 (2412 MHz)" }, { 2417000, "2 (2417 MHz)" }, { 2422000, "3 (2422 MHz)" }, { 2427000, "4 (2427 MHz)" }, { 2432000, "5 (2432 MHz)" }, { 2437000, "6 (2437 MHz)" }, { 2442000, "7 (2442 MHz)" }, { 2447000, "8 (2447 MHz)" }, { 2452000, "9 (2452 MHz)" }, { 2457000, "10 (2457 MHz)" }, { 2462000, "11 (2462 MHz)" }, { 2467000, "12 (2467 MHz)" }, { 2472000, "13 (2472 MHz)" }, { 2484000, "14 (2484 MHz)" }, { 0, NULL } }; /* frequency to channel mapping (OID_802_11_CONFIGURATION) */ static const value_string win32_802_11_channel_vals[] = { { 2412000, "1" }, { 2417000, "2" }, { 2422000, "3" }, { 2427000, "4" }, { 2432000, "5" }, { 2437000, "6" }, { 2442000, "7" }, { 2447000, "8" }, { 2452000, "9" }, { 2457000, "10" }, { 2462000, "11" }, { 2467000, "12" }, { 2472000, "13" }, { 2484000, "14" }, { 0, NULL } }; /* Information Element IDs (802.11 Spec: "7.3.2 Information elements") */ #define IE_ID_SSID 0 #define IE_ID_SUPPORTED_RATES 1 #define IE_ID_DS_PARAMETER_SET 3 #define IE_ID_TIM 5 #define IE_ID_COUNTRY 7 #define IE_ID_ERP_INFORMATION 42 #define IE_ID_WPA2 48 #define IE_ID_EXTENDED_SUPPORT_RATES 50 #define IE_ID_VENDOR_SPECIFIC 221 #ifdef DEBUG_IE /* ElementID in NDIS_802_11_VARIABLE_IEs */ static const value_string ie_id_vals[] = { { IE_ID_SSID, "SSID, 802.11" }, { IE_ID_SUPPORTED_RATES, "Supported Rates, 802.11" }, { 2, "FH Parameter Set, 802.11" }, { IE_ID_DS_PARAMETER_SET, "DS Parameter Set, 802.11" }, { 4, "CF Parameter Set, 802.11" }, { IE_ID_TIM, "TIM, 802.11" }, { 6, "IBSS Parameter Set, 802.11" }, { IE_ID_COUNTRY, "Country, 802.11d" }, { 8, "Hopping Pattern Parameters, 802.11d" }, { 9, "Hopping Pattern Table, 802.11d" }, { 10, "Request, 802.11d" }, /* 11-15 reserved, 802.11d */ { 16, "Challenge text, 802.11" }, /* 17-31 reserved, 802.11h */ { 32, "Power Constraint, 802.11h" }, { 33, "Power Capability, 802.11h" }, { 34, "TPC Request, 802.11h" }, { 35, "TPC Report, 802.11h" }, { 36, "Supported Channels, 802.11h" }, { 37, "Channel Switch Announcement, 802.11h" }, { 38, "Measurement Request, 802.11h" }, { 39, "Measurement Report, 802.11h" }, { 40, "Quiet, 802.11h" }, { 41, "IBSS DFS, 802.11h" }, { IE_ID_ERP_INFORMATION, "ERP information, 802.11g" }, /* 43-47 reserved, 802.11i */ { IE_ID_WPA2, "WPA2/RSN (Robust Secure Network), 802.11i" }, /* 49 reserved, 802.11i */ { IE_ID_EXTENDED_SUPPORT_RATES, "Extended Supported Rates, 802.11g" }, /* 51-255 reserved, 802.11g */ { IE_ID_VENDOR_SPECIFIC, "WPA, (not 802.11!)" }, { 0, NULL } }; #endif #if 0 static const value_string oid_vals[] = { { OID_GEN_SUPPORTED_LIST, "OID_GEN_SUPPORTED_LIST" }, { OID_GEN_HARDWARE_STATUS, "OID_GEN_HARDWARE_STATUS (only internally interesting)" }, { OID_GEN_MEDIA_SUPPORTED, "OID_GEN_MEDIA_SUPPORTED" }, { OID_GEN_MEDIA_IN_USE, "OID_GEN_MEDIA_IN_USE" }, { OID_GEN_MAXIMUM_LOOKAHEAD, "OID_GEN_MAXIMUM_LOOKAHEAD (unused)" }, { OID_GEN_MAXIMUM_FRAME_SIZE, "OID_GEN_MAXIMUM_FRAME_SIZE (unused)" }, { OID_GEN_LINK_SPEED, "OID_GEN_LINK_SPEED" }, { OID_GEN_TRANSMIT_BUFFER_SPACE, "OID_GEN_TRANSMIT_BUFFER_SPACE" }, { OID_GEN_RECEIVE_BUFFER_SPACE, "OID_GEN_RECEIVE_BUFFER_SPACE" }, { OID_GEN_TRANSMIT_BLOCK_SIZE, "OID_GEN_TRANSMIT_BLOCK_SIZE" }, { OID_GEN_RECEIVE_BLOCK_SIZE, "OID_GEN_RECEIVE_BLOCK_SIZE" }, { OID_GEN_VENDOR_ID, "OID_GEN_VENDOR_ID" }, { OID_GEN_VENDOR_DESCRIPTION, "OID_GEN_VENDOR_DESCRIPTION" }, { OID_GEN_CURRENT_PACKET_FILTER, "OID_GEN_CURRENT_PACKET_FILTER (info seems to be constant)" }, { OID_GEN_CURRENT_LOOKAHEAD, "OID_GEN_CURRENT_LOOKAHEAD (only internally interesting)" }, { OID_GEN_DRIVER_VERSION, "OID_GEN_DRIVER_VERSION" }, { OID_GEN_MAXIMUM_TOTAL_SIZE, "OID_GEN_MAXIMUM_TOTAL_SIZE" }, { OID_GEN_PROTOCOL_OPTIONS, "OID_GEN_PROTOCOL_OPTIONS (info not interesting)" }, { OID_GEN_MAC_OPTIONS, "OID_GEN_MAC_OPTIONS" }, { OID_GEN_MEDIA_CONNECT_STATUS, "OID_GEN_MEDIA_CONNECT_STATUS" }, { OID_GEN_MAXIMUM_SEND_PACKETS, "OID_GEN_MAXIMUM_SEND_PACKETS (only internally interesting)" }, { OID_GEN_VENDOR_DRIVER_VERSION, "OID_GEN_VENDOR_DRIVER_VERSION" }, { OID_GEN_XMIT_OK, "OID_GEN_XMIT_OK" }, { OID_GEN_RCV_OK, "OID_GEN_RCV_OK" }, { OID_GEN_XMIT_ERROR, "OID_GEN_XMIT_ERROR" }, { OID_GEN_RCV_ERROR, "OID_GEN_RCV_ERROR" }, { OID_GEN_RCV_NO_BUFFER, "OID_GEN_RCV_NO_BUFFER" }, { OID_GEN_DIRECTED_BYTES_XMIT, "OID_GEN_DIRECTED_BYTES_XMIT" }, { OID_GEN_DIRECTED_FRAMES_XMIT, "OID_GEN_DIRECTED_FRAMES_XMIT" }, { OID_GEN_MULTICAST_BYTES_XMIT, "OID_GEN_MULTICAST_BYTES_XMIT" }, { OID_GEN_MULTICAST_FRAMES_XMIT, "OID_GEN_MULTICAST_FRAMES_XMIT" }, { OID_GEN_BROADCAST_BYTES_XMIT, "OID_GEN_BROADCAST_BYTES_XMIT" }, { OID_GEN_BROADCAST_FRAMES_XMIT, "OID_GEN_BROADCAST_FRAMES_XMIT" }, { OID_GEN_DIRECTED_BYTES_RCV, "OID_GEN_DIRECTED_BYTES_RCV" }, { OID_GEN_DIRECTED_FRAMES_RCV, "OID_GEN_DIRECTED_FRAMES_RCV" }, { OID_GEN_MULTICAST_BYTES_RCV, "OID_GEN_MULTICAST_BYTES_RCV" }, { OID_GEN_MULTICAST_FRAMES_RCV, "OID_GEN_MULTICAST_FRAMES_RCV" }, { OID_GEN_BROADCAST_BYTES_RCV, "OID_GEN_BROADCAST_BYTES_RCV" }, { OID_GEN_BROADCAST_FRAMES_RCV, "OID_GEN_BROADCAST_FRAMES_RCV" }, { OID_GEN_RCV_CRC_ERROR, "OID_GEN_RCV_CRC_ERROR" }, { OID_GEN_TRANSMIT_QUEUE_LENGTH, "OID_GEN_TRANSMIT_QUEUE_LENGTH" }, { OID_GEN_GET_TIME_CAPS, "OID_GEN_GET_TIME_CAPS (unsupp, unused)" }, { OID_GEN_GET_NETCARD_TIME, "OID_GEN_GET_NETCARD_TIME (unsupp, unused)" }, { OID_GEN_PHYSICAL_MEDIUM, "OID_GEN_PHYSICAL_MEDIUM" }, /*{ OID_GEN_MACHINE_NAME, "OID_GEN_MACHINE_NAME (unsupp, unused)" },*/ { OID_GEN_VLAN_ID, "OID_GEN_VLAN_ID" }, { OID_GEN_MEDIA_CAPABILITIES, "OID_GEN_MEDIA_CAPABILITIES (unsupp, unused)" }, { OID_GEN_NETWORK_LAYER_ADDRESSES, "OID_GEN_NETWORK_LAYER_ADDRESSES (write only)" }, { OID_GEN_TRANSPORT_HEADER_OFFSET, "OID_GEN_TRANSPORT_HEADER_OFFSET (write only)" }, { OID_802_3_PERMANENT_ADDRESS, "OID_802_3_PERMANENT_ADDRESS" }, { OID_802_3_CURRENT_ADDRESS, "OID_802_3_CURRENT_ADDRESS" }, { OID_802_3_MAXIMUM_LIST_SIZE, "OID_802_3_MAXIMUM_LIST_SIZE (unused)" }, { OID_802_3_MULTICAST_LIST, "OID_802_3_MULTICAST_LIST (unused)" }, /* XXX */ { OID_802_3_MAC_OPTIONS, "OID_802_3_MAC_OPTIONS (unsupp, unused)" }, { OID_802_3_RCV_ERROR_ALIGNMENT, "OID_802_3_RCV_ERROR_ALIGNMENT" }, { OID_802_3_XMIT_ONE_COLLISION, "OID_802_3_XMIT_ONE_COLLISION" }, { OID_802_3_XMIT_MORE_COLLISIONS, "OID_802_3_XMIT_MORE_COLLISIONS" }, { OID_802_3_XMIT_DEFERRED, "OID_802_3_XMIT_DEFERRED" }, { OID_802_3_XMIT_MAX_COLLISIONS, "OID_802_3_XMIT_MAX_COLLISIONS" }, { OID_802_3_RCV_OVERRUN, "OID_802_3_RCV_OVERRUN" }, { OID_802_3_XMIT_UNDERRUN, "OID_802_3_XMIT_UNDERRUN" }, { OID_802_3_XMIT_HEARTBEAT_FAILURE, "OID_802_3_XMIT_HEARTBEAT_FAILURE (unsupp, used)" }, { OID_802_3_XMIT_TIMES_CRS_LOST, "OID_802_3_XMIT_TIMES_CRS_LOST (unsupp, used)" }, { OID_802_3_XMIT_LATE_COLLISIONS, "OID_802_3_XMIT_LATE_COLLISIONS" }, { OID_802_11_BSSID, "OID_802_11_BSSID" }, { OID_802_11_SSID, "OID_802_11_SSID" }, { OID_802_11_NETWORK_TYPES_SUPPORTED, "OID_802_11_NETWORK_TYPES_SUPPORTED (info not interesting)" }, { OID_802_11_NETWORK_TYPE_IN_USE, "OID_802_11_NETWORK_TYPE_IN_USE" }, { OID_802_11_TX_POWER_LEVEL, "OID_802_11_TX_POWER_LEVEL (unsupp, used)" }, { OID_802_11_RSSI, "OID_802_11_RSSI" }, { OID_802_11_RSSI_TRIGGER, "OID_802_11_RSSI_TRIGGER (unsupp, unused)" }, { OID_802_11_INFRASTRUCTURE_MODE, "OID_802_11_INFRASTRUCTURE_MODE" }, { OID_802_11_FRAGMENTATION_THRESHOLD, "OID_802_11_FRAGMENTATION_THRESHOLD (unused)" }, { OID_802_11_RTS_THRESHOLD, "OID_802_11_RTS_THRESHOLD (unused)" }, { OID_802_11_NUMBER_OF_ANTENNAS, "OID_802_11_NUMBER_OF_ANTENNAS (unsupp, unused)" }, { OID_802_11_RX_ANTENNA_SELECTED, "OID_802_11_RX_ANTENNA_SELECTED (unsupp, unused)" }, { OID_802_11_TX_ANTENNA_SELECTED, "OID_802_11_TX_ANTENNA_SELECTED (unsupp, unused)" }, { OID_802_11_SUPPORTED_RATES, "OID_802_11_SUPPORTED_RATES" }, { OID_802_11_DESIRED_RATES, "OID_802_11_DESIRED_RATES (unsupp, used)" }, { OID_802_11_CONFIGURATION, "OID_802_11_CONFIGURATION" }, { OID_802_11_STATISTICS, "OID_802_11_STATISTICS (unsupp, unused)" }, { OID_802_11_ADD_WEP, "OID_802_11_ADD_WEP (write only)" }, { OID_802_11_REMOVE_WEP, "OID_802_11_REMOVE_WEP (write only)" }, { OID_802_11_DISASSOCIATE, "OID_802_11_DISASSOCIATE (write only)" }, { OID_802_11_POWER_MODE, "OID_802_11_POWER_MODE (info not interesting)" }, { OID_802_11_BSSID_LIST, "OID_802_11_BSSID_LIST" }, { OID_802_11_AUTHENTICATION_MODE, "OID_802_11_AUTHENTICATION_MODE" }, { OID_802_11_PRIVACY_FILTER, "OID_802_11_PRIVACY_FILTER (info not interesting)" }, { OID_802_11_BSSID_LIST_SCAN, "OID_802_11_BSSID_LIST_SCAN" }, { OID_802_11_WEP_STATUS, "OID_802_11_WEP_STATUS (info not interesting?)" }, { OID_802_11_ENCRYPTION_STATUS, "OID_802_11_ENCRYPTION_STATUS (unsupp, used)" }, { OID_802_11_RELOAD_DEFAULTS, "OID_802_11_RELOAD_DEFAULTS (write only)" }, { OID_802_11_ADD_KEY, "OID_802_11_ADD_KEY (write only)" }, { OID_802_11_REMOVE_KEY, "OID_802_11_REMOVE_KEY (write only)" }, { OID_802_11_ASSOCIATION_INFORMATION, "OID_802_11_ASSOCIATION_INFORMATION (unused)" }, /* XXX */ { OID_802_11_TEST, "OID_802_11_TEST (write only)" }, #if (_MSC_VER != 1400) /* These are not defined in Ntddndis.h in MSVC2005/MSVC2005EE PSDK */ { OID_802_11_CAPABILITY, "OID_802_11_CAPABILITY (unsupp, unused)" }, { OID_802_11_PMKID, "OID_802_11_PMKID (unsupp, unused)" }, #endif /* Token-Ring list is utterly incomplete (contains only the values for MS Loopback Driver) */ { OID_802_5_PERMANENT_ADDRESS, "OID_802_5_PERMANENT_ADDRESS (unused)" }, { OID_802_5_CURRENT_ADDRESS, "OID_802_5_CURRENT_ADDRESS (unused)" }, { OID_802_5_CURRENT_FUNCTIONAL, "OID_802_5_CURRENT_FUNCTIONAL (unused)" }, { OID_802_5_CURRENT_GROUP, "OID_802_5_CURRENT_GROUP (unused)" }, { OID_802_5_LAST_OPEN_STATUS, "OID_802_5_LAST_OPEN_STATUS (unused)" }, { OID_802_5_CURRENT_RING_STATUS, "OID_802_5_CURRENT_RING_STATUS (unused)" }, { OID_802_5_CURRENT_RING_STATE, "OID_802_5_CURRENT_RING_STATE (unused)" }, { OID_802_5_LINE_ERRORS, "OID_802_5_LINE_ERRORS (unused)" }, { OID_802_5_LOST_FRAMES, "OID_802_5_LOST_FRAMES (unused)" }, /* FDDI list is utterly incomplete (contains only the values for MS Loopback Driver) */ { OID_FDDI_LONG_PERMANENT_ADDR, "OID_FDDI_LONG_PERMANENT_ADDR (unused)" }, { OID_FDDI_LONG_CURRENT_ADDR, "OID_FDDI_LONG_CURRENT_ADDR (unused)" }, { OID_FDDI_LONG_MULTICAST_LIST, "OID_FDDI_LONG_MULTICAST_LIST (unused)" }, { OID_FDDI_LONG_MAX_LIST_SIZE, "OID_FDDI_LONG_MAX_LIST_SIZE (unused)" }, { OID_FDDI_SHORT_PERMANENT_ADDR, "OID_FDDI_SHORT_PERMANENT_ADDR (unused)" }, { OID_FDDI_SHORT_CURRENT_ADDR, "OID_FDDI_SHORT_CURRENT_ADDR (unused)" }, { OID_FDDI_SHORT_MULTICAST_LIST, "OID_FDDI_SHORT_MULTICAST_LIST (unused)" }, { OID_FDDI_SHORT_MAX_LIST_SIZE, "OID_FDDI_SHORT_MAX_LIST_SIZE (unused)" }, /* LocalTalk list is utterly incomplete (contains only the values for MS Loopback Driver) */ { OID_LTALK_CURRENT_NODE_ID, "OID_LTALK_CURRENT_NODE_ID (unused)" }, /* Arcnet list is utterly incomplete (contains only the values for MS Loopback Driver) */ { OID_ARCNET_PERMANENT_ADDRESS, "OID_ARCNET_PERMANENT_ADDRESS (unused)" }, { OID_ARCNET_CURRENT_ADDRESS, "OID_ARCNET_CURRENT_ADDRESS (unused)" }, { OID_TCP_TASK_OFFLOAD, "OID_TCP_TASK_OFFLOAD" }, /* PnP and power management OIDs */ { OID_PNP_CAPABILITIES, "OID_PNP_CAPABILITIES (unused)" }, { OID_PNP_SET_POWER, "OID_PNP_SET_POWER (write only)" }, { OID_PNP_QUERY_POWER, "OID_PNP_QUERY_POWER (unused)" }, { OID_PNP_ADD_WAKE_UP_PATTERN, "OID_PNP_ADD_WAKE_UP_PATTERN (write only)" }, { OID_PNP_REMOVE_WAKE_UP_PATTERN, "OID_PNP_REMOVE_WAKE_UP_PATTERN (write only)" }, { OID_PNP_WAKE_UP_PATTERN_LIST, "OID_PNP_WAKE_UP_PATTERN_LIST (unused)" }, { OID_PNP_ENABLE_WAKE_UP, "OID_PNP_ENABLE_WAKE_UP (unused)" }, /* Unknown OID's (seen on an "Intel(R) PRO/Wireless 2200BG" 802.11 interface) */ { 0xFF100000, "Unknown 0xFF100000 (unused)" }, { 0xFF100002, "Unknown 0xFF100002 (unused)" }, { 0xFF100003, "Unknown 0xFF100003 (unused)" }, { 0xFF100004, "Unknown 0xFF100004 (unused)" }, { 0xFF100005, "Unknown 0xFF100005 (unused)" }, { 0xFF100006, "Unknown 0xFF100006 (unused)" }, { 0xFF100007, "Unknown 0xFF100007 (unused)" }, { 0xFF100009, "Unknown 0xFF100009 (unused)" }, { 0xFF10000b, "Unknown 0xFF10000b (unused)" }, { 0xFF10000c, "Unknown 0xFF10000c (unused)" }, { 0xFF10000e, "Unknown 0xFF10000e (unused)" }, { 0xFF10000f, "Unknown 0xFF10000f (unused)" }, /* continued by a lot more 0xFF... values */ { 0, NULL } }; #endif /***************************************************************************/ /* debug functions, query or list supported NDIS OID's */ #if 0 static void supported_list(LPADAPTER adapter) { unsigned char values[10000]; int length; g_warning("supported_list_unhandled"); length = sizeof(values); if (wpcap_packet_request(adapter, OID_GEN_SUPPORTED_LIST, FALSE /* !set */, values, &length)) { guint32 *value = (guint32 *)values; while (length >= 4) { printf("OID: 0x%08X %s\n", *value, val_to_str(*value, oid_vals, "unknown")); value++; length -= 4; } } } static gboolean supported_query_oid(LPADAPTER adapter, guint32 oid) { unsigned char values[10000]; int length; length = sizeof(values); if (wpcap_packet_request(adapter, OID_GEN_SUPPORTED_LIST, FALSE /* !set */, values, &length)) { guint32 *value = (guint32 *) values; while (length >= 4) { if (*value == oid) { return TRUE; } value++; length -= 4; } } return FALSE; } #endif /******************************************************************************/ /* info functions, get and display various NDIS driver values */ #if 0 GtkWidget *meter; GtkWidget *val_lb; static GtkWidget * add_meter_to_grid(GtkWidget *grid, guint *row, gchar *title, int value, gchar *value_title, int min, int max, int yellow_level, GList *scale) { GtkWidget *label; gchar *indent; GtkWidget *main_hb; /* the label */ indent = g_strdup_printf(" %s", title); label = gtk_label_new(indent); g_free(indent); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); ws_gtk_grid_attach_extended(GTK_GRID(grid), label, 0, *row, 1, 1, GTK_EXPAND|GTK_FILL, 0, 0,0); /* the level meter */ main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6, FALSE); meter = gtk_vumeter_new (); gtk_vumeter_set_orientation(GTK_VUMETER(meter), GTK_VUMETER_LEFT_TO_RIGHT); gtk_vumeter_set_min_max(GTK_VUMETER(meter), &min, &max); gtk_vumeter_set_yellow_level (GTK_VUMETER(meter), yellow_level); gtk_vumeter_set_thickness (GTK_VUMETER(meter), 10); gtk_vumeter_set_thickness_reduction (GTK_VUMETER(meter), 2); gtk_vumeter_set_scale_hole_size (GTK_VUMETER(meter), 2); gtk_vumeter_set_colors_inverted (GTK_VUMETER(meter), TRUE); if (scale) { gtk_vumeter_set_scale_items(GTK_VUMETER(meter), scale); } gtk_vumeter_set_level(GTK_VUMETER(meter), value); gtk_box_pack_start (GTK_BOX(main_hb), meter, TRUE /*expand*/, TRUE /*fill*/, 0 /* padding */); val_lb = gtk_label_new(value_title); gtk_widget_set_size_request(val_lb, 50, -1); gtk_misc_set_alignment(GTK_MISC(val_lb), 1.0, 0.5); gtk_box_pack_start (GTK_BOX(main_hb), val_lb, FALSE /*expand*/, FALSE /*fill*/, 0 /* padding */); ws_gtk_grid_attach_extended(GTK_GRID(grid), main_hb, 1, *row, 1, 1, GTK_EXPAND|GTK_FILL, 0, 0,0); *row += 1; return meter; } #endif static void add_row_to_grid(GtkWidget *grid, guint *row, gchar *title, const gchar *value, gboolean sensitive) { GtkWidget *label; gchar *indent; if (strlen(value) != 0) { indent = g_strdup_printf(" %s", title); } else { indent = g_strdup(title); } label = gtk_label_new(indent); g_free(indent); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_widget_set_sensitive(label, sensitive); ws_gtk_grid_attach_extended(GTK_GRID(grid), label, 0, *row, 1, 1, GTK_EXPAND | GTK_FILL, 0, 0,0); label = gtk_label_new(value); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_widget_set_sensitive(label, sensitive); ws_gtk_grid_attach_extended(GTK_GRID(grid), label, 1, *row, 1, 1, GTK_EXPAND | GTK_FILL, 0, 0,0); *row += 1; } #if 0 static void add_string_to_grid_sensitive(GtkWidget *grid, guint *row, gchar *title, gchar *value, gboolean sensitive) { add_row_to_grid(grid, row, title, value, sensitive); } #endif static void add_string_to_grid(GtkWidget *grid, guint *row, gchar *title, const gchar *value) { add_row_to_grid(grid, row, title, value, TRUE); } static void ssid_details(GtkWidget *grid, guint *row, struct ndis_essid *ssid_in) { struct ndis_essid ssid[2]; /* prevent an off by one error */ ssid[0] = *ssid_in; g_assert(ssid->length <= NDIS_ESSID_MAX_SIZE); if (ssid->length != 0) { ssid->essid[ssid->length] = '\0'; add_string_to_grid(grid, row, "SSID (Service Set IDentifier)", ssid->essid); } else { add_string_to_grid(grid, row, "SSID (Service Set IDentifier)", "(currently not associated with an SSID)"); } } static GString * rates_details(unsigned char *values, int length) { int i; GString *Rates; float float_value; int int_value; Rates = g_string_new(""); if (length != 0) { i = 0; while (length--) { if (values[i]) { if (i != 0) { g_string_append(Rates, "/"); } float_value = ((float) (values[i] & 0x7F)) / 2; /* reduce the screen estate by showing fractions only where required */ int_value = (int)float_value; if (float_value == (float)int_value) { g_string_append_printf(Rates, "%.0f", float_value); } else { g_string_append_printf(Rates, "%.1f", float_value); } } i++; } Rates = g_string_append(Rates, " MBits/s"); } else { Rates = g_string_append(Rates, "-"); } return Rates; } #if 0 static GList * rates_vu_list(unsigned char *values, int length, int *max) { int i; GList *Rates = NULL; GtkVUMeterScaleItem *item; *max = 0; if (length == 0) { return NULL; } /* add a zero scale point */ item = g_malloc(sizeof(GtkVUMeterScaleItem)); item->level = 0; item->large = TRUE; item->label = "0"; Rates = g_list_append(Rates, item); /* get the maximum rate */ for(i=0; i *max) { *max = level; } } } /* debug: fake the 108MBit entry (I don't own one :-) */ *max = 108; item = g_malloc(sizeof(GtkVUMeterScaleItem)); item->level = 108; item->large = TRUE; item->label = "108"; Rates = g_list_append(Rates, item); for(i=0; ilevel = (values[i] & 0x7F) / 2; /* common data rates: */ /* 802.11 (15.1) : mandatory: 2, 1 */ /* 802.11a (17.1) : mandatory: 24, 12, 6 optional: 54, 48, 36, 18, 9 */ /* 802.11b (18.1) : mandatory: 11, 5.5 (+ 2, 1) */ /* 802.11g (19.1.1): mandatory: 24, 12, 11, 6, 5.5, 2, 1 optional: 54, 48, 36, 33, 22, 18, 9 */ /* 802.11n: ? */ /* proprietary: 108 */ switch (item->level) { case 2: if (*max >= 108) { item->large = FALSE; item->label = NULL; } else { item->large = TRUE; item->label = "2"; } break; case 5: item->large = TRUE; item->label = "5.5"; break; case 11: item->large = TRUE; item->label = "11"; break; case 18: item->large = TRUE; item->label = "18"; break; case 24: item->large = TRUE; item->label = "24"; break; case 36: item->large = TRUE; item->label = "36"; break; case 48: item->large = TRUE; item->label = "48"; break; case 54: item->large = TRUE; item->label = "54"; break; case 72: /* XXX */ item->large = TRUE; item->label = "72"; break; case 96: /* XXX */ item->large = TRUE; item->label = "96"; break; case 108: item->large = TRUE; item->label = "108"; break; default: item->large = FALSE; item->label = NULL; } Rates = g_list_append(Rates, item); } } return Rates; } #endif /* debugging only */ static void hex(unsigned char *p, int len) { int i = 0; while (len) { g_warning("%u: 0x%x (%u) '%c'", i, *p, *p, isprint(*p) ? *p : '.'); i++; p++; len--; } } static void capture_if_details_802_11_bssid_list(GtkWidget *main_vb, struct ndis_bssid_list *bssid_list) { struct ndis_ssid_item *bssid_item; unsigned char mac[6]; const gchar *manuf_name; GString *Rates; if (bssid_list->num_items != 0) { static const char *titles[] = { "SSID", "MAC", "Vendor", "Privacy", "RSSI" , "Network Type" , "Infra. Mode" , "Ch." , "Rates", "Country" }; GtkWidget *list; gboolean privacy_required; gboolean privacy_wpa; gboolean privacy_wpa2; gchar ssid_buff [DETAILS_STR_MAX]; gchar mac_buff [DETAILS_STR_MAX]; gchar vendor_buff [DETAILS_STR_MAX]; gchar privacy_buff [DETAILS_STR_MAX]; gchar rssi_buff [DETAILS_STR_MAX]; gchar nettype_buff [DETAILS_STR_MAX]; gchar infra_buff [DETAILS_STR_MAX]; gchar freq_buff [DETAILS_STR_MAX]; gchar country_buff [DETAILS_STR_MAX] = ""; list = simple_list_new(10, titles); gtk_box_pack_start(GTK_BOX(main_vb), list, TRUE /*expand*/, TRUE /*fill*/, 0 /* padding */); bssid_item = &bssid_list->items[0]; while (bssid_list->num_items--) { privacy_required = FALSE; privacy_wpa = FALSE; privacy_wpa2 = FALSE; /* SSID */ if (bssid_item->ssid.length > DETAILS_STR_MAX-1) { bssid_item->ssid.length = DETAILS_STR_MAX-1; } memcpy(ssid_buff, bssid_item->ssid.essid, bssid_item->ssid.length); ssid_buff[bssid_item->ssid.length] = '\0'; /* MAC */ memcpy(mac, &bssid_item->mac, sizeof(mac)); g_snprintf(mac_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); /* Vendor */ manuf_name = get_manuf_name_if_known(mac); if (manuf_name != NULL) { g_strlcpy(vendor_buff, manuf_name, DETAILS_STR_MAX); } else { vendor_buff[0] = '\0'; } /* Supported Rates */ Rates = rates_details(bssid_item->rates, NDIS_MAX_RATES_EX); /* RSSI */ g_snprintf(rssi_buff, DETAILS_STR_MAX, "%d dBm", bssid_item->rssi); /* Privacy */ /* (flag is set, if WEP (or higher) privacy is required) */ if (bssid_item->privacy) { privacy_required = TRUE; } /* Network Type */ g_snprintf(nettype_buff, sizeof(nettype_buff), "%s", val_to_str(bssid_item->net_type, win32_802_11_network_type_vals, "(0x%x)")); /* Infrastructure Mode */ g_snprintf(infra_buff, sizeof(infra_buff), "%s", val_to_str(bssid_item->mode, win32_802_11_infra_mode_vals, "(0x%x)")); /* Channel */ g_snprintf(freq_buff, sizeof(freq_buff), "%s", val_to_str(bssid_item->config.ds_config, win32_802_11_channel_vals, "(%u kHz)")); /* XXX - IE Length is currently not really supported here */ { int len = bssid_item->ie_length; unsigned char *iep = bssid_item->ies; unsigned char id; guint el_len; NDIS_802_11_FIXED_IEs *fixed_ies; /*#define DEBUG_IE*/ #ifdef DEBUG_IE const gchar *manuf_name; gchar string_buff[DETAILS_STR_MAX]; #endif fixed_ies = (NDIS_802_11_FIXED_IEs *)iep; /** UCHAR Timestamp[8]; USHORT BeaconInterval; USHORT Capabilities; } NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; **/ iep += sizeof(NDIS_802_11_FIXED_IEs); len = bssid_item->ie_length - sizeof(NDIS_802_11_FIXED_IEs); while (len >= 2) { id = *iep; iep++; el_len = *iep; iep++; len -= 2; #ifdef DEBUG_IE g_warning("ID: %s (%u) Len: %u", val_to_str(id, ie_id_vals, "0x%x"), id, el_len); #endif switch (id) { case(IE_ID_COUNTRY): if (el_len >= 6) g_snprintf(country_buff, sizeof(country_buff), "%c%c: Ch: %u-%u Max: %ddBm", iep[0], iep[1], iep[3], iep[4], iep[5]); break; case(IE_ID_WPA2): privacy_wpa2 = TRUE; break; case(IE_ID_VENDOR_SPECIFIC): /* WPA */ privacy_wpa = TRUE; #ifdef DEBUG_IE /* include information from epan/packet-ieee80211.c dissect_vendor_ie_wpawme() */ manuf_name = get_manuf_name_if_known(iep); if (manuf_name != NULL) { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X (%s) Type: %02X", *(iep), *(iep+1), *(iep+2), manuf_name, *(iep+3)); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X Type: %02X", *(iep), *(iep+1), *(iep+2), *(iep+3)); } g_warning("%s", string_buff); iep += 4; el_len-= 4; len -= 4; g_warning("WPA IE: %u", id); hex(iep, el_len); #endif break; case(IE_ID_SSID): case(IE_ID_SUPPORTED_RATES): case(IE_ID_DS_PARAMETER_SET): case(IE_ID_TIM): case(IE_ID_ERP_INFORMATION): case(IE_ID_EXTENDED_SUPPORT_RATES): /* we already have that data, do nothing */ break; default: /* unexpected IE_ID, print out hexdump */ g_warning("Unknown IE ID: %u Len: %u", id, el_len); hex(iep, el_len); } iep += el_len; len -= el_len; } } if (privacy_required) { if (privacy_wpa2) { /* XXX - how to detect data encryption (TKIP and AES)? */ /* XXX - how to detect authentication (PSK or not)? */ g_snprintf(privacy_buff, DETAILS_STR_MAX, "WPA2"); } else { if (privacy_wpa) { /* XXX - how to detect data encryption (TKIP and AES)? */ /* XXX - how to detect authentication (PSK or not)? */ g_snprintf(privacy_buff, DETAILS_STR_MAX, "WPA"); } else { /* XXX - how to detect authentication (Open System and Shared Key)? */ g_snprintf(privacy_buff, DETAILS_STR_MAX, "WEP"); } } } else { g_snprintf(privacy_buff, DETAILS_STR_MAX, "None"); } simple_list_append(list, 0, ssid_buff, 1, mac_buff, 2, vendor_buff, 3, privacy_buff, 4, rssi_buff, 5, nettype_buff, 6, infra_buff, 7, freq_buff, 8, Rates->str, 9, country_buff, -1); g_string_free(Rates, TRUE /* free_segment */); /* the bssid_list isn't an array, but a sequence of variable length items */ bssid_item = (struct ndis_ssid_item *) (((char *) bssid_item) + bssid_item->length); } } } static int capture_if_details_802_11(GtkWidget *grid, GtkWidget *main_vb, guint *row, LPADAPTER adapter) { ULONG ulong_value; LONG rssi = -100; unsigned int uint_value; unsigned char values[100]; struct ndis_essid ssid; int length; gchar string_buff[DETAILS_STR_MAX]; GString *Rates; int entries = 0; const gchar *manuf_name; struct ndis_bssid_list *bssid_list; struct ndis_configuration *configuration; add_string_to_grid(grid, row, "Current network", ""); /* SSID */ length = sizeof(struct ndis_essid); memset(&ssid, 0, length); if (wpcap_packet_request(adapter, OID_802_11_SSID, FALSE /* !set */, (char *) &ssid, &length)) { ssid_details(grid, row, &ssid); entries++; } else { add_string_to_grid(grid, row, "SSID (Service Set IDentifier)", "-"); } /* BSSID */ length = sizeof(values); memset(values, 0, 6); if (wpcap_packet_request(adapter, OID_802_11_BSSID, FALSE /* !set */, values, &length)) { manuf_name = get_manuf_name_if_known(values); if (manuf_name != NULL) { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)", values[0], values[1], values[2], values[3], values[4], values[5], manuf_name); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X", values[0], values[1], values[2], values[3], values[4], values[5]); } entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "BSSID (Basic Service Set IDentifier)", string_buff); /* Network type in use */ if (wpcap_packet_request_uint(adapter, OID_802_11_NETWORK_TYPE_IN_USE, &uint_value)) { add_string_to_grid(grid, row, "Network type used", val_to_str(uint_value, win32_802_11_network_type_vals, "(0x%x)")); entries++; } else { add_string_to_grid(grid, row, "Network type used", "-"); } /* Infrastructure mode */ if (wpcap_packet_request_ulong(adapter, OID_802_11_INFRASTRUCTURE_MODE, &uint_value)) { add_string_to_grid(grid, row, "Infrastructure mode", val_to_str(uint_value, win32_802_11_infra_mode_vals, "(0x%x)")); entries++; } else { add_string_to_grid(grid, row, "Infrastructure mode", "-"); } /* Authentication mode */ if (wpcap_packet_request_ulong(adapter, OID_802_11_AUTHENTICATION_MODE, &uint_value)) { add_string_to_grid(grid, row, "Authentication mode", val_to_str(uint_value, win32_802_11_auth_mode_vals, "(0x%x)")); entries++; } else { add_string_to_grid(grid, row, "Authentication mode", "-"); } /* Encryption (WEP) status */ if (wpcap_packet_request_ulong(adapter, OID_802_11_ENCRYPTION_STATUS, &uint_value)) { add_string_to_grid(grid, row, "Encryption status", val_to_str(uint_value, win32_802_11_encryption_status_vals, "(0x%x)")); entries++; } else { add_string_to_grid(grid, row, "Encryption status", "-"); } /* TX power */ if (wpcap_packet_request_ulong(adapter, OID_802_11_TX_POWER_LEVEL, &ulong_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%ld mW", ulong_value); add_string_to_grid(grid, row, "TX power", string_buff); entries++; } else { add_string_to_grid(grid, row, "TX power", "-"); } /* RSSI */ if (wpcap_packet_request_ulong(adapter, OID_802_11_RSSI, &rssi)) { #if 0 int i; GList * scale_items = NULL; GList * current; GtkVUMeterScaleItem *item; for (i = 0; i <= 100; i++) { item = g_malloc(sizeof(GtkVUMeterScaleItem)); item->level = i; item->large = !(i%5); item->label = NULL; switch (item->level) { case 0: item->label = "-100 "; break; case 20: item->label = "-80 "; break; case 40: item->label = "-60 "; break; case 60: item->label = "-40 "; break; case 80: item->label = "-20 "; break; case 100: item->label = "0"; break; default: item->label = NULL; } scale_items = g_list_append(scale_items, item); } if (rssi < -100) { rssi = -100; } g_snprintf(string_buff, DETAILS_STR_MAX, "%ld dBm", rssi); add_meter_to_grid(grid, row, "RSSI (Received Signal Strength Indication)", rssi+100 , string_buff, -100+100, 0+100, -80+100, scale_items); current = scale_items; while (current != NULL) { g_free(current->data); current = g_list_next(current); } g_list_free(scale_items); entries++; #endif } else { add_string_to_grid(grid, row, "RSSI (Received Signal Strength Indication)", "-"); } /* Supported Rates */ length = sizeof(values); if (!wpcap_packet_request(adapter, OID_802_11_SUPPORTED_RATES, FALSE /* !set */, values, &length)) { length = 0; } else { entries++; } /* if we can get the link speed, show Supported Rates in level meter format */ if (length != 0 && wpcap_packet_request_uint(adapter, OID_GEN_LINK_SPEED, &uint_value)) { #if 0 int max; int yellow; GList *rates_list; GList * current; rates_list = rates_vu_list(values, length, &max); /* if we don't have a signal, we might not have a valid link speed */ if (rssi == -100) { uint_value = 0; } uint_value /= 10 * 1000; g_snprintf(string_buff, DETAILS_STR_MAX, "%u MBits/s", uint_value); if (max >= 54) { yellow = 2; } else { yellow = 1; } add_meter_to_grid(grid, row, "Link Speed", uint_value, string_buff, 0, max, yellow, rates_list); current = rates_list; while (current != NULL) { g_free(current->data); current = g_list_next(current); } g_list_free(rates_list); #endif } /* Supported Rates in String format */ Rates = rates_details(values, length); add_string_to_grid(grid, row, "Supported Rates", Rates->str); g_string_free(Rates, TRUE /* free_segment */); /* Desired Rates */ length = sizeof(values); if (!wpcap_packet_request(adapter, OID_802_11_DESIRED_RATES, FALSE /* !set */, values, &length)) { length = 0; } else { entries++; } Rates = rates_details(values, length); add_string_to_grid(grid, row, "Desired Rates", Rates->str); g_string_free(Rates, TRUE /* free_segment */); /* Configuration (e.g. frequency) */ length = sizeof(values); if (wpcap_packet_request(adapter, OID_802_11_CONFIGURATION, FALSE /* !set */, (char *) values, &length)) { configuration = (struct ndis_configuration *) values; add_string_to_grid(grid, row, "Channel", val_to_str(configuration->ds_config, win32_802_11_channel_freq_vals, "(%u kHz)")); entries++; } else { add_string_to_grid(grid, row, "Channel", "-"); } /* BSSID list: first trigger a scan */ length = sizeof(uint_value); if (wpcap_packet_request(adapter, OID_802_11_BSSID_LIST_SCAN, TRUE /* set */, (char *) &uint_value, &length)) { #if 0 g_warning("BSSID list scan done"); } else { g_warning("BSSID list scan failed"); #endif } /* BSSID list: get scan results */ /* XXX - we might have to wait up to 7 seconds! */ length = sizeof(ULONG) + sizeof(struct ndis_ssid_item) * 16; bssid_list = g_malloc(length); /* some drivers don't set bssid_list->num_items to 0 if OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */ memset(bssid_list, 0, length); if (wpcap_packet_request(adapter, OID_802_11_BSSID_LIST, FALSE /* !set */, (char *) bssid_list, &length)) { add_string_to_grid(grid, row, "", ""); add_string_to_grid(grid, row, "Available networks (BSSID list)", ""); capture_if_details_802_11_bssid_list(main_vb, bssid_list); entries += bssid_list->num_items; } else { add_string_to_grid(grid, row, "Available networks (BSSID list)", "-"); } g_free(bssid_list); return entries; } static int capture_if_details_802_3(GtkWidget *grid, GtkWidget *main_vb, guint *row, LPADAPTER adapter) { unsigned int uint_value; unsigned char values[100]; int length; gchar string_buff[DETAILS_STR_MAX]; const gchar *manuf_name; int entries = 0; add_string_to_grid(grid, row, "Characteristics", ""); length = sizeof(values); if (wpcap_packet_request(adapter, OID_802_3_PERMANENT_ADDRESS, FALSE /* !set */, values, &length)) { manuf_name = get_manuf_name_if_known(values); if (manuf_name != NULL) { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)", values[0], values[1], values[2], values[3], values[4], values[5], manuf_name); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X", values[0], values[1], values[2], values[3], values[4], values[5]); } entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Permanent station address", string_buff); length = sizeof(values); if (wpcap_packet_request(adapter, OID_802_3_CURRENT_ADDRESS, FALSE /* !set */, values, &length)) { manuf_name = get_manuf_name_if_known(values); if (manuf_name != NULL) { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)", values[0], values[1], values[2], values[3], values[4], values[5], manuf_name); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X", values[0], values[1], values[2], values[3], values[4], values[5]); } entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Current station address", string_buff); add_string_to_grid(grid, row, "", ""); add_string_to_grid(grid, row, "Statistics", ""); if (wpcap_packet_request_uint(adapter, OID_802_3_RCV_ERROR_ALIGNMENT, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets received with alignment error", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_ONE_COLLISION, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets transmitted with one collision", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_MORE_COLLISIONS, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets transmitted with more than one collision", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_RCV_OVERRUN, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets not received due to overrun", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_DEFERRED, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets transmitted after deferred", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_MAX_COLLISIONS, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets not transmitted due to collisions", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_UNDERRUN, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets not transmitted due to underrun", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_HEARTBEAT_FAILURE, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packets transmitted with heartbeat failure", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_TIMES_CRS_LOST, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Times carrier sense signal lost during transmission", string_buff); if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_LATE_COLLISIONS, &uint_value)) { g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Times late collisions detected", string_buff); return entries; } static int capture_if_details_task_offload(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) { NDIS_TASK_OFFLOAD_HEADER *offload; unsigned char values[10000]; int length; gchar string_buff[DETAILS_STR_MAX]; int entries = 0; int TcpIpChecksumSupported = 0; int IpSecSupported = 0; int TcpLargeSendSupported = 0; /* Task Offload */ offload = (NDIS_TASK_OFFLOAD_HEADER *) values; offload->Version = NDIS_TASK_OFFLOAD_VERSION; offload->Size = sizeof(NDIS_TASK_OFFLOAD_HEADER); offload->Reserved = 0; offload->OffsetFirstTask = 0; /* the EncapsulationFormat seems to be ignored on a query (using Ethernet values) */ offload->EncapsulationFormat.Encapsulation = IEEE_802_3_Encapsulation; offload->EncapsulationFormat.Flags.FixedHeaderSize = 1; offload->EncapsulationFormat.Flags.Reserved = 0; offload->EncapsulationFormat.EncapsulationHeaderSize = 14; /* sizeof(struct ether_header) */; length = sizeof(values); if (wpcap_packet_request(adapter, OID_TCP_TASK_OFFLOAD, FALSE /* !set */, values, &length)) { NDIS_TASK_OFFLOAD *of; /* XXX - hmmm, using a tvb for this? */ unsigned char *valuep = values + offload->OffsetFirstTask; length -= offload->OffsetFirstTask; do { of = (NDIS_TASK_OFFLOAD *) valuep; switch (of->Task) { case TcpIpChecksumNdisTask: { NDIS_TASK_TCP_IP_CHECKSUM *tic = (NDIS_TASK_TCP_IP_CHECKSUM *) (of->TaskBuffer); entries++; TcpIpChecksumSupported++; add_string_to_grid(table, row, "TCP/IP Checksum", ""); g_snprintf(string_buff, DETAILS_STR_MAX, ""); add_string_to_grid(table, row, "V4 transmit checksum", ""); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s, IP: %s", tic->V4Transmit.TcpChecksum ? "Yes" : "No", tic->V4Transmit.UdpChecksum ? "Yes" : "No", tic->V4Transmit.IpChecksum ? "Yes" : "No"); add_string_to_grid(table, row, "Calculation supported", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s", tic->V4Transmit.TcpOptionsSupported ? "Yes" : "No", tic->V4Transmit.IpOptionsSupported ? "Yes" : "No"); add_string_to_grid(table, row, "Options fields supported", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, ""); add_string_to_grid(table, row, "V4 receive checksum", ""); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s, IP: %s", tic->V4Receive.TcpChecksum ? "Yes" : "No", tic->V4Receive.UdpChecksum ? "Yes" : "No", tic->V4Receive.IpChecksum ? "Yes" : "No"); add_string_to_grid(table, row, "Validation supported", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s", tic->V4Receive.TcpOptionsSupported ? "Yes" : "No", tic->V4Receive.IpOptionsSupported ? "Yes" : "No"); add_string_to_grid(table, row, "Options fields supported", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, ""); add_string_to_grid(table, row, "V6 transmit checksum", ""); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s", tic->V6Transmit.TcpChecksum ? "Yes" : "No", tic->V6Transmit.UdpChecksum ? "Yes" : "No"); add_string_to_grid(table, row, "Calculation supported", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s", tic->V6Transmit.TcpOptionsSupported ? "Yes" : "No", tic->V6Transmit.IpOptionsSupported ? "Yes" : "No"); add_string_to_grid(table, row, "Options fields supported", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, ""); add_string_to_grid(table, row, "V6 receive checksum", ""); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s", tic->V6Receive.TcpChecksum ? "Yes" : "No", tic->V6Receive.UdpChecksum ? "Yes" : "No"); add_string_to_grid(table, row, "Validation supported", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s", tic->V6Receive.TcpOptionsSupported ? "Yes" : "No", tic->V6Receive.IpOptionsSupported ? "Yes" : "No"); add_string_to_grid(table, row, "Options fields supported", string_buff); } break; case IpSecNdisTask: entries++; IpSecSupported++; add_string_to_grid(table, row, "IPSEC", ""); g_snprintf(string_buff, DETAILS_STR_MAX, "IPSEC (TaskID 1) not decoded yet"); add_string_to_grid(table, row, "Task", string_buff); break; case TcpLargeSendNdisTask: { NDIS_TASK_TCP_LARGE_SEND *tls = (NDIS_TASK_TCP_LARGE_SEND *) (of->TaskBuffer); entries++; TcpLargeSendSupported++; add_string_to_grid(table, row, "TCP large send", ""); /* XXX - while MSDN tells about version 0, we see version 1?!? */ if (tls->Version == 1) { g_snprintf(string_buff, DETAILS_STR_MAX, "%u", tls->MaxOffLoadSize); add_string_to_grid(table, row, "Max Offload Size", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, "%u", tls->MinSegmentCount); add_string_to_grid(table, row, "Min Segment Count", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, "%s", tls->TcpOptions ? "Yes" : "No"); add_string_to_grid(table, row, "TCP option fields", string_buff); g_snprintf(string_buff, DETAILS_STR_MAX, "%s", tls->IpOptions ? "Yes" : "No"); add_string_to_grid(table, row, "IP option fields", string_buff); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "%u (unknown)", tls->Version); add_string_to_grid(table, row, "Version", string_buff); } } break; default: g_snprintf(string_buff, DETAILS_STR_MAX, "Unknown task %u", of->Task); add_string_to_grid(table, row, "Task", string_buff); } add_string_to_grid(table, row, "", ""); valuep += of->OffsetNextTask; length -= of->OffsetNextTask; } while (of->OffsetNextTask != 0); } if (TcpIpChecksumSupported == 0) { add_string_to_grid(table, row, "TCP/IP Checksum", ""); add_string_to_grid(table, row, "Offload not supported", "-"); } if (IpSecSupported == 0) { add_string_to_grid(table, row, "IpSec", ""); add_string_to_grid(table, row, "Offload not supported", "-"); } if (TcpLargeSendSupported == 0) { add_string_to_grid(table, row, "TCP Large Send", ""); add_string_to_grid(table, row, "Offload not supported", "-"); } return entries; } static int capture_if_details_general(GtkWidget *grid, GtkWidget *main_vb, guint *row, LPADAPTER adapter, gchar *iface) { gchar *interface_friendly_name; gchar string_buff[DETAILS_STR_MAX]; const gchar *manuf_name; unsigned int uint_value; unsigned int uint_array[50]; int uint_array_size; unsigned int physical_medium; int i; unsigned char values[100]; guint16 wvalues[100]; char *utf8value; int length; unsigned short ushort_value; int entries = 0; gchar *size_str; /* general */ add_string_to_grid(grid, row, "Characteristics", ""); /* OS friendly name - look it up from iface ("\Device\NPF_{11111111-2222-3333-4444-555555555555}") */ interface_friendly_name = get_windows_interface_friendly_name(/* IN */ iface); if (interface_friendly_name != NULL){ add_string_to_grid(grid, row, "OS Friendly name", interface_friendly_name); g_free(interface_friendly_name); } /* 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); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Vendor description", string_buff); /* NDIS's "Friendly name" */ length = sizeof(wvalues); if (wpcap_packet_request(adapter, OID_GEN_FRIENDLY_NAME, FALSE /* !set */, (char *)wvalues, &length)) { utf8value = g_utf16_to_utf8(wvalues, -1, NULL, NULL, NULL); g_snprintf(string_buff, DETAILS_STR_MAX, "%s", utf8value); g_free(utf8value); entries++; } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "NDIS Friendly name", string_buff); /* Interface */ add_string_to_grid(grid, row, "Interface", iface); /* link status (connected/disconnected) */ if (wpcap_packet_request_uint(adapter, OID_GEN_MEDIA_CONNECT_STATUS, &uint_value)) { entries++; if (uint_value == 0) { add_string_to_grid(grid, row, "Link status", "Connected"); } else { add_string_to_grid(grid, row, "Link status", "Disconnected"); } } else { add_string_to_grid(grid, row, "Link status", "-"); } /* link speed */ if (wpcap_packet_request_uint(adapter, OID_GEN_LINK_SPEED, &uint_value)) { entries++; uint_value *= 100; size_str = format_size(uint_value, format_size_unit_bits_s|format_size_prefix_si); g_strlcpy(string_buff, size_str, DETAILS_STR_MAX); g_free(size_str); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Link speed", string_buff); uint_array_size = sizeof(uint_array); if (wpcap_packet_request(adapter, OID_GEN_MEDIA_SUPPORTED, FALSE /* !set */, (char *) uint_array, &uint_array_size)) { entries++; uint_array_size /= sizeof(unsigned int); i = 0; while (uint_array_size--) { add_string_to_grid(grid, row, "Media supported", val_to_str(uint_array[i], win32_802_3_medium_vals, "(0x%x)")); i++; } } else { add_string_to_grid(grid, row, "Media supported", "-"); } uint_array_size = sizeof(uint_array); if (wpcap_packet_request(adapter, OID_GEN_MEDIA_IN_USE, FALSE /* !set */, (char *) uint_array, &uint_array_size)) { entries++; uint_array_size /= sizeof(unsigned int); i = 0; while (uint_array_size--) { add_string_to_grid(grid, row, "Medium in use", val_to_str(uint_array[i], win32_802_3_medium_vals, "(0x%x)")); i++; } } else { add_string_to_grid(grid, row, "Medium in use", "-"); } if (wpcap_packet_request_uint(adapter, OID_GEN_PHYSICAL_MEDIUM, &physical_medium)) { entries++; add_string_to_grid(grid, row, "Physical medium", val_to_str(physical_medium, win32_802_3_physical_medium_vals, "(0x%x)")); } else { add_string_to_grid(grid, row, "Physical medium", "-"); } length = sizeof(ushort_value); if (wpcap_packet_request(adapter, OID_GEN_DRIVER_VERSION, FALSE /* !set */, (char *) &ushort_value, &length)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%u.%u", ushort_value / 0x100, ushort_value % 0x100); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "NDIS Driver Version", string_buff); length = sizeof(uint_value); if (wpcap_packet_request(adapter, OID_GEN_VENDOR_DRIVER_VERSION, FALSE /* !set */, (char *) &uint_value, &length)) { entries++; /* XXX - what's the correct output format? */ g_snprintf(string_buff, DETAILS_STR_MAX, "%u.%u (Hex: %X.%X)", (uint_value / 0x10000 ) % 0x10000, uint_value % 0x10000, (uint_value / 0x10000 ) % 0x10000, uint_value % 0x10000); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Vendor Driver Version", string_buff); length = sizeof(values); if (wpcap_packet_request(adapter, OID_GEN_VENDOR_ID, FALSE /* !set */, values, &length)) { entries++; manuf_name = get_manuf_name_if_known(values); if (manuf_name != NULL) { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X (%s) NIC: %02X", values[0], values[1], values[2], manuf_name, values[3]); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X NIC: %02X", values[0], values[1], values[2], values[3]); } } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Vendor ID", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_MAC_OPTIONS, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "802.1P Priority: %s, 802.1Q VLAN: %s", (uint_value & NDIS_MAC_OPTION_8021P_PRIORITY) ? "Supported" : "Unsupported", (uint_value & NDIS_MAC_OPTION_8021Q_VLAN) ? "Supported" : "Unsupported" ); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "MAC Options", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_VLAN_ID, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%u", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "VLAN ID", string_buff); #if 0 /* value seems to be constant */ if (wpcap_packet_request_uint(adapter, OID_GEN_CURRENT_PACKET_FILTER, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Packet filter", string_buff); #endif if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_BUFFER_SPACE, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Transmit Buffer Space", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_RECEIVE_BUFFER_SPACE, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Receive Buffer Space", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_BLOCK_SIZE , &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Transmit Block Size", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_RECEIVE_BLOCK_SIZE, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Receive Block Size", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_MAXIMUM_TOTAL_SIZE, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(grid, row, "Maximum Packet Size", string_buff); return entries; } static int capture_if_details_stats(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) { gchar string_buff[DETAILS_STR_MAX]; unsigned int uint_value; int entries = 0; add_string_to_grid(table, row, "Statistics", ""); if (wpcap_packet_request_uint(adapter, OID_GEN_XMIT_OK, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Transmit OK", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_XMIT_ERROR, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Transmit Error", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_OK, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Receive OK", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_ERROR, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Receive Error", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_NO_BUFFER, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Receive but no Buffer", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_BYTES_XMIT, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Directed bytes transmitted w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_FRAMES_XMIT, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Directed packets transmitted w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_BYTES_XMIT, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Multicast bytes transmitted w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_FRAMES_XMIT, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Multicast packets transmitted w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_BYTES_XMIT, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Broadcast bytes transmitted w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_FRAMES_XMIT, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Broadcast packets transmitted w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_BYTES_RCV, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Directed bytes received w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_FRAMES_RCV, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Directed packets received w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_BYTES_RCV, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Multicast bytes received w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_FRAMES_RCV, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Multicast packets received w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_BYTES_RCV, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Broadcast bytes received w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_FRAMES_RCV, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Broadcast packets received w/o errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_CRC_ERROR, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Packets received with CRC or FCS errors", string_buff); if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_QUEUE_LENGTH, &uint_value)) { entries++; g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value); } else { g_snprintf(string_buff, DETAILS_STR_MAX, "-"); } add_string_to_grid(table, row, "Packets queued for transmission", string_buff); return entries; } static GtkWidget * capture_if_details_page_new(GtkWidget **grid) { GtkWidget *main_vb; main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE); gtk_container_set_border_width(GTK_CONTAINER(main_vb), 12); /* grid */ *grid = ws_gtk_grid_new(); ws_gtk_grid_set_column_spacing(GTK_GRID(*grid), 6); ws_gtk_grid_set_row_spacing(GTK_GRID(*grid), 3); gtk_box_pack_start(GTK_BOX (main_vb), *grid, TRUE, TRUE, 0); return main_vb; } static void capture_if_details_open_win(char *iface) { GtkWidget *details_open_w, *main_vb, *bbox, *close_bt, *help_bt; GtkWidget *page_general, *page_stats, *page_802_3, *page_802_11, *page_task_offload; GtkWidget *page_lb; GtkWidget *grid, *notebook, *label; guint row; LPADAPTER adapter; int entries; /* open the network adapter */ adapter = wpcap_packet_open(iface); if (adapter == NULL) { /* * We have an adapter that is not exposed through normal APIs (e.g. TurboCap) * or an adapter that isn't plugged in. * * XXX - We should use the TurboCap API to get info about TurboCap adapters. */ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%sCould not open adapter %s!%s" "\n\nHas it been unplugged?", simple_dialog_primary_start(), iface, simple_dialog_primary_end()); return; } /* open a new window */ details_open_w = dlg_window_new("Wireshark: Interface Details"); /* transient_for top_level */ gtk_window_set_destroy_with_parent (GTK_WINDOW(details_open_w), TRUE); /* Container for the window contents */ main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 12, FALSE); gtk_container_set_border_width(GTK_CONTAINER(main_vb), 12); gtk_container_add(GTK_CONTAINER(details_open_w), main_vb); /* notebook */ notebook = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(main_vb), notebook, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); /* General page */ page_general = capture_if_details_page_new(&grid); page_lb = gtk_label_new("Characteristics"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_general, page_lb); row = 0; entries = capture_if_details_general(grid, page_general, &row, adapter, iface); if (entries == 0) { gtk_widget_set_sensitive(page_lb, FALSE); } /* Statistics page */ page_stats = capture_if_details_page_new(&grid); page_lb = gtk_label_new("Statistics"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_stats, page_lb); row = 0; entries = capture_if_details_stats(grid, page_stats, &row, adapter); if (entries == 0) { gtk_widget_set_sensitive(page_lb, FALSE); } /* 802.3 (Ethernet) page */ page_802_3 = capture_if_details_page_new(&grid); page_lb = gtk_label_new("802.3 (Ethernet)"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_802_3, page_lb); row = 0; entries = capture_if_details_802_3(grid, page_802_3, &row, adapter); if (entries == 0) { gtk_widget_set_sensitive(page_lb, FALSE); } /* 802_11 (WI-FI) page */ page_802_11 = capture_if_details_page_new(&grid); page_lb = gtk_label_new("802.11 (WLAN)"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_802_11, page_lb); row = 0; entries = capture_if_details_802_11(grid, page_802_11, &row, adapter); if (entries == 0) { gtk_widget_set_sensitive(page_lb, FALSE); } /* Task offload page */ page_task_offload = capture_if_details_page_new(&grid); page_lb = gtk_label_new("Task Offload"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_task_offload, page_lb); row = 0; entries = capture_if_details_task_offload(grid, page_task_offload, &row, adapter); if (entries == 0) { gtk_widget_set_sensitive(page_lb, FALSE); } wpcap_packet_close(adapter); label = gtk_label_new("Some drivers may not provide accurate values."); gtk_box_pack_start(GTK_BOX(main_vb), label, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/); /* Button row. */ bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL); gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/); close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE); window_set_cancel_button(details_open_w, close_bt, window_cancel_button_cb); help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP); g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer) (HELP_CAPTURE_INTERFACES_DETAILS_DIALOG)); gtk_widget_grab_focus(close_bt); g_signal_connect(details_open_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL); gtk_widget_show_all(details_open_w); window_present(details_open_w); } static void capture_if_details_open_answered_cb(gpointer dialog _U_, gint btn, gpointer data) { switch (btn) { case(ESD_BTN_OK): capture_if_details_open_win(data); break; case(ESD_BTN_CANCEL): break; default: g_assert_not_reached(); } } void capture_if_details_open(char *iface) { char *version; gboolean version_ok = FALSE; gpointer dialog; /* check packet.dll version */ version = wpcap_packet_get_version(); if (version == NULL) { /* couldn't even get the packet.dll version, must be a very old one or just not existing -> give up */ /* (this seems to be the case for 2.3 beta and all previous releases) */ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "%sCouldn't obtain WinPcap packet.dll version.%s" "\n\nThe WinPcap packet.dll is not installed or the version you use seems to be very old." "\n\nPlease update or install WinPcap.", simple_dialog_primary_start(), simple_dialog_primary_end()); return; } /* XXX - add more known DLL versions here */ /* (all versions since the 2.3 release seems to be working (although the 2.3 beta did not) */ if ( /* * 4.0 version strings: * 4.0.0.703: 4.0 beta 3 * 4.0.0.655: 4.0 beta 2 * 4.0.0.592: 4.0 beta 1 */ (strcmp(version, "3" ) > 0) || /* 4.0 and above (including betas) */ (strcmp(version, "3, 2, 0, 29") == 0) || /* 3.2 beta 1 */ (strcmp(version, "3, 1, 0, 27") == 0) || /* 3.1 release */ (strcmp(version, "3, 1, 0, 24") == 0) || /* 3.1 beta 4 */ (strcmp(version, "3, 1, 0, 23") == 0) || /* 3.1 beta 3 */ (strcmp(version, "3, 1, 0, 22") == 0) || /* 3.1 beta 2 */ (strcmp(version, "3, 1, 0, 20") == 0) || /* 3.1 beta */ (strcmp(version, "3.0 alpha3" ) == 0) || /* 3.0 release or 3.0 beta (yes, both versions report alpha3!) */ (strcmp(version, "2.3" ) == 0) /* 2.3 release */ ) { version_ok = TRUE; } if (!version_ok) { /* packet.dll version not known to us, warn user but try to continue */ dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK | ESD_BTN_CANCEL, "%sUnknown WinPcap version.%s" "\n\nThe WinPcap packet.dll version \"%s\" is unknown. It may not" "\nprovide functions that we need and might even crash." "\n\nContinue anyway?", simple_dialog_primary_start(), simple_dialog_primary_end(), version); simple_dialog_set_cb(dialog, capture_if_details_open_answered_cb, iface); } else { capture_if_details_open_win(iface); } } gboolean capture_if_has_details(char *iface) { LPADAPTER adapter; if (!iface) { return FALSE; } adapter = wpcap_packet_open(iface); if (adapter) { wpcap_packet_close(adapter); return TRUE; } return FALSE; } #endif /* HAVE_LIBPCAP && _WIN32 */ /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * vi: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */