g_string_sprintf --> g_string_printf and g_string_sprintfa --> g_string_append_printf
[obnox/wireshark/wip.git] / gtk / capture_if_details_dlg_win32.c
1 /* capture_if_details_dlg.c
2  * Routines for capture interface details window (only Win32!)
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29
30 #if defined HAVE_LIBPCAP && defined _WIN32
31
32 #include <time.h>
33 #include <string.h>
34
35 #include <gtk/gtk.h>
36
37 #include <epan/value_string.h>
38 #include <epan/addr_resolv.h>
39
40 #include "../globals.h"
41 #include "../file.h"
42 #include "../capture.h"
43 #include "../capture_wpcap_packet.h"
44 #include "../simple_dialog.h"
45 #include <wiretap/wtap.h>
46
47 #include "gtk/main.h"
48 #include "gtk/dlg_utils.h"
49 #include "gtk/gui_utils.h"
50 #include "gtk/help_dlg.h"
51 #include "gtk/gtkvumeter.h"
52 #include "gtk/capture_if_details_dlg_win32.h"
53
54
55
56 /* packet32.h requires sockaddr_storage 
57  * wether sockaddr_storage is defined or not depends on the Platform SDK 
58  * version installed. The only one not defining it is the SDK that comes
59  * with MSVC 6.0 (WINVER 0x0400).
60  *
61  * copied from RFC2553 (and slightly modified because of datatypes) ...
62  * XXX - defined more than once, move this to a header file */
63 #if (WINVER <= 0x0400) && defined(_MSC_VER)
64 typedef unsigned short eth_sa_family_t;
65
66 /*
67  * Desired design of maximum size and alignment
68  */
69 #define ETH_SS_MAXSIZE    128  /* Implementation specific max size */
70 #define ETH_SS_ALIGNSIZE  (sizeof (gint64 /*int64_t*/))
71                          /* Implementation specific desired alignment */
72 /*
73  * Definitions used for sockaddr_storage structure paddings design.
74  */
75 #define ETH_SS_PAD1SIZE   (ETH_SS_ALIGNSIZE - sizeof (eth_sa_family_t))
76 #define ETH_SS_PAD2SIZE   (ETH_SS_MAXSIZE - (sizeof (eth_sa_family_t) + \
77                               ETH_SS_PAD1SIZE + ETH_SS_ALIGNSIZE))
78
79 struct sockaddr_storage {
80     eth_sa_family_t  __ss_family;     /* address family */
81     /* Following fields are implementation specific */
82     char      __ss_pad1[ETH_SS_PAD1SIZE];
83               /* 6 byte pad, this is to make implementation */
84               /* specific pad up to alignment field that */
85               /* follows explicit in the data structure */
86     gint64 /*int64_t*/   __ss_align;     /* field to force desired structure */
87                /* storage alignment */
88     char      __ss_pad2[ETH_SS_PAD2SIZE];
89               /* 112 byte pad to achieve desired size, */
90               /* _SS_MAXSIZE value minus size of ss_family */
91               /* __ss_pad1, __ss_align fields is 112 */
92 };
93 /* ... copied from RFC2553 */
94 #endif /* WINVER */
95
96 #include <Packet32.h>
97 #include <windows.h>
98 #include <windowsx.h>
99 #include <Ntddndis.h>
100
101 #define DETAILS_STR_MAX     1024
102
103
104 /* The informations and definitions used here are coming from various places on the web:
105  *
106  * ndiswrapper (various NDIS related definitions)
107  *  http://cvs.sourceforge.net/viewcvs.py/ndiswrapper/ndiswrapper/driver/
108  *
109  * ReactOS (various NDIS related definitions)
110  *  http://www.reactos.org/generated/doxygen/d2/d6d/ndis_8h-source.html
111  *
112  * IEEE802.11 "Detailed NDIS OID Log for a 802.11b Miniport"
113  *  http://www.ndis.com/papers/ieee802_11_log.htm
114  *
115  * FreeBSD (various NDIS related definitions)
116  *  http://lists.freebsd.org/pipermail/p4-projects/2004-January/003433.html
117  *
118  * MS WHDC "Network Drivers and Windows"
119  *  http://www.microsoft.com/whdc/archive/netdrv_up.mspx
120  *
121  * IEEE "Get IEEE 802" (the various 802.11 docs)
122  *  http://standards.ieee.org/getieee802/802.11.html
123  *
124  * MS MSDN "Network Devices: Windows Driver Kit"
125  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/NetXP_r/hh/NetXP_r/netref_4c297a96-2ba5-41ed-ab21-b7a9cfaa9b4d.xml.asp
126  *
127  * MS MSDN "Microsoft Windows CE .NET 4.2 Network Driver Reference"
128  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxgrfNetworkDriverReference.asp
129  *
130  * MS MSDN (some explanations of a special MS 802.11 Information Element)
131  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp
132  *
133  * "WLANINFO fuer Windows XP"
134  *  http://www-pc.uni-regensburg.de/systemsw/TOOLS/wlaninfo.htm
135  */
136
137 /********************************************************************************/
138 /* definitions that would usually come from the windows DDK (device driver kit) */
139 /* and are not part of the ntddndis.h file delivered with WinPcap */
140
141 /* Required OIDs */
142 #define OID_GEN_VLAN_ID                         0x0001021C
143
144 /* Optional OIDs */
145 #define OID_GEN_MEDIA_CAPABILITIES              0x00010201
146 #define OID_GEN_PHYSICAL_MEDIUM                 0x00010202
147
148 /* Optional OIDs */
149 #define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
150 #define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
151
152
153 /* Physical medium (OID_GEN_PHYSICAL_MEDIUM) */
154 typedef enum ndis_phys_medium {
155         NdisPhysicalMediumUnspecified,
156         NdisPhysicalMediumWirelessLan,
157         NdisPhysicalMediumCableModem,
158         NdisPhysicalMediumPhoneLine,
159         NdisPhysicalMediumPowerLine,
160         NdisPhysicalMediumDSL,
161         NdisPhysicalMediumFibreChannel,
162         NdisPhysicalMedium1394,
163         NdisPhysicalMediumWirelessWan,
164         NdisPhysicalMediumMax
165 };
166
167 /* flag definitions for OID_GEN_MAC_OPTIONS */
168 #define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA     0x00000001
169 #define NDIS_MAC_OPTION_RECEIVE_SERIALIZED      0x00000002
170 #define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND      0x00000004
171 #define NDIS_MAC_OPTION_NO_LOOPBACK             0x00000008
172 #define NDIS_MAC_OPTION_FULL_DUPLEX             0x00000010
173 #define NDIS_MAC_OPTION_EOTX_INDICATION         0x00000020
174 #define NDIS_MAC_OPTION_8021P_PRIORITY          0x00000040
175 #define NDIS_MAC_OPTION_8021Q_VLAN              0x00000080
176
177 /* 802.11 OIDs */
178 #define OID_802_11_BSSID                        0x0D010101
179 #define OID_802_11_SSID                         0x0D010102
180 #define OID_802_11_NETWORK_TYPES_SUPPORTED      0x0D010203
181 #define OID_802_11_NETWORK_TYPE_IN_USE          0x0D010204
182 #define OID_802_11_TX_POWER_LEVEL               0x0D010205
183 #define OID_802_11_RSSI                         0x0D010206
184 #define OID_802_11_RSSI_TRIGGER                 0x0D010207
185 #define OID_802_11_INFRASTRUCTURE_MODE          0x0D010108
186 #define OID_802_11_FRAGMENTATION_THRESHOLD      0x0D010209
187 #define OID_802_11_RTS_THRESHOLD                0x0D01020A
188 #define OID_802_11_NUMBER_OF_ANTENNAS           0x0D01020B
189 #define OID_802_11_RX_ANTENNA_SELECTED          0x0D01020C
190 #define OID_802_11_TX_ANTENNA_SELECTED          0x0D01020D
191 #define OID_802_11_SUPPORTED_RATES              0x0D01020E
192 #define OID_802_11_DESIRED_RATES                0x0D010210
193 #define OID_802_11_CONFIGURATION                0x0D010211
194 #define OID_802_11_STATISTICS                   0x0D020212
195 #define OID_802_11_ADD_WEP                      0x0D010113
196 #define OID_802_11_REMOVE_WEP                   0x0D010114
197 #define OID_802_11_DISASSOCIATE                 0x0D010115
198 #define OID_802_11_POWER_MODE                   0x0D010216
199 #define OID_802_11_BSSID_LIST                   0x0D010217
200 #define OID_802_11_AUTHENTICATION_MODE          0x0D010118
201 #define OID_802_11_PRIVACY_FILTER               0x0D010119
202 #define OID_802_11_BSSID_LIST_SCAN              0x0D01011A
203 #define OID_802_11_WEP_STATUS                   0x0D01011B
204 #define OID_802_11_ENCRYPTION_STATUS            OID_802_11_WEP_STATUS
205 #define OID_802_11_RELOAD_DEFAULTS              0x0D01011C
206 #define OID_802_11_ADD_KEY                      0x0D01011D
207 #define OID_802_11_REMOVE_KEY                   0x0D01011E
208 #define OID_802_11_ASSOCIATION_INFORMATION      0x0D01011F
209 #define OID_802_11_TEST                         0x0D010120
210 #define OID_802_11_CAPABILITY                   0x0D010122
211 #define OID_802_11_PMKID                        0x0D010123
212
213
214 /* PnP and power management OIDs */
215 #define OID_PNP_CAPABILITIES                    0xFD010100
216 #define OID_PNP_SET_POWER                       0xFD010101
217 #define OID_PNP_QUERY_POWER                     0xFD010102
218 #define OID_PNP_ADD_WAKE_UP_PATTERN             0xFD010103
219 #define OID_PNP_REMOVE_WAKE_UP_PATTERN          0xFD010104
220 #define OID_PNP_WAKE_UP_PATTERN_LIST            0xFD010105
221 #define OID_PNP_ENABLE_WAKE_UP                  0xFD010106
222
223
224 /* Currently associated SSID (OID_802_11_SSID) */
225 #define NDIS_ESSID_MAX_SIZE 32
226 struct ndis_essid {
227         ULONG length;
228         UCHAR essid[NDIS_ESSID_MAX_SIZE];
229 };
230
231 /* Current infrastructure mode (OID_802_11_INFRASTRUCTURE_MODE) */
232 enum network_infrastructure {
233         Ndis802_11IBSS,
234         Ndis802_11Infrastructure,
235         Ndis802_11AutoUnknown,
236         Ndis802_11InfrastructureMax
237 };
238
239 /* Current authentication mode (OID_802_11_AUTHENTICATION_MODE) */
240 enum authentication_mode {
241         Ndis802_11AuthModeOpen,
242         Ndis802_11AuthModeShared,
243         Ndis802_11AuthModeAutoSwitch,
244         Ndis802_11AuthModeWPA,
245         Ndis802_11AuthModeWPAPSK,
246         Ndis802_11AuthModeWPANone,
247         Ndis802_11AuthModeWPA2,
248         Ndis802_11AuthModeWPA2PSK,
249         Ndis802_11AuthModeMax
250 };
251
252 /* Current network type (OID_802_11_NETWORK_TYPES_SUPPORTED / OID_802_11_NETWORK_TYPE_IN_USE) */
253 enum network_type {
254         Ndis802_11FH,
255         Ndis802_11DS,
256         Ndis802_11OFDM5,
257         Ndis802_11OFDM24,
258         /* MSDN site uses Ndis802_11Automode, which is not mentioned
259          * in DDK, so add one and assign it to
260          * Ndis802_11NetworkTypeMax */
261         Ndis802_11Automode,
262         Ndis802_11NetworkTypeMax = Ndis802_11Automode
263 };
264
265 /* Current encryption status (OID_802_11_ENCRYPTION_STATUS) */
266 enum encryption_status {
267         Ndis802_11WEPEnabled,
268         Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
269         Ndis802_11WEPDisabled,
270         Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
271         Ndis802_11WEPKeyAbsent,
272         Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
273         Ndis802_11WEPNotSupported,
274         Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
275         Ndis802_11Encryption2Enabled,
276         Ndis802_11Encryption2KeyAbsent,
277         Ndis802_11Encryption3Enabled,
278         Ndis802_11Encryption3KeyAbsent
279 };
280
281
282 /* some definitions needed for the following structs */
283 #define NDIS_MAX_RATES_EX 16
284 typedef UCHAR mac_address[/* ETH_ALEN */ 6];
285 typedef UCHAR ndis_rates[NDIS_MAX_RATES_EX];
286
287 /* configuration, e.g. frequency (OID_802_11_CONFIGURATION / OID_802_11_BSSID_LIST) */
288 struct /*packed*/ ndis_configuration {
289         ULONG length;
290         ULONG beacon_period;
291         ULONG atim_window;
292         ULONG ds_config;
293         struct ndis_configuration_fh {
294                 ULONG length;
295                 ULONG hop_pattern;
296                 ULONG hop_set;
297                 ULONG dwell_time;
298         } fh_config;
299 };
300
301 /* bssid list item (OID_802_11_BSSID_LIST) */
302 struct ndis_ssid_item {
303         ULONG length;
304         mac_address mac;
305         UCHAR reserved[2];
306         struct ndis_essid ssid;
307         ULONG privacy;
308         LONG rssi;
309         UINT net_type;
310         struct ndis_configuration config;
311         UINT mode;
312         ndis_rates rates;
313         ULONG ie_length;
314         UCHAR ies[1];
315 };
316
317
318 typedef struct _NDIS_802_11_FIXED_IEs
319 {
320   UCHAR  Timestamp[8];
321   USHORT  BeaconInterval;
322   USHORT  Capabilities;
323 } NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
324
325
326 /* bssid list (OID_802_11_BSSID_LIST) */
327 struct ndis_bssid_list {
328         ULONG num_items;
329         struct ndis_ssid_item items[1];
330 };
331
332
333 /******************************************************************************/
334 /* OID_TCP_TASK_OFFLOAD specific definitions that would usually come from the */
335 /* windows DDK (device driver kit) and are not part of the ntddndis.h file */
336 /* delivered with WinPcap */
337
338 /* optional OID */
339 #define OID_TCP_TASK_OFFLOAD    0xFC010201
340
341 /* task id's */
342 typedef enum _NDIS_TASK {
343   TcpIpChecksumNdisTask,
344   IpSecNdisTask,
345   TcpLargeSendNdisTask,
346   MaxNdisTask
347 } NDIS_TASK, *PNDIS_TASK;
348
349 /* TaskBuffer content on TcpIpChecksumNdisTask */
350 typedef struct _NDIS_TASK_TCP_IP_CHECKSUM
351 {
352   struct
353   {
354     ULONG    IpOptionsSupported:1;
355     ULONG    TcpOptionsSupported:1;
356     ULONG    TcpChecksum:1;
357     ULONG    UdpChecksum:1;
358     ULONG    IpChecksum:1;
359   } V4Transmit;
360
361   struct
362   {
363     ULONG    IpOptionsSupported:1;
364     ULONG    TcpOptionsSupported:1;
365     ULONG    TcpChecksum:1;
366     ULONG    UdpChecksum:1;
367     ULONG    IpChecksum:1;
368   } V4Receive;
369
370   struct
371   {
372     ULONG    IpOptionsSupported:1;
373     ULONG    TcpOptionsSupported:1;
374     ULONG    TcpChecksum:1;
375     ULONG    UdpChecksum:1;
376   } V6Transmit;
377
378   struct
379   {
380     ULONG    IpOptionsSupported:1;
381     ULONG    TcpOptionsSupported:1;
382     ULONG    TcpChecksum:1;
383     ULONG    UdpChecksum:1;
384   } V6Receive;
385 } NDIS_TASK_TCP_IP_CHECKSUM, *PNDIS_TASK_TCP_IP_CHECKSUM;
386
387 /* TaskBuffer content on TcpLargeSendNdisTask */
388 typedef struct _NDIS_TASK_TCP_LARGE_SEND
389 {
390   ULONG  Version;
391   ULONG  MaxOffLoadSize;
392   ULONG  MinSegmentCount;
393   BOOLEAN  TcpOptions;
394   BOOLEAN  IpOptions;
395 } NDIS_TASK_TCP_LARGE_SEND, *PNDIS_TASK_TCP_LARGE_SEND;
396
397 /* Encapsulations */
398 typedef enum _NDIS_ENCAPSULATION {
399   UNSPECIFIED_Encapsulation,
400   NULL_Encapsulation,
401   IEEE_802_3_Encapsulation,
402   IEEE_802_5_Encapsulation,
403   LLC_SNAP_ROUTED_Encapsulation,
404   LLC_SNAP_BRIDGED_Encapsulation
405 } NDIS_ENCAPSULATION;
406
407 /* Encapsulation format */
408 typedef struct _NDIS_ENCAPSULATION_FORMAT {
409   NDIS_ENCAPSULATION  Encapsulation;
410   struct {
411     ULONG  FixedHeaderSize : 1;
412     ULONG  Reserved : 31;
413   } Flags;
414   ULONG  EncapsulationHeaderSize;
415 } NDIS_ENCAPSULATION_FORMAT, *PNDIS_ENCAPSULATION_FORMAT;
416
417 /* request struct */
418 typedef struct _NDIS_TASK_OFFLOAD_HEADER
419 {
420   ULONG  Version;
421   ULONG  Size;
422   ULONG  Reserved;
423   UCHAR  OffsetFirstTask;
424   NDIS_ENCAPSULATION_FORMAT  EncapsulationFormat;
425 } NDIS_TASK_OFFLOAD_HEADER, *PNDIS_TASK_OFFLOAD_HEADER;
426
427 /* response struct */
428 #define NDIS_TASK_OFFLOAD_VERSION 1
429 typedef struct _NDIS_TASK_OFFLOAD
430 {
431   ULONG  Version;
432   ULONG  Size;
433   NDIS_TASK  Task;
434   ULONG  OffsetNextTask;
435   ULONG  TaskBufferLength;
436   UCHAR  TaskBuffer[1];
437 } NDIS_TASK_OFFLOAD, *PNDIS_TASK_OFFLOAD;
438
439
440 /***********************************************************************/
441 /* value_string's for info functions */
442
443
444 /* NDIS driver medium (OID_GEN_MEDIA_SUPPORTED / OID_GEN_MEDIA_IN_USE) */
445 static const value_string win32_802_3_medium_vals[] = {
446         { NdisMedium802_3,      "802.3 (Ethernet)" },    /* might as well be WLAN, ... (see NDIS_PHYSICAL_MEDIUM) */
447         { NdisMedium802_5,      "802.5 (Token Ring)" },
448         { NdisMediumFddi,       "FDDI" },
449         { NdisMediumWan,        "WAN" },
450         { NdisMediumLocalTalk,  "Local Talk" },
451         { NdisMediumDix,        "Dix" },
452         { NdisMediumArcnetRaw,  "Arcnet Raw" },
453         { NdisMediumArcnet878_2,"Arcnet 878_2" },
454         { NdisMediumAtm,        "ATM" },
455         { NdisMediumWirelessWan,"Wireless WAN" },
456         { NdisMediumIrda,       "Irda" },
457     { 0, NULL }
458 };
459
460 /* NDIS physical driver medium (OID_GEN_PHYSICAL_MEDIUM) */
461 static const value_string win32_802_3_physical_medium_vals[] = {
462         { NdisPhysicalMediumUnspecified,    "Unspecified" },
463         { NdisPhysicalMediumWirelessLan,    "Wireless LAN" },
464         { NdisPhysicalMediumCableModem,     "Cable Modem (DOCSIS)" },
465         { NdisPhysicalMediumPhoneLine,      "Phone Line" },
466         { NdisPhysicalMediumPowerLine,      "Power Line" },
467         { NdisPhysicalMediumDSL,            "DSL" },
468         { NdisPhysicalMediumFibreChannel,   "Fibre Channel" },
469         { NdisPhysicalMedium1394,           "IEEE 1394" },
470         { NdisPhysicalMediumWirelessWan,    "Wireless WAN" },
471     { 0, NULL }
472 };
473
474 static const value_string win32_802_11_infra_mode_vals[] = {
475         { Ndis802_11IBSS,           "Ad Hoc" },
476         { Ndis802_11Infrastructure, "Access Point" },
477         { Ndis802_11AutoUnknown,    "Auto or unknown" },
478     { 0, NULL }
479 };
480
481 static const value_string win32_802_11_auth_mode_vals[] = {
482         { Ndis802_11AuthModeOpen,       "Open System" },
483         { Ndis802_11AuthModeShared,     "Shared Key" },
484         { Ndis802_11AuthModeAutoSwitch, "Auto Switch" },
485         { Ndis802_11AuthModeWPA,        "WPA" },
486         { Ndis802_11AuthModeWPAPSK,     "WPA-PSK (pre shared key)" },
487         { Ndis802_11AuthModeWPANone,    "WPA (ad hoc)" },
488         { Ndis802_11AuthModeWPA2,       "WPA2" },
489         { Ndis802_11AuthModeWPA2PSK,    "WPA2-PSK (pre shared key)" },
490     { 0, NULL }
491 };
492
493 static const value_string win32_802_11_network_type_vals[] = {
494         { Ndis802_11FH,         "FH (frequency-hopping spread-spectrum)" },
495         { Ndis802_11DS,         "DS (direct-sequence spread-spectrum)" },
496         { Ndis802_11OFDM5,      "5-GHz OFDM" },
497         { Ndis802_11OFDM24,     "2.4-GHz OFDM" },
498         { Ndis802_11Automode,   "Auto" },
499     { 0, NULL }
500 };
501
502 static const value_string win32_802_11_encryption_status_vals[] = {
503         { Ndis802_11Encryption1Enabled,     "WEP enabled, TKIP & AES disabled, transmit key available" },
504         { Ndis802_11EncryptionDisabled,     "WEP & TKIP & AES disabled, transmit key available" },
505         { Ndis802_11Encryption1KeyAbsent,   "WEP enabled, TKIP & AES disabled, transmit key unavailable" },
506         { Ndis802_11EncryptionNotSupported, "WEP & TKIP & AES not supported" },
507         { Ndis802_11Encryption2Enabled,     "WEP & TKIP enabled, AES disabled, transmit key available" },
508         { Ndis802_11Encryption2KeyAbsent,   "WEP & TKIP enabled, AES disabled, transmit key unavailable" },
509         { Ndis802_11Encryption3Enabled,     "WEP & TKIP & AES enabled, transmit key available" },
510         { Ndis802_11Encryption3KeyAbsent,   "WEP & TKIP & AES enabled, transmit key unavailable" },
511     { 0, NULL }
512 };
513
514 /* frequency to channel mapping (OID_802_11_CONFIGURATION) */
515 static const value_string win32_802_11_channel_freq_vals[] = {
516         { 2412000, "1 (2412 MHz)" },
517         { 2417000, "2 (2417 MHz)" },
518         { 2422000, "3 (2422 MHz)" },
519         { 2427000, "4 (2427 MHz)" },
520         { 2432000, "5 (2432 MHz)" },
521         { 2437000, "6 (2437 MHz)" },
522         { 2442000, "7 (2442 MHz)" },
523         { 2447000, "8 (2447 MHz)" },
524         { 2452000, "9 (2452 MHz)" },
525         { 2457000, "10 (2457 MHz)" },
526         { 2462000, "11 (2462 MHz)" },
527         { 2467000, "12 (2467 MHz)" },
528         { 2472000, "13 (2472 MHz)" },
529         { 2484000, "14 (2484 MHz)" },
530     { 0, NULL }
531 };
532
533 /* frequency to channel mapping (OID_802_11_CONFIGURATION) */
534 static const value_string win32_802_11_channel_vals[] = {
535         { 2412000, "1" },
536         { 2417000, "2" },
537         { 2422000, "3" },
538         { 2427000, "4" },
539         { 2432000, "5" },
540         { 2437000, "6" },
541         { 2442000, "7" },
542         { 2447000, "8" },
543         { 2452000, "9" },
544         { 2457000, "10" },
545         { 2462000, "11" },
546         { 2467000, "12" },
547         { 2472000, "13" },
548         { 2484000, "14" },
549     { 0, NULL }
550 };
551
552
553 /* ElementID in NDIS_802_11_VARIABLE_IEs */
554 static const value_string ie_id_vals[] = {
555         { 0, "SSID, 802.11" },
556         { 1, "Supported Rates, 802.11" },
557         { 2, "FH Parameter Set, 802.11" },
558         { 3, "DS Parameter Set, 802.11" },
559         { 4, "CF Parameter Set, 802.11" },
560         { 5, "TIM, 802.11" },
561         { 6, "IBSS Parameter Set, 802.11" },
562         { 7, "Country, 802.11d" },
563         { 8, "Hopping Pattern Parameters, 802.11d" },
564         { 9, "Hopping Pattern Table, 802.11d" },
565         { 10, "Request, 802.11d" },
566     /* 11-15 reserved, 802.11d */
567         { 16, "Challenge text, 802.11" },
568     /* 17-31 reserved, 802.11h */
569         { 32, "Power Constraint, 802.11h" },
570         { 33, "Power Capability, 802.11h" },
571         { 34, "TPC Request, 802.11h" },
572         { 35, "TPC Report, 802.11h" },
573         { 36, "Supported Channels, 802.11h" },
574         { 37, "Channel Switch Announcement, 802.11h" },
575         { 38, "Measurement Request, 802.11h" },
576         { 39, "Measurement Report, 802.11h" },
577         { 40, "Quiet, 802.11h" },
578         { 41, "IBSS DFS, 802.11h" },
579         { 42, "ERP information, 802.11g" },
580     /* 43-47 reserved, 802.11i */
581         { 48, "WPA2/RSN (Robust Secure Network), 802.11i" },
582     /* 49 reserved, 802.11i */
583         { 50, "Extended Supported Rates, 802.11g" },
584     /* 51-255 reserved, 802.11g */
585         { 221, "WPA, (no 802.11!)" },
586     { 0, NULL }
587 };
588
589
590 static const value_string oid_vals[] = {
591         { OID_GEN_SUPPORTED_LIST, "OID_GEN_SUPPORTED_LIST" },
592         { OID_GEN_HARDWARE_STATUS, "OID_GEN_HARDWARE_STATUS (only internally interesting)" },
593         { OID_GEN_MEDIA_SUPPORTED, "OID_GEN_MEDIA_SUPPORTED" },
594         { OID_GEN_MEDIA_IN_USE, "OID_GEN_MEDIA_IN_USE" },
595     { OID_GEN_MAXIMUM_LOOKAHEAD, "OID_GEN_MAXIMUM_LOOKAHEAD (unused)" },
596         { OID_GEN_MAXIMUM_FRAME_SIZE, "OID_GEN_MAXIMUM_FRAME_SIZE (unused)" },
597         { OID_GEN_LINK_SPEED, "OID_GEN_LINK_SPEED" },
598         { OID_GEN_TRANSMIT_BUFFER_SPACE, "OID_GEN_TRANSMIT_BUFFER_SPACE" },
599         { OID_GEN_RECEIVE_BUFFER_SPACE, "OID_GEN_RECEIVE_BUFFER_SPACE" },
600         { OID_GEN_TRANSMIT_BLOCK_SIZE, "OID_GEN_TRANSMIT_BLOCK_SIZE" },
601         { OID_GEN_RECEIVE_BLOCK_SIZE, "OID_GEN_RECEIVE_BLOCK_SIZE" },
602         { OID_GEN_VENDOR_ID, "OID_GEN_VENDOR_ID" },
603         { OID_GEN_VENDOR_DESCRIPTION, "OID_GEN_VENDOR_DESCRIPTION" },
604         { OID_GEN_CURRENT_PACKET_FILTER, "OID_GEN_CURRENT_PACKET_FILTER (info seems to be constant)" },
605         { OID_GEN_CURRENT_LOOKAHEAD, "OID_GEN_CURRENT_LOOKAHEAD (only internally interesting)" },
606         { OID_GEN_DRIVER_VERSION, "OID_GEN_DRIVER_VERSION" },
607         { OID_GEN_MAXIMUM_TOTAL_SIZE, "OID_GEN_MAXIMUM_TOTAL_SIZE" },
608         { OID_GEN_PROTOCOL_OPTIONS, "OID_GEN_PROTOCOL_OPTIONS (info not interesting)" },
609     { OID_GEN_MAC_OPTIONS, "OID_GEN_MAC_OPTIONS" },
610         { OID_GEN_MEDIA_CONNECT_STATUS, "OID_GEN_MEDIA_CONNECT_STATUS" },
611         { OID_GEN_MAXIMUM_SEND_PACKETS, "OID_GEN_MAXIMUM_SEND_PACKETS (only internally interesting)" },
612         { OID_GEN_VENDOR_DRIVER_VERSION, "OID_GEN_VENDOR_DRIVER_VERSION" },
613         { OID_GEN_XMIT_OK, "OID_GEN_XMIT_OK" },
614         { OID_GEN_RCV_OK, "OID_GEN_RCV_OK" },
615         { OID_GEN_XMIT_ERROR, "OID_GEN_XMIT_ERROR" },
616         { OID_GEN_RCV_ERROR, "OID_GEN_RCV_ERROR" },
617         { OID_GEN_RCV_NO_BUFFER, "OID_GEN_RCV_NO_BUFFER" },
618         { OID_GEN_DIRECTED_BYTES_XMIT, "OID_GEN_DIRECTED_BYTES_XMIT" },
619         { OID_GEN_DIRECTED_FRAMES_XMIT, "OID_GEN_DIRECTED_FRAMES_XMIT" },
620         { OID_GEN_MULTICAST_BYTES_XMIT, "OID_GEN_MULTICAST_BYTES_XMIT" },
621         { OID_GEN_MULTICAST_FRAMES_XMIT, "OID_GEN_MULTICAST_FRAMES_XMIT" },
622         { OID_GEN_BROADCAST_BYTES_XMIT, "OID_GEN_BROADCAST_BYTES_XMIT" },
623         { OID_GEN_BROADCAST_FRAMES_XMIT, "OID_GEN_BROADCAST_FRAMES_XMIT" },
624         { OID_GEN_DIRECTED_BYTES_RCV, "OID_GEN_DIRECTED_BYTES_RCV" },
625         { OID_GEN_DIRECTED_FRAMES_RCV, "OID_GEN_DIRECTED_FRAMES_RCV" },
626         { OID_GEN_MULTICAST_BYTES_RCV, "OID_GEN_MULTICAST_BYTES_RCV" },
627         { OID_GEN_MULTICAST_FRAMES_RCV, "OID_GEN_MULTICAST_FRAMES_RCV" },
628         { OID_GEN_BROADCAST_BYTES_RCV, "OID_GEN_BROADCAST_BYTES_RCV" },
629     { OID_GEN_BROADCAST_FRAMES_RCV, "OID_GEN_BROADCAST_FRAMES_RCV" },
630         { OID_GEN_RCV_CRC_ERROR, "OID_GEN_RCV_CRC_ERROR" },
631         { OID_GEN_TRANSMIT_QUEUE_LENGTH, "OID_GEN_TRANSMIT_QUEUE_LENGTH" },
632         { OID_GEN_GET_TIME_CAPS, "OID_GEN_GET_TIME_CAPS (unsupp, unused)" },
633         { OID_GEN_GET_NETCARD_TIME, "OID_GEN_GET_NETCARD_TIME (unsupp, unused)" },
634
635     { OID_GEN_PHYSICAL_MEDIUM, "OID_GEN_PHYSICAL_MEDIUM" },
636         /*{ OID_GEN_MACHINE_NAME, "OID_GEN_MACHINE_NAME (unsupp, unused)" },*/
637         { OID_GEN_VLAN_ID, "OID_GEN_VLAN_ID" },
638         { OID_GEN_MEDIA_CAPABILITIES, "OID_GEN_MEDIA_CAPABILITIES (unsupp, unused)" },
639
640     { OID_GEN_NETWORK_LAYER_ADDRESSES, "OID_GEN_NETWORK_LAYER_ADDRESSES (write only)" },
641     { OID_GEN_TRANSPORT_HEADER_OFFSET, "OID_GEN_TRANSPORT_HEADER_OFFSET (write only)" },
642
643         { OID_802_3_PERMANENT_ADDRESS, "OID_802_3_PERMANENT_ADDRESS" },
644         { OID_802_3_CURRENT_ADDRESS, "OID_802_3_CURRENT_ADDRESS" },
645     { OID_802_3_MAXIMUM_LIST_SIZE, "OID_802_3_MAXIMUM_LIST_SIZE (unused)" },
646     { OID_802_3_MULTICAST_LIST, "OID_802_3_MULTICAST_LIST (unused)" }, /* XXX */
647     { OID_802_3_MAC_OPTIONS, "OID_802_3_MAC_OPTIONS (unsupp, unused)" },
648
649     { OID_802_3_RCV_ERROR_ALIGNMENT, "OID_802_3_RCV_ERROR_ALIGNMENT" },
650     { OID_802_3_XMIT_ONE_COLLISION, "OID_802_3_XMIT_ONE_COLLISION" },
651     { OID_802_3_XMIT_MORE_COLLISIONS, "OID_802_3_XMIT_MORE_COLLISIONS" },
652     { OID_802_3_XMIT_DEFERRED, "OID_802_3_XMIT_DEFERRED" },
653     { OID_802_3_XMIT_MAX_COLLISIONS, "OID_802_3_XMIT_MAX_COLLISIONS" },
654     { OID_802_3_RCV_OVERRUN, "OID_802_3_RCV_OVERRUN" },
655     { OID_802_3_XMIT_UNDERRUN, "OID_802_3_XMIT_UNDERRUN" },
656     { OID_802_3_XMIT_HEARTBEAT_FAILURE, "OID_802_3_XMIT_HEARTBEAT_FAILURE (unsupp, used)" },
657     { OID_802_3_XMIT_TIMES_CRS_LOST, "OID_802_3_XMIT_TIMES_CRS_LOST (unsupp, used)" },
658     { OID_802_3_XMIT_LATE_COLLISIONS, "OID_802_3_XMIT_LATE_COLLISIONS" },
659
660     { OID_802_11_BSSID, "OID_802_11_BSSID" },
661         { OID_802_11_SSID, "OID_802_11_SSID" },
662         { OID_802_11_NETWORK_TYPES_SUPPORTED, "OID_802_11_NETWORK_TYPES_SUPPORTED (info not interesting)" },
663         { OID_802_11_NETWORK_TYPE_IN_USE, "OID_802_11_NETWORK_TYPE_IN_USE" },
664         { OID_802_11_TX_POWER_LEVEL, "OID_802_11_TX_POWER_LEVEL (unsupp, used)" },
665         { OID_802_11_RSSI, "OID_802_11_RSSI" },
666         { OID_802_11_RSSI_TRIGGER, "OID_802_11_RSSI_TRIGGER (unsupp, unused)" },
667     { OID_802_11_INFRASTRUCTURE_MODE, "OID_802_11_INFRASTRUCTURE_MODE" },
668         { OID_802_11_FRAGMENTATION_THRESHOLD, "OID_802_11_FRAGMENTATION_THRESHOLD (unused)" },
669         { OID_802_11_RTS_THRESHOLD, "OID_802_11_RTS_THRESHOLD (unused)" },
670         { OID_802_11_NUMBER_OF_ANTENNAS, "OID_802_11_NUMBER_OF_ANTENNAS (unsupp, unused)" },
671         { OID_802_11_RX_ANTENNA_SELECTED, "OID_802_11_RX_ANTENNA_SELECTED (unsupp, unused)" },
672         { OID_802_11_TX_ANTENNA_SELECTED, "OID_802_11_TX_ANTENNA_SELECTED (unsupp, unused)" },
673         { OID_802_11_SUPPORTED_RATES, "OID_802_11_SUPPORTED_RATES" },
674         { OID_802_11_DESIRED_RATES, "OID_802_11_DESIRED_RATES (unsupp, used)" },
675         { OID_802_11_CONFIGURATION, "OID_802_11_CONFIGURATION" },
676         { OID_802_11_STATISTICS, "OID_802_11_STATISTICS (unsupp, unused)" },
677         { OID_802_11_ADD_WEP, "OID_802_11_ADD_WEP (write only)" },
678         { OID_802_11_REMOVE_WEP, "OID_802_11_REMOVE_WEP (write only)" },
679         { OID_802_11_DISASSOCIATE, "OID_802_11_DISASSOCIATE (write only)" },
680         { OID_802_11_POWER_MODE, "OID_802_11_POWER_MODE (info not interesting)" },
681         { OID_802_11_BSSID_LIST, "OID_802_11_BSSID_LIST" },
682         { OID_802_11_AUTHENTICATION_MODE, "OID_802_11_AUTHENTICATION_MODE" },
683         { OID_802_11_PRIVACY_FILTER, "OID_802_11_PRIVACY_FILTER (info not interesting)" },
684         { OID_802_11_BSSID_LIST_SCAN, "OID_802_11_BSSID_LIST_SCAN" },
685         { OID_802_11_WEP_STATUS, "OID_802_11_WEP_STATUS (info not interesting?)" },
686         { OID_802_11_ENCRYPTION_STATUS, "OID_802_11_ENCRYPTION_STATUS (unsupp, used)" },
687         { OID_802_11_RELOAD_DEFAULTS, "OID_802_11_RELOAD_DEFAULTS (write only)" },
688         { OID_802_11_ADD_KEY, "OID_802_11_ADD_KEY (write only)" },
689         { OID_802_11_REMOVE_KEY, "OID_802_11_REMOVE_KEY (write only)" },
690         { OID_802_11_ASSOCIATION_INFORMATION, "OID_802_11_ASSOCIATION_INFORMATION (unused)" }, /* XXX */
691         { OID_802_11_TEST, "OID_802_11_TEST (write only)" },
692         { OID_802_11_CAPABILITY, "OID_802_11_CAPABILITY (unsupp, unused)" },
693         { OID_802_11_PMKID, "OID_802_11_PMKID (unsupp, unused)" },
694
695     /* Token-Ring list is utterly incomplete (contains only the values for MS Loopback Driver) */
696     { OID_802_5_PERMANENT_ADDRESS, "OID_802_5_PERMANENT_ADDRESS (unused)" },
697     { OID_802_5_CURRENT_ADDRESS, "OID_802_5_CURRENT_ADDRESS (unused)" },
698     { OID_802_5_CURRENT_FUNCTIONAL, "OID_802_5_CURRENT_FUNCTIONAL (unused)" },
699     { OID_802_5_CURRENT_GROUP, "OID_802_5_CURRENT_GROUP (unused)" },
700     { OID_802_5_LAST_OPEN_STATUS, "OID_802_5_LAST_OPEN_STATUS (unused)" },
701     { OID_802_5_CURRENT_RING_STATUS, "OID_802_5_CURRENT_RING_STATUS (unused)" },
702     { OID_802_5_CURRENT_RING_STATE, "OID_802_5_CURRENT_RING_STATE (unused)" },
703     { OID_802_5_LINE_ERRORS, "OID_802_5_LINE_ERRORS (unused)" },
704     { OID_802_5_LOST_FRAMES, "OID_802_5_LOST_FRAMES (unused)" },
705
706     /* FDDI list is utterly incomplete (contains only the values for MS Loopback Driver) */
707     { OID_FDDI_LONG_PERMANENT_ADDR, "OID_FDDI_LONG_PERMANENT_ADDR (unused)" },
708     { OID_FDDI_LONG_CURRENT_ADDR, "OID_FDDI_LONG_CURRENT_ADDR (unused)" },
709     { OID_FDDI_LONG_MULTICAST_LIST, "OID_FDDI_LONG_MULTICAST_LIST (unused)" },
710     { OID_FDDI_LONG_MAX_LIST_SIZE, "OID_FDDI_LONG_MAX_LIST_SIZE (unused)" },
711     { OID_FDDI_SHORT_PERMANENT_ADDR, "OID_FDDI_SHORT_PERMANENT_ADDR (unused)" },
712     { OID_FDDI_SHORT_CURRENT_ADDR, "OID_FDDI_SHORT_CURRENT_ADDR (unused)" },
713     { OID_FDDI_SHORT_MULTICAST_LIST, "OID_FDDI_SHORT_MULTICAST_LIST (unused)" },
714     { OID_FDDI_SHORT_MAX_LIST_SIZE, "OID_FDDI_SHORT_MAX_LIST_SIZE (unused)" },
715
716     /* LocalTalk list is utterly incomplete (contains only the values for MS Loopback Driver) */
717     { OID_LTALK_CURRENT_NODE_ID, "OID_LTALK_CURRENT_NODE_ID (unused)" },
718
719     /* Arcnet list is utterly incomplete (contains only the values for MS Loopback Driver) */
720     { OID_ARCNET_PERMANENT_ADDRESS, "OID_ARCNET_PERMANENT_ADDRESS (unused)" },
721     { OID_ARCNET_CURRENT_ADDRESS, "OID_ARCNET_CURRENT_ADDRESS (unused)" },
722
723     { OID_TCP_TASK_OFFLOAD, "OID_TCP_TASK_OFFLOAD" },
724
725     /* PnP and power management OIDs */
726     { OID_PNP_CAPABILITIES, "OID_PNP_CAPABILITIES (unused)" },
727     { OID_PNP_SET_POWER, "OID_PNP_SET_POWER (write only)" },
728     { OID_PNP_QUERY_POWER, "OID_PNP_QUERY_POWER (unused)" },
729     { OID_PNP_ADD_WAKE_UP_PATTERN, "OID_PNP_ADD_WAKE_UP_PATTERN (write only)" },
730     { OID_PNP_REMOVE_WAKE_UP_PATTERN, "OID_PNP_REMOVE_WAKE_UP_PATTERN (write only)" },
731     { OID_PNP_WAKE_UP_PATTERN_LIST, "OID_PNP_WAKE_UP_PATTERN_LIST (unused)" },
732     { OID_PNP_ENABLE_WAKE_UP, "OID_PNP_ENABLE_WAKE_UP (unused)" },
733
734     /* Unknown OID's (seen on an "Intel(R) PRO/Wireless 2200BG" 802.11 interface) */
735     { 0xFF100000, "Unknown 0xFF100000 (unused)" },
736     { 0xFF100002, "Unknown 0xFF100002 (unused)" },
737     { 0xFF100003, "Unknown 0xFF100003 (unused)" },
738     { 0xFF100004, "Unknown 0xFF100004 (unused)" },
739     { 0xFF100005, "Unknown 0xFF100005 (unused)" },
740     { 0xFF100006, "Unknown 0xFF100006 (unused)" },
741     { 0xFF100007, "Unknown 0xFF100007 (unused)" },
742     { 0xFF100009, "Unknown 0xFF100009 (unused)" },
743     { 0xFF10000b, "Unknown 0xFF10000b (unused)" },
744     { 0xFF10000c, "Unknown 0xFF10000c (unused)" },
745     { 0xFF10000e, "Unknown 0xFF10000e (unused)" },
746     { 0xFF10000f, "Unknown 0xFF10000f (unused)" },
747     /* continued by a lot more 0xFF... values */
748
749     { 0, NULL }
750 };
751
752
753 /***************************************************************************/
754 /* debug functions, query or list supported NDIS OID's */
755
756
757 static void
758 supported_list(LPADAPTER adapter)
759 {
760     unsigned char       values[10000];
761     int                 length;
762
763
764     g_warning("supported_list_unhandled");
765     length = sizeof(values);
766     if (wpcap_packet_request(adapter, OID_GEN_SUPPORTED_LIST, FALSE /* !set */, values, &length)) {
767         guint32 *value = (guint32 *) values;
768
769         while (length>=4) {
770             printf("OID: 0x%08X %s\n", *value, val_to_str(*value, oid_vals, "unknown"));
771
772             value++;
773             length-=4;
774         }
775     }
776 }
777
778
779 static gboolean
780 supported_query_oid(LPADAPTER adapter, guint32 oid)
781 {
782     unsigned char       values[10000];
783     int                 length;
784
785
786     length = sizeof(values);
787     if (wpcap_packet_request(adapter, OID_GEN_SUPPORTED_LIST, FALSE /* !set */, values, &length)) {
788         guint32 *value = (guint32 *) values;
789
790         while (length>=4) {
791             if(*value == oid) {
792                 return TRUE;
793             }
794             value++;
795             length-=4;
796         }
797     }
798
799     return FALSE;
800 }
801
802
803 /******************************************************************************/
804 /* info functions, get and display various NDIS driver values */
805
806
807
808     GtkWidget *meter;
809     GtkWidget *val_lb;
810
811 static GtkWidget *
812 add_meter_to_table(GtkWidget *list, guint *row, gchar *title,
813                  int value, gchar *value_title,
814                  int min, int max,
815                  int yellow_level,
816                  GList *scale)
817 {
818     GtkWidget *label;
819     gchar     *indent;
820     GtkWidget *main_hb;
821
822
823     /* the label */
824     indent = g_strdup_printf("   %s", title);
825     label = gtk_label_new(indent);
826     g_free(indent);
827     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
828     gtk_table_attach(GTK_TABLE(list), label, 0, 1, *row, *row+1, GTK_EXPAND|GTK_FILL, 0, 0,0);
829
830     /* the level meter */
831     main_hb = gtk_hbox_new(FALSE, 6);
832
833     meter = gtk_vumeter_new ();
834
835     gtk_vumeter_set_orientation(GTK_VUMETER(meter), GTK_VUMETER_LEFT_TO_RIGHT);
836
837     gtk_vumeter_set_min_max(GTK_VUMETER(meter), &min, &max);
838     gtk_vumeter_set_yellow_level (GTK_VUMETER(meter), yellow_level);
839     gtk_vumeter_set_thickness (GTK_VUMETER(meter), 10);
840     gtk_vumeter_set_thickness_reduction (GTK_VUMETER(meter), 2);
841     gtk_vumeter_set_scale_hole_size (GTK_VUMETER(meter), 2);
842     gtk_vumeter_set_colors_inverted (GTK_VUMETER(meter), TRUE);
843
844     if(scale) {
845         gtk_vumeter_set_scale_items(GTK_VUMETER(meter), scale);
846     }
847
848     gtk_vumeter_set_level(GTK_VUMETER(meter), value);
849
850     gtk_box_pack_start                (GTK_BOX(main_hb),
851                                              meter,
852                                              TRUE /*expand*/,
853                                              TRUE /*fill*/,
854                                              0 /* padding */);
855
856     val_lb = gtk_label_new(value_title);
857     gtk_widget_set_size_request(val_lb, 50, -1);
858     gtk_misc_set_alignment(GTK_MISC(val_lb), 1.0, 0.5);
859
860     gtk_box_pack_start                (GTK_BOX(main_hb),
861                                              val_lb,
862                                              FALSE /*expand*/,
863                                              FALSE /*fill*/,
864                                              0 /* padding */);
865
866     gtk_table_attach(GTK_TABLE(list), main_hb, 1, 2, *row, *row+1, GTK_EXPAND|GTK_FILL, 0, 0,0);
867
868     *row = *row + 1;
869
870     return meter;
871 }
872
873
874
875 static void
876 add_row_to_table(GtkWidget *list, guint *row, gchar *title, const gchar *value, gboolean sensitive)
877 {
878     GtkWidget *label;
879     gchar     *indent;
880
881     if(strlen(value) != 0) {
882         indent = g_strdup_printf("   %s", title);
883     } else {
884         indent = g_strdup(title);
885     }
886     label = gtk_label_new(indent);
887     g_free(indent);
888     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
889     gtk_widget_set_sensitive(label, sensitive);
890     gtk_table_attach(GTK_TABLE(list), label, 0, 1, *row, *row+1, GTK_EXPAND | GTK_FILL, 0, 0,0);
891
892     label = gtk_label_new(value);
893     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
894     gtk_widget_set_sensitive(label, sensitive);
895     gtk_table_attach(GTK_TABLE(list), label, 1, 2, *row, *row+1, GTK_EXPAND | GTK_FILL, 0, 0,0);
896
897     *row = *row + 1;
898 }
899
900
901 static void
902 add_string_to_table_sensitive(GtkWidget *list, guint *row, gchar *title, gchar *value, gboolean sensitive)
903 {
904     add_row_to_table(list, row, title, value, sensitive);
905 }
906
907
908 static void
909 add_string_to_table(GtkWidget *list, guint *row, gchar *title, const gchar *value)
910 {
911     add_row_to_table(list, row, title, value, TRUE);
912 }
913
914
915 static void
916 ssid_details(GtkWidget *table, guint *row, struct ndis_essid *ssid_in) {
917     struct ndis_essid   ssid[2]; /* prevent an off by one error */
918
919
920     ssid[0] = *ssid_in;
921     g_assert(ssid->length <= NDIS_ESSID_MAX_SIZE);
922
923     if(ssid->length != 0) {
924         ssid->essid[ssid->length] = '\0';
925         add_string_to_table(table, row, "SSID (Service Set IDentifier)", ssid->essid);
926     } else {
927         add_string_to_table(table, row, "SSID (Service Set IDentifier)", "(currently not associated with an SSID)");
928     }
929 }
930
931
932 static GString *
933 rates_details(unsigned char *values, int length) {
934     int                 i;
935     GString             *Rates;
936     float               float_value;
937     int                 int_value;
938
939
940     Rates = g_string_new("");
941
942     if(length != 0) {
943         i = 0;
944         while(length--) {
945             if(values[i]) {
946                 if(i != 0) {
947                     g_string_append(Rates, "/");
948                 }
949
950                 float_value = ((float) (values[i] & 0x7F)) / 2;
951
952                 /* reduce the screen estate by showing fractions only where required */
953                 int_value = (int)float_value;
954                 if(float_value == (float)int_value) {
955                     g_string_append_printf(Rates, "%.0f", float_value);
956                 } else {
957                     g_string_append_printf(Rates, "%.1f", float_value);
958                 }
959             }
960             i++;
961         }
962         Rates = g_string_append(Rates, " MBits/s");
963     } else {
964         Rates = g_string_append(Rates, "-");
965     }
966
967     return Rates;
968 }
969
970
971
972 static GList *
973 rates_vu_list(unsigned char *values, int length, int *max)
974 {
975     int                 i;
976     GList               *Rates = NULL;
977     GtkVUMeterScaleItem * item;
978
979
980     *max = 0;
981
982     if(length == 0) {
983         return NULL;
984     }
985
986     /* add a zero scale point */
987     item = g_malloc(sizeof(GtkVUMeterScaleItem));
988     item->level = 0;
989     item->large = TRUE;
990     item->label = "0";
991     Rates = g_list_append(Rates, item);
992
993     /* get the maximum rate */
994     for(i=0; i<length; i++) {
995         gint level;
996
997         if(values[i]) {
998             level = (values[i] & 0x7F) / 2;
999
1000             if(level > *max) {
1001                 *max = level;
1002             }
1003         }
1004     }
1005
1006 #if 0
1007     /* debug: fake the 108MBit entry (I don't own one :-) */
1008     *max = 108;
1009
1010     item = g_malloc(sizeof(GtkVUMeterScaleItem));
1011     item->level = 108;
1012     item->large = TRUE;
1013     item->label = "108";
1014     Rates = g_list_append(Rates, item);
1015 #endif
1016
1017     for(i=0; i<length; i++) {
1018         if(values[i]) {
1019             /* reduce the screen estate by showing fractions only where required */
1020             item = g_malloc(sizeof(GtkVUMeterScaleItem));
1021
1022             item->level = (values[i] & 0x7F) / 2;
1023
1024             /* common data rates: */
1025             /* 802.11  (15.1)  : mandatory: 2, 1 */
1026             /* 802.11a (17.1)  : mandatory: 24, 12, 6 optional: 54, 48, 36, 18, 9 */
1027             /* 802.11b (18.1)  : mandatory: 11, 5.5 (+ 2, 1) */
1028             /* 802.11g (19.1.1): mandatory: 24, 12, 11, 6, 5.5, 2, 1 optional: 54, 48, 36, 33, 22, 18, 9 */
1029             /* 802.11n: ? */
1030             /* proprietary: 108 */
1031
1032             switch(item->level) {
1033             case 2:
1034                 if(*max >= 108) {
1035                     item->large = FALSE;
1036                     item->label = NULL;
1037                 } else {
1038                     item->large = TRUE;
1039                     item->label = "2";
1040                 }
1041                 break;
1042             case 5:
1043                 item->large = TRUE;
1044                 item->label = "5.5";
1045                 break;
1046             case 11:
1047                 item->large = TRUE;
1048                 item->label = "11";
1049                 break;
1050             case 18:
1051                 item->large = TRUE;
1052                 item->label = "18";
1053                 break;
1054             case 24:
1055                 item->large = TRUE;
1056                 item->label = "24";
1057                 break;
1058             case 36:
1059                 item->large = TRUE;
1060                 item->label = "36";
1061                 break;
1062             case 48:
1063                 item->large = TRUE;
1064                 item->label = "48";
1065                 break;
1066             case 54:
1067                 item->large = TRUE;
1068                 item->label = "54";
1069                 break;
1070             case 72: /* XXX */
1071                 item->large = TRUE;
1072                 item->label = "72";
1073                 break;
1074             case 96: /* XXX */
1075                 item->large = TRUE;
1076                 item->label = "96";
1077                 break;
1078             case 108:
1079                 item->large = TRUE;
1080                 item->label = "108";
1081                 break;
1082             default:
1083                 item->large = FALSE;
1084                 item->label = NULL;
1085             }
1086
1087             Rates = g_list_append(Rates, item);
1088         }
1089     }
1090
1091     return Rates;
1092 }
1093
1094
1095 /* debugging only */
1096 static void
1097 hex(unsigned char *p, int len) {
1098     int i = 0;
1099     while(len) {
1100         g_warning("%u: 0x%x (%u) '%c'", i, *p, *p,
1101             isprint(*p) ? *p : '.');
1102
1103         i++;
1104         p++;
1105         len--;
1106     }
1107 }
1108
1109
1110 static void
1111 capture_if_details_802_11_bssid_list(GtkWidget *main_vb, struct ndis_bssid_list *bssid_list)
1112 {
1113     struct ndis_ssid_item   *bssid_item;
1114     unsigned char           mac[6];
1115     const gchar             *manuf_name;
1116     GString                 *Rates;
1117
1118
1119     if(bssid_list->num_items != 0) {
1120         char *titles[] = { "SSID", "MAC", "Vendor", "Privacy", "RSSI" , "Network Type" , "Infra. Mode" , "Ch." , "Rates" };
1121         GtkWidget   *list;
1122         gboolean    privacy_required;
1123         gboolean    privacy_wpa;
1124         gboolean    privacy_wpa2;
1125
1126         gchar ssid_buff[DETAILS_STR_MAX];
1127         gchar mac_buff[DETAILS_STR_MAX];
1128         gchar vendor_buff[DETAILS_STR_MAX];
1129         gchar privacy_buff[DETAILS_STR_MAX];
1130         gchar rssi_buff[DETAILS_STR_MAX];
1131         gchar nettype_buff[DETAILS_STR_MAX];
1132         gchar infra_buff[DETAILS_STR_MAX];
1133         gchar freq_buff[DETAILS_STR_MAX];
1134
1135         list = simple_list_new(9, titles);
1136         gtk_box_pack_start(GTK_BOX(main_vb), list, TRUE /*expand*/, TRUE /*fill*/, 0 /* padding */);
1137
1138         bssid_item = &bssid_list->items[0];
1139
1140         while(bssid_list->num_items--) {
1141             privacy_required = FALSE;
1142             privacy_wpa = FALSE;
1143             privacy_wpa2 = FALSE;
1144
1145             /* SSID */
1146             if(bssid_item->ssid.length > DETAILS_STR_MAX-1) {
1147                 bssid_item->ssid.length = DETAILS_STR_MAX-1;
1148             }
1149             memcpy(ssid_buff, bssid_item->ssid.essid, bssid_item->ssid.length);
1150             ssid_buff[bssid_item->ssid.length] = '\0';
1151
1152             /* MAC */
1153             memcpy(mac, &bssid_item->mac, sizeof(mac));
1154             g_snprintf(mac_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
1155                 mac[0], mac[1], mac[2],
1156                 mac[3], mac[4], mac[5]);
1157
1158             /* Vendor */
1159             manuf_name = get_manuf_name_if_known(mac);
1160             if(manuf_name != NULL) {
1161                 g_strlcpy(vendor_buff, manuf_name, DETAILS_STR_MAX);
1162             } else {
1163                 vendor_buff[0] = '\0';
1164             }
1165
1166             /* Supported Rates */
1167             Rates = rates_details(bssid_item->rates, NDIS_MAX_RATES_EX);
1168
1169             /* RSSI */
1170             g_snprintf(rssi_buff, DETAILS_STR_MAX, "%d dBm", bssid_item->rssi);
1171
1172             /* Privacy */
1173             /* (flag is set, if WEP (or higher) privacy is required) */
1174             if(bssid_item->privacy) {
1175                 privacy_required = TRUE;
1176             }
1177
1178             /* Network Type */
1179             g_snprintf(nettype_buff, sizeof(nettype_buff), "%s",
1180                 val_to_str(bssid_item->net_type, win32_802_11_network_type_vals, "(0x%x)"));
1181
1182             /* Infrastructure Mode */
1183             g_snprintf(infra_buff, sizeof(infra_buff), "%s",
1184                 val_to_str(bssid_item->mode, win32_802_11_infra_mode_vals, "(0x%x)"));
1185
1186             /* Channel */
1187             g_snprintf(freq_buff, sizeof(freq_buff), "%s",
1188                 val_to_str(bssid_item->config.ds_config, win32_802_11_channel_vals, "(%u kHz)"));
1189
1190             /* XXX - IE Length is currently not really supported here */
1191             {
1192                 int len = bssid_item->ie_length;
1193                 unsigned char *iep = bssid_item->ies;
1194                 unsigned char id;
1195                 unsigned el_len;
1196                 NDIS_802_11_FIXED_IEs *fixed_ies;
1197 /*#define DEBUG_IE*/
1198 #ifdef DEBUG_IE
1199                 const gchar     *manuf_name;
1200                 gchar           string_buff[DETAILS_STR_MAX];
1201 #endif
1202
1203
1204                 fixed_ies = (NDIS_802_11_FIXED_IEs *) iep;
1205
1206 #if 0
1207                   UCHAR  Timestamp[8];
1208   USHORT  BeaconInterval;
1209   USHORT  Capabilities;
1210 } NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
1211 #endif
1212
1213                 iep += sizeof(NDIS_802_11_FIXED_IEs);
1214                 len = bssid_item->ie_length - sizeof(NDIS_802_11_FIXED_IEs);
1215
1216                 while(len >= 2) {
1217                     id = *iep;
1218                     iep++;
1219                     el_len = *iep;
1220                     iep++;
1221                     len-=2;
1222
1223 #ifdef DEBUG_IE
1224                     g_warning("ID: %s (%u) Len: %u",
1225                         val_to_str(id, ie_id_vals, "0x%x"), id, el_len);
1226 #endif
1227
1228                     if (id != 0 && id != 1 && id != 3 && id != 5 && id != 42 && id != 50 && id != 221) {
1229                         hex(iep, el_len);
1230                     }
1231
1232                     /* WPA2 (RSN) */
1233                     if (id == 48) {
1234                         privacy_wpa2 = TRUE;
1235                     }
1236
1237                     /* WPA */
1238                     if (id == 221) {
1239                         privacy_wpa = TRUE;
1240
1241 #ifdef DEBUG_IE
1242                         /* include information from epan/packet-ieee80211.c dissect_vendor_ie_wpawme() */
1243                         manuf_name = get_manuf_name_if_known(iep);
1244                         if(manuf_name != NULL) {
1245                             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X (%s) Type: %02X",
1246                                 *(iep), *(iep+1), *(iep+2), manuf_name, *(iep+3));
1247                         } else {
1248                             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X Type: %02X",
1249                                 *(iep), *(iep+1), *(iep+2), *(iep+3));
1250                         }
1251
1252                         g_warning("%s", string_buff);
1253                         iep += 4;
1254                         el_len-= 4;
1255                         len -= 4;
1256
1257                         hex(iep, el_len);
1258 #endif
1259                     }
1260
1261                     iep += el_len;
1262                     len -= el_len;
1263                 }
1264             }
1265
1266             if(privacy_required) {
1267                 if(privacy_wpa2) {
1268                     /* XXX - how to detect data encryption (TKIP and AES)? */
1269                     /* XXX - how to detect authentication (PSK or not)? */
1270                     g_snprintf(privacy_buff, DETAILS_STR_MAX, "WPA2");
1271                 } else {
1272                     if(privacy_wpa) {
1273                         /* XXX - how to detect data encryption (TKIP and AES)? */
1274                         /* XXX - how to detect authentication (PSK or not)? */
1275                         g_snprintf(privacy_buff, DETAILS_STR_MAX, "WPA");
1276                     } else {
1277                         /* XXX - how to detect authentication (Open System and Shared Key)? */
1278                         g_snprintf(privacy_buff, DETAILS_STR_MAX, "WEP");
1279                     }
1280                 }
1281             } else {
1282                 g_snprintf(privacy_buff, DETAILS_STR_MAX, "None");
1283             }
1284
1285             simple_list_append(list,
1286                 0, ssid_buff,
1287                 1, mac_buff,
1288                 2, vendor_buff,
1289                 3, privacy_buff,
1290                 4, rssi_buff,
1291                 5, nettype_buff,
1292                 6, infra_buff,
1293                 7, freq_buff,
1294                 8, Rates->str,
1295                 -1);
1296
1297             g_string_free(Rates, TRUE /* free_segment */);
1298
1299             /* the bssid_list isn't an array, but a sequence of variable length items */
1300             bssid_item = (struct ndis_ssid_item *) (((char *) bssid_item) + bssid_item->length);
1301         }
1302     }
1303 }
1304
1305 static int
1306 capture_if_details_802_11(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) {
1307     ULONG               ulong_value;
1308     LONG                rssi = -100;
1309     unsigned int        uint_value;
1310     unsigned char       values[100];
1311     struct ndis_essid   ssid;
1312     int                 length;
1313     struct ndis_bssid_list      *bssid_list;
1314     struct ndis_configuration   *configuration;
1315     gchar               string_buff[DETAILS_STR_MAX];
1316     GString             *Rates;
1317     int                 entries = 0;
1318     const gchar         *manuf_name;
1319
1320
1321     add_string_to_table(table, row, "Current network", "");
1322
1323     /* SSID */
1324     length = sizeof(struct ndis_essid);
1325     memset(&ssid, 0, length);
1326     if (wpcap_packet_request(adapter, OID_802_11_SSID, FALSE /* !set */, (char *) &ssid, &length)) {
1327         ssid_details(table, row, &ssid);
1328         entries++;
1329     } else {
1330         add_string_to_table(table, row, "SSID (Service Set IDentifier)", "-");
1331     }
1332
1333     /* BSSID */
1334     length = sizeof(values);
1335     memset(values, 0, 6);
1336     if (wpcap_packet_request(adapter, OID_802_11_BSSID, FALSE /* !set */, values, &length)) {
1337         manuf_name = get_manuf_name_if_known(values);
1338         if(manuf_name != NULL) {
1339             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
1340                 values[0], values[1], values[2],
1341                 values[3], values[4], values[5],
1342                 manuf_name);
1343         } else {
1344             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
1345                 values[0], values[1], values[2],
1346                 values[3], values[4], values[5]);
1347         }
1348         entries++;
1349     } else {
1350         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1351     }
1352     add_string_to_table(table, row, "BSSID (Basic Service Set IDentifier)", string_buff);
1353
1354     /* Network type in use */
1355     if (wpcap_packet_request_uint(adapter, OID_802_11_NETWORK_TYPE_IN_USE, &uint_value)) {
1356         add_string_to_table(table, row, "Network type used",
1357             val_to_str(uint_value, win32_802_11_network_type_vals, "(0x%x)"));
1358         entries++;
1359     } else {
1360         add_string_to_table(table, row, "Network type used", "-");
1361     }
1362
1363     /* Infrastructure mode */
1364     if (wpcap_packet_request_ulong(adapter, OID_802_11_INFRASTRUCTURE_MODE, &uint_value)) {
1365         add_string_to_table(table, row, "Infrastructure mode",
1366             val_to_str(uint_value, win32_802_11_infra_mode_vals, "(0x%x)"));
1367         entries++;
1368     } else {
1369         add_string_to_table(table, row, "Infrastructure mode", "-");
1370     }
1371
1372     /* Authentication mode */
1373     if (wpcap_packet_request_ulong(adapter, OID_802_11_AUTHENTICATION_MODE, &uint_value)) {
1374         add_string_to_table(table, row, "Authentication mode",
1375             val_to_str(uint_value, win32_802_11_auth_mode_vals, "(0x%x)"));
1376         entries++;
1377     } else {
1378         add_string_to_table(table, row, "Authentication mode", "-");
1379     }
1380
1381     /* Encryption (WEP) status */
1382     if (wpcap_packet_request_ulong(adapter, OID_802_11_ENCRYPTION_STATUS, &uint_value)) {
1383         add_string_to_table(table, row, "Encryption status",
1384             val_to_str(uint_value, win32_802_11_encryption_status_vals, "(0x%x)"));
1385         entries++;
1386     } else {
1387         add_string_to_table(table, row, "Encryption status", "-");
1388     }
1389
1390     /* TX power */
1391     if (wpcap_packet_request_ulong(adapter, OID_802_11_TX_POWER_LEVEL, &ulong_value)) {
1392         g_snprintf(string_buff, DETAILS_STR_MAX, "%ld mW", ulong_value);
1393         add_string_to_table(table, row, "TX power", string_buff);
1394         entries++;
1395     } else {
1396         add_string_to_table(table, row, "TX power", "-");
1397     }
1398
1399     /* RSSI */
1400     if (wpcap_packet_request_ulong(adapter, OID_802_11_RSSI, &rssi)) {
1401         int i;
1402         GList * scale_items = NULL;
1403         GList * current;
1404         GtkVUMeterScaleItem *item;
1405
1406
1407         for (i = 0; i <= 100; i++) {
1408             item = g_malloc(sizeof(GtkVUMeterScaleItem));
1409
1410             item->level = i;
1411             item->large = !(i%5);
1412             item->label = NULL;
1413
1414             switch(item->level) {
1415             case 0:
1416                 item->label = "-100 ";
1417                 break;
1418             case 20:
1419                 item->label = "-80 ";
1420                 break;
1421             case 40:
1422                 item->label = "-60 ";
1423                 break;
1424             case 60:
1425                 item->label = "-40 ";
1426                 break;
1427             case 80:
1428                 item->label = "-20 ";
1429                 break;
1430             case 100:
1431                 item->label = "0";
1432                 break;
1433             default:
1434                 item->label = NULL;
1435             }
1436
1437             scale_items = g_list_append(scale_items, item);
1438         }
1439
1440         if(rssi < -100) {
1441             rssi = -100;
1442         }
1443         g_snprintf(string_buff, DETAILS_STR_MAX, "%ld dBm", rssi);
1444
1445         add_meter_to_table(table, row, "RSSI (Received Signal Strength Indication)",
1446             rssi+100 , string_buff, -100+100, 0+100, -80+100, scale_items);
1447
1448         current = scale_items;
1449         while (current != NULL) {
1450             g_free(current->data);
1451
1452             current = g_list_next(current);
1453         }
1454         g_list_free(scale_items);
1455         entries++;
1456     } else {
1457         add_string_to_table(table, row, "RSSI (Received Signal Strength Indication)", "-");
1458     }
1459
1460     /* Supported Rates */
1461     length = sizeof(values);
1462     if (!wpcap_packet_request(adapter, OID_802_11_SUPPORTED_RATES, FALSE /* !set */, values, &length)) {
1463         length = 0;
1464     } else {
1465         entries++;
1466     }
1467
1468     /* if we can get the link speed, show Supported Rates in level meter format */
1469     if (length != 0 && wpcap_packet_request_uint(adapter, OID_GEN_LINK_SPEED, &uint_value)) {
1470         int max;
1471         int yellow;
1472         GList *rates_list;
1473         GList * current;
1474
1475
1476         rates_list = rates_vu_list(values, length, &max);
1477
1478         /* if we don't have a signal, we might not have a valid link speed */
1479         if(rssi == -100) {
1480             uint_value = 0;
1481         }
1482
1483         uint_value /= 10 * 1000;
1484         g_snprintf(string_buff, DETAILS_STR_MAX, "%u MBits/s", uint_value);
1485
1486         if(max >= 54) {
1487             yellow = 2;
1488         } else {
1489             yellow = 1;
1490         }
1491         add_meter_to_table(table, row, "Link Speed",
1492                 uint_value, string_buff, 0, max, yellow, rates_list);
1493
1494         current = rates_list;
1495         while (current != NULL) {
1496             g_free(current->data);
1497
1498             current = g_list_next(current);
1499         }
1500         g_list_free(rates_list);
1501     }
1502
1503     /* Supported Rates in String format */
1504     Rates = rates_details(values, length);
1505     add_string_to_table(table, row, "Supported Rates", Rates->str);
1506     g_string_free(Rates, TRUE /* free_segment */);
1507
1508     /* Desired Rates */
1509     length = sizeof(values);
1510     if (!wpcap_packet_request(adapter, OID_802_11_DESIRED_RATES, FALSE /* !set */, values, &length)) {
1511         length = 0;
1512     } else {
1513         entries++;
1514     }
1515
1516     Rates = rates_details(values, length);
1517     add_string_to_table(table, row, "Desired Rates", Rates->str);
1518     g_string_free(Rates, TRUE /* free_segment */);
1519
1520     /* Configuration (e.g. frequency) */
1521     length = sizeof(values);
1522     if (wpcap_packet_request(adapter, OID_802_11_CONFIGURATION, FALSE /* !set */, (char *) values, &length)) {
1523         configuration = (struct ndis_configuration *) values;
1524
1525         add_string_to_table(table, row, "Channel",
1526             val_to_str(configuration->ds_config, win32_802_11_channel_freq_vals, "(%u kHz)"));
1527         entries++;
1528     } else {
1529         add_string_to_table(table, row, "Channel", "-");
1530     }
1531
1532     /* BSSID list: first trigger a scan */
1533     length = sizeof(uint_value);
1534     if (wpcap_packet_request(adapter, OID_802_11_BSSID_LIST_SCAN, TRUE /* set */, (char *) &uint_value, &length)) {
1535 #if 0
1536         g_warning("BSSID list scan done");
1537     } else {
1538         g_warning("BSSID list scan failed");
1539 #endif
1540     }
1541
1542     /* BSSID list: get scan results */
1543     /* XXX - we might have to wait up to 7 seconds! */
1544         length = sizeof(ULONG) + sizeof(struct ndis_ssid_item) * 16;
1545         bssid_list = g_malloc(length);
1546         /* some drivers don't set bssid_list->num_items to 0 if
1547            OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */
1548         memset(bssid_list, 0, length);
1549
1550     if (wpcap_packet_request(adapter, OID_802_11_BSSID_LIST, FALSE /* !set */, (char *) bssid_list, &length)) {
1551         add_string_to_table(table, row, "", "");
1552         add_string_to_table(table, row, "Available networks (BSSID list)", "");
1553
1554         capture_if_details_802_11_bssid_list(main_vb, bssid_list);
1555         entries += bssid_list->num_items;
1556     } else {
1557         add_string_to_table(table, row, "Available networks (BSSID list)", "-");
1558     }
1559
1560     g_free(bssid_list);
1561
1562     return entries;
1563 }
1564
1565
1566 static int
1567 capture_if_details_802_3(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) {
1568     unsigned int    uint_value;
1569     unsigned char   values[100];
1570     int             length;
1571     gchar           string_buff[DETAILS_STR_MAX];
1572     const gchar     *manuf_name;
1573     int             entries = 0;
1574
1575
1576     add_string_to_table(table, row, "Characteristics", "");
1577
1578     length = sizeof(values);
1579     if (wpcap_packet_request(adapter, OID_802_3_PERMANENT_ADDRESS, FALSE /* !set */, values, &length)) {
1580         manuf_name = get_manuf_name_if_known(values);
1581         if(manuf_name != NULL) {
1582             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
1583                 values[0], values[1], values[2],
1584                 values[3], values[4], values[5],
1585                 manuf_name);
1586         } else {
1587             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
1588                 values[0], values[1], values[2],
1589                 values[3], values[4], values[5]);
1590         }
1591         entries++;
1592     } else {
1593         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1594     }
1595     add_string_to_table(table, row, "Permanent station address", string_buff);
1596
1597     length = sizeof(values);
1598     if (wpcap_packet_request(adapter, OID_802_3_CURRENT_ADDRESS, FALSE /* !set */, values, &length)) {
1599         manuf_name = get_manuf_name_if_known(values);
1600         if(manuf_name != NULL) {
1601             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
1602                 values[0], values[1], values[2],
1603                 values[3], values[4], values[5],
1604                 manuf_name);
1605         } else {
1606             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
1607                 values[0], values[1], values[2],
1608                 values[3], values[4], values[5]);
1609         }
1610         entries++;
1611     } else {
1612         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1613     }
1614     add_string_to_table(table, row, "Current station address", string_buff);
1615
1616
1617     add_string_to_table(table, row, "", "");
1618     add_string_to_table(table, row, "Statistics", "");
1619
1620     if (wpcap_packet_request_uint(adapter, OID_802_3_RCV_ERROR_ALIGNMENT, &uint_value)) {
1621         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1622         entries++;
1623     } else {
1624         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1625     }
1626     add_string_to_table(table, row, "Packets received with alignment error", string_buff);
1627
1628     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_ONE_COLLISION, &uint_value)) {
1629         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1630         entries++;
1631     } else {
1632         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1633     }
1634     add_string_to_table(table, row, "Packets transmitted with one collision", string_buff);
1635
1636     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_MORE_COLLISIONS, &uint_value)) {
1637         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1638         entries++;
1639     } else {
1640         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1641     }
1642     add_string_to_table(table, row, "Packets transmitted with more than one collision", string_buff);
1643
1644     if (wpcap_packet_request_uint(adapter, OID_802_3_RCV_OVERRUN, &uint_value)) {
1645         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1646         entries++;
1647     } else {
1648         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1649     }
1650     add_string_to_table(table, row, "Packets not received due to overrun", string_buff);
1651
1652     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_DEFERRED, &uint_value)) {
1653         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1654         entries++;
1655     } else {
1656         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1657     }
1658     add_string_to_table(table, row, "Packets transmitted after deferred", string_buff);
1659
1660     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_MAX_COLLISIONS, &uint_value)) {
1661         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1662         entries++;
1663     } else {
1664         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1665     }
1666     add_string_to_table(table, row, "Packets not transmitted due to collisions", string_buff);
1667
1668     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_UNDERRUN, &uint_value)) {
1669         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1670         entries++;
1671     } else {
1672         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1673     }
1674     add_string_to_table(table, row, "Packets not transmitted due to underrun", string_buff);
1675
1676     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_HEARTBEAT_FAILURE, &uint_value)) {
1677         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1678         entries++;
1679     } else {
1680         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1681     }
1682     add_string_to_table(table, row, "Packets transmitted with heartbeat failure", string_buff);
1683
1684     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_TIMES_CRS_LOST, &uint_value)) {
1685         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1686         entries++;
1687     } else {
1688         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1689     }
1690     add_string_to_table(table, row, "Times carrier sense signal lost during transmission", string_buff);
1691
1692     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_LATE_COLLISIONS, &uint_value)) {
1693         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1694         entries++;
1695     } else {
1696         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1697     }
1698     add_string_to_table(table, row, "Times late collisions detected", string_buff);
1699
1700     return entries;
1701 }
1702
1703 static int
1704 capture_if_details_task_offload(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) {
1705     NDIS_TASK_OFFLOAD_HEADER *offload;
1706     unsigned char   values[10000];
1707     int             length;
1708     gchar           string_buff[DETAILS_STR_MAX];
1709     int             entries = 0;
1710     int             TcpIpChecksumSupported = 0;
1711     int             IpSecSupported = 0;
1712     int             TcpLargeSendSupported = 0;
1713
1714
1715     /* Task Offload */
1716     offload = (NDIS_TASK_OFFLOAD_HEADER *) values;
1717     offload->Version = NDIS_TASK_OFFLOAD_VERSION;
1718     offload->Size = sizeof(NDIS_TASK_OFFLOAD_HEADER);
1719     offload->Reserved = 0;
1720     offload->OffsetFirstTask = 0;
1721     /* the EncapsulationFormat seems to be ignored on a query (using Ethernet values) */
1722     offload->EncapsulationFormat.Encapsulation = IEEE_802_3_Encapsulation;
1723     offload->EncapsulationFormat.Flags.FixedHeaderSize = 1;
1724     offload->EncapsulationFormat.Flags.Reserved = 0;
1725     offload->EncapsulationFormat.EncapsulationHeaderSize = 14; /* sizeof(struct ether_header) */;
1726
1727     length = sizeof(values);
1728     if (wpcap_packet_request(adapter, OID_TCP_TASK_OFFLOAD, FALSE /* !set */, values, &length)) {
1729         NDIS_TASK_OFFLOAD *of;
1730         /* XXX - hmmm, using a tvb for this? */
1731         unsigned char *valuep = values + offload->OffsetFirstTask;
1732         length -= offload->OffsetFirstTask;
1733
1734         do {
1735             of = (NDIS_TASK_OFFLOAD *) valuep;
1736
1737             switch(of->Task) {
1738             case TcpIpChecksumNdisTask:
1739                 {
1740                     NDIS_TASK_TCP_IP_CHECKSUM *tic = (NDIS_TASK_TCP_IP_CHECKSUM *) (of->TaskBuffer);
1741
1742                     entries++;
1743                     TcpIpChecksumSupported++;
1744
1745                     add_string_to_table(table, row, "TCP/IP Checksum", "");
1746
1747                     g_snprintf(string_buff, DETAILS_STR_MAX, "");
1748                     add_string_to_table(table, row, "V4 transmit checksum", "");
1749
1750                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s, IP: %s",
1751                         tic->V4Transmit.TcpChecksum ? "Yes" : "No",
1752                         tic->V4Transmit.UdpChecksum ? "Yes" : "No",
1753                         tic->V4Transmit.IpChecksum ? "Yes" : "No");
1754                     add_string_to_table(table, row, "Calculation supported", string_buff);
1755
1756                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s",
1757                         tic->V4Transmit.TcpOptionsSupported ? "Yes" : "No",
1758                         tic->V4Transmit.IpOptionsSupported ? "Yes" : "No");
1759                     add_string_to_table(table, row, "Options fields supported", string_buff);
1760
1761                     g_snprintf(string_buff, DETAILS_STR_MAX, "");
1762                     add_string_to_table(table, row, "V4 receive checksum", "");
1763
1764                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s, IP: %s",
1765                         tic->V4Receive.TcpChecksum ? "Yes" : "No",
1766                         tic->V4Receive.UdpChecksum ? "Yes" : "No",
1767                         tic->V4Receive.IpChecksum ? "Yes" : "No");
1768                     add_string_to_table(table, row, "Validation supported", string_buff);
1769
1770                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s",
1771                         tic->V4Receive.TcpOptionsSupported ? "Yes" : "No",
1772                         tic->V4Receive.IpOptionsSupported ? "Yes" : "No");
1773                     add_string_to_table(table, row, "Options fields supported", string_buff);
1774
1775                     g_snprintf(string_buff, DETAILS_STR_MAX, "");
1776                     add_string_to_table(table, row, "V6 transmit checksum", "");
1777
1778                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s",
1779                         tic->V6Transmit.TcpChecksum ? "Yes" : "No",
1780                         tic->V6Transmit.UdpChecksum ? "Yes" : "No");
1781                     add_string_to_table(table, row, "Calculation supported", string_buff);
1782
1783                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s",
1784                         tic->V6Transmit.TcpOptionsSupported ? "Yes" : "No",
1785                         tic->V6Transmit.IpOptionsSupported ? "Yes" : "No");
1786                     add_string_to_table(table, row, "Options fields supported", string_buff);
1787
1788                     g_snprintf(string_buff, DETAILS_STR_MAX, "");
1789                     add_string_to_table(table, row, "V6 receive checksum", "");
1790
1791                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, UDP: %s",
1792                         tic->V6Receive.TcpChecksum ? "Yes" : "No",
1793                         tic->V6Receive.UdpChecksum ? "Yes" : "No");
1794                     add_string_to_table(table, row, "Validation supported", string_buff);
1795
1796                     g_snprintf(string_buff, DETAILS_STR_MAX, "TCP: %s, IP: %s",
1797                         tic->V6Receive.TcpOptionsSupported ? "Yes" : "No",
1798                         tic->V6Receive.IpOptionsSupported ? "Yes" : "No");
1799                     add_string_to_table(table, row, "Options fields supported", string_buff);
1800                 }
1801                 break;
1802             case IpSecNdisTask:
1803                 entries++;
1804                 IpSecSupported++;
1805
1806                 add_string_to_table(table, row, "IPSEC", "");
1807                 g_snprintf(string_buff, DETAILS_STR_MAX, "IPSEC (TaskID 1) not decoded yet");
1808                 add_string_to_table(table, row, "Task", string_buff);
1809                 break;
1810             case TcpLargeSendNdisTask:
1811                 {
1812                     NDIS_TASK_TCP_LARGE_SEND *tls = (NDIS_TASK_TCP_LARGE_SEND *) (of->TaskBuffer);
1813
1814                     entries++;
1815                     TcpLargeSendSupported++;
1816
1817                     add_string_to_table(table, row, "TCP large send", "");
1818                     /* XXX - while MSDN tells about version 0, we see version 1?!? */
1819                     if(tls->Version == 1) {
1820                         g_snprintf(string_buff, DETAILS_STR_MAX, "%u", tls->MaxOffLoadSize);
1821                         add_string_to_table(table, row, "Max Offload Size", string_buff);
1822                         g_snprintf(string_buff, DETAILS_STR_MAX, "%u", tls->MinSegmentCount);
1823                         add_string_to_table(table, row, "Min Segment Count", string_buff);
1824                         g_snprintf(string_buff, DETAILS_STR_MAX, "%s", tls->TcpOptions ? "Yes" : "No");
1825                         add_string_to_table(table, row, "TCP option fields", string_buff);
1826                         g_snprintf(string_buff, DETAILS_STR_MAX, "%s", tls->IpOptions ? "Yes" : "No");
1827                         add_string_to_table(table, row, "IP option fields", string_buff);
1828                     } else {
1829                         g_snprintf(string_buff, DETAILS_STR_MAX, "%u (unknown)", tls->Version);
1830                         add_string_to_table(table, row, "Version", string_buff);
1831                     }
1832                 }
1833                 break;
1834             default:
1835                 g_snprintf(string_buff, DETAILS_STR_MAX, "Unknown task %u", of->Task);
1836                 add_string_to_table(table, row, "Task", string_buff);
1837
1838             }
1839
1840             add_string_to_table(table, row, "", "");
1841
1842             valuep += of->OffsetNextTask;
1843             length -= of->OffsetNextTask;
1844         } while(of->OffsetNextTask != 0);
1845     }
1846
1847     if(TcpIpChecksumSupported == 0) {
1848         add_string_to_table(table, row, "TCP/IP Checksum", "");
1849         add_string_to_table(table, row, "Offload not supported", "-");
1850     }
1851
1852     if(IpSecSupported == 0) {
1853         add_string_to_table(table, row, "IpSec", "");
1854         add_string_to_table(table, row, "Offload not supported", "-");
1855     }
1856
1857     if(TcpLargeSendSupported == 0) {
1858         add_string_to_table(table, row, "TCP Large Send", "");
1859         add_string_to_table(table, row, "Offload not supported", "-");
1860     }
1861
1862     return entries;
1863 }
1864
1865 static int
1866 capture_if_details_general(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter, gchar *iface) {
1867     gchar           string_buff[DETAILS_STR_MAX];
1868     const gchar     *manuf_name;
1869     unsigned int    uint_value;
1870     unsigned int    uint_array[50];
1871     int             uint_array_size;
1872     unsigned int    physical_medium;
1873     int             i;
1874     unsigned char   values[100];
1875     int             length;
1876     unsigned short  ushort_value;
1877     int             entries = 0;
1878
1879
1880     /* general */
1881     add_string_to_table(table, row, "Characteristics", "");
1882
1883     /* Vendor description */
1884     length = sizeof(values);
1885     if (wpcap_packet_request(adapter, OID_GEN_VENDOR_DESCRIPTION, FALSE /* !set */, values, &length)) {
1886         g_snprintf(string_buff, DETAILS_STR_MAX, "%s", values);
1887         entries++;
1888     } else {
1889         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1890     }
1891     add_string_to_table(table, row, "Vendor description", string_buff);
1892
1893     /* Interface */
1894     add_string_to_table(table, row, "Interface", iface);
1895
1896     /* link status (connected/disconnected) */
1897     if (wpcap_packet_request_uint(adapter, OID_GEN_MEDIA_CONNECT_STATUS, &uint_value)) {
1898         entries++;
1899         if(uint_value == 0) {
1900             add_string_to_table(table, row, "Link status", "Connected");
1901         } else {
1902             add_string_to_table(table, row, "Link status", "Disconnected");
1903         }
1904     } else {
1905         add_string_to_table(table, row, "Link status", "-");
1906     }
1907
1908     /* link speed */
1909     if (wpcap_packet_request_uint(adapter, OID_GEN_LINK_SPEED, &uint_value)) {
1910         entries++;
1911         uint_value *= 100;
1912         if(uint_value >= 1000 * 1000) {
1913             g_snprintf(string_buff, DETAILS_STR_MAX, "%d MBits/s", uint_value / 1000 / 1000);
1914         } else {
1915             if(uint_value >= 1000) {
1916                 g_snprintf(string_buff, DETAILS_STR_MAX, "%d KBits/s", uint_value / 1000);
1917             } else {
1918                 g_snprintf(string_buff, DETAILS_STR_MAX, "%d Bits/s", uint_value);
1919             }
1920         }
1921     } else {
1922         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1923     }
1924     add_string_to_table(table, row, "Link speed", string_buff);
1925
1926
1927
1928     uint_array_size = sizeof(uint_array);
1929     if (wpcap_packet_request(adapter, OID_GEN_MEDIA_SUPPORTED, FALSE /* !set */, (char *) uint_array, &uint_array_size)) {
1930         entries++;
1931         uint_array_size /= sizeof(unsigned int);
1932         i=0;
1933         while(uint_array_size--) {
1934             add_string_to_table(table, row, "Media supported",
1935                 val_to_str(uint_array[i], win32_802_3_medium_vals, "(0x%x)"));
1936             i++;
1937         }
1938     } else {
1939         add_string_to_table(table, row, "Media supported", "-");
1940     }
1941
1942     uint_array_size = sizeof(uint_array);
1943     if (wpcap_packet_request(adapter, OID_GEN_MEDIA_IN_USE, FALSE /* !set */, (char *) uint_array, &uint_array_size)) {
1944         entries++;
1945         uint_array_size /= sizeof(unsigned int);
1946         i=0;
1947         while(uint_array_size--) {
1948             add_string_to_table(table, row, "Medium in use",
1949                   val_to_str(uint_array[i], win32_802_3_medium_vals, "(0x%x)"));
1950             i++;
1951         }
1952     } else {
1953         add_string_to_table(table, row, "Medium in use", "-");
1954     }
1955
1956     if (wpcap_packet_request_uint(adapter, OID_GEN_PHYSICAL_MEDIUM, &physical_medium)) {
1957         entries++;
1958         add_string_to_table(table, row, "Physical medium",
1959             val_to_str(physical_medium, win32_802_3_physical_medium_vals, "(0x%x)"));
1960     } else {
1961         add_string_to_table(table, row, "Physical medium", "-");
1962     }
1963
1964     length = sizeof(ushort_value);
1965     if (wpcap_packet_request(adapter, OID_GEN_DRIVER_VERSION, FALSE /* !set */, (char *) &ushort_value, &length)) {
1966         entries++;
1967         g_snprintf(string_buff, DETAILS_STR_MAX, "%u.%u", ushort_value / 0x100, ushort_value % 0x100);
1968     } else {
1969         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1970     }
1971     add_string_to_table(table, row, "NDIS Driver Version", string_buff);
1972
1973     length = sizeof(uint_value);
1974     if (wpcap_packet_request(adapter, OID_GEN_VENDOR_DRIVER_VERSION, FALSE /* !set */, (char *) &uint_value, &length)) {
1975         entries++;
1976         /* XXX - what's the correct output format? */
1977         g_snprintf(string_buff, DETAILS_STR_MAX, "%u.%u (Hex: %X.%X)",
1978             (uint_value / 0x10000  ) % 0x10000,
1979              uint_value              % 0x10000,
1980             (uint_value / 0x10000  ) % 0x10000,
1981              uint_value              % 0x10000);
1982     } else {
1983         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1984     }
1985     add_string_to_table(table, row, "Vendor Driver Version", string_buff);
1986
1987     length = sizeof(values);
1988     if (wpcap_packet_request(adapter, OID_GEN_VENDOR_ID, FALSE /* !set */, values, &length)) {
1989         entries++;
1990         manuf_name = get_manuf_name_if_known(values);
1991         if(manuf_name != NULL) {
1992             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X (%s) NIC: %02X",
1993                 values[0], values[1], values[2], manuf_name, values[3]);
1994         } else {
1995             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X NIC: %02X",
1996                 values[0], values[1], values[2], values[3]);
1997         }
1998     } else {
1999         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2000     }
2001     add_string_to_table(table, row, "Vendor ID", string_buff);
2002
2003     if (wpcap_packet_request_uint(adapter, OID_GEN_MAC_OPTIONS, &uint_value)) {
2004         entries++;
2005         g_snprintf(string_buff, DETAILS_STR_MAX,
2006             "802.1P Priority: %s, 802.1Q VLAN: %s",
2007             (uint_value & NDIS_MAC_OPTION_8021P_PRIORITY) ? "Supported" : "Unsupported",
2008             (uint_value & NDIS_MAC_OPTION_8021Q_VLAN) ? "Supported" : "Unsupported" );
2009     } else {
2010         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2011     }
2012     add_string_to_table(table, row, "MAC Options", string_buff);
2013
2014     if (wpcap_packet_request_uint(adapter, OID_GEN_VLAN_ID, &uint_value)) {
2015         entries++;
2016         g_snprintf(string_buff, DETAILS_STR_MAX, "%u", uint_value);
2017     } else {
2018         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2019     }
2020     add_string_to_table(table, row, "VLAN ID", string_buff);
2021
2022 #if 0
2023     /* value seems to be constant */
2024     if (wpcap_packet_request_uint(adapter, OID_GEN_CURRENT_PACKET_FILTER, &uint_value)) {
2025         entries++;
2026         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2027     } else {
2028         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2029     }
2030     add_string_to_table(table, row, "Packet filter", string_buff);
2031 #endif
2032
2033     if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_BUFFER_SPACE, &uint_value)) {
2034         entries++;
2035         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2036     } else {
2037         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2038     }
2039     add_string_to_table(table, row, "Transmit Buffer Space", string_buff);
2040
2041     if (wpcap_packet_request_uint(adapter, OID_GEN_RECEIVE_BUFFER_SPACE, &uint_value)) {
2042         entries++;
2043         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2044     } else {
2045         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2046     }
2047     add_string_to_table(table, row, "Receive Buffer Space", string_buff);
2048
2049     if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_BLOCK_SIZE , &uint_value)) {
2050         entries++;
2051         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2052     } else {
2053         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2054     }
2055     add_string_to_table(table, row, "Transmit Block Size", string_buff);
2056
2057     if (wpcap_packet_request_uint(adapter, OID_GEN_RECEIVE_BLOCK_SIZE, &uint_value)) {
2058         entries++;
2059         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2060     } else {
2061         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2062     }
2063     add_string_to_table(table, row, "Receive Block Size", string_buff);
2064
2065     if (wpcap_packet_request_uint(adapter, OID_GEN_MAXIMUM_TOTAL_SIZE, &uint_value)) {
2066         entries++;
2067         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2068     } else {
2069         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2070     }
2071     add_string_to_table(table, row, "Maximum Packet Size", string_buff);
2072
2073     return entries;
2074 }
2075
2076
2077 static int
2078 capture_if_details_stats(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) {
2079     gchar           string_buff[DETAILS_STR_MAX];
2080     unsigned int    uint_value;
2081     int             entries = 0;
2082
2083
2084     add_string_to_table(table, row, "Statistics", "");
2085
2086     if (wpcap_packet_request_uint(adapter, OID_GEN_XMIT_OK, &uint_value)) {
2087         entries++;
2088         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2089     } else {
2090         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2091     }
2092     add_string_to_table(table, row, "Transmit OK", string_buff);
2093
2094     if (wpcap_packet_request_uint(adapter, OID_GEN_XMIT_ERROR, &uint_value)) {
2095         entries++;
2096         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2097     } else {
2098         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2099     }
2100     add_string_to_table(table, row, "Transmit Error", string_buff);
2101
2102
2103     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_OK, &uint_value)) {
2104         entries++;
2105         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2106     } else {
2107         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2108     }
2109     add_string_to_table(table, row, "Receive OK", string_buff);
2110
2111     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_ERROR, &uint_value)) {
2112         entries++;
2113         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2114     } else {
2115         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2116     }
2117     add_string_to_table(table, row, "Receive Error", string_buff);
2118
2119     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_NO_BUFFER, &uint_value)) {
2120         entries++;
2121         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2122     } else {
2123         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2124     }
2125     add_string_to_table(table, row, "Receive but no Buffer", string_buff);
2126
2127     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_BYTES_XMIT, &uint_value)) {
2128         entries++;
2129         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2130     } else {
2131         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2132     }
2133     add_string_to_table(table, row, "Directed bytes transmitted w/o errors", string_buff);
2134
2135     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_FRAMES_XMIT, &uint_value)) {
2136         entries++;
2137         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2138     } else {
2139         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2140     }
2141     add_string_to_table(table, row, "Directed packets transmitted w/o errors", string_buff);
2142
2143     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_BYTES_XMIT, &uint_value)) {
2144         entries++;
2145         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2146     } else {
2147         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2148     }
2149     add_string_to_table(table, row, "Multicast bytes transmitted w/o errors", string_buff);
2150
2151     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_FRAMES_XMIT, &uint_value)) {
2152         entries++;
2153         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2154     } else {
2155         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2156     }
2157     add_string_to_table(table, row, "Multicast packets transmitted w/o errors", string_buff);
2158
2159     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_BYTES_XMIT, &uint_value)) {
2160         entries++;
2161         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2162     } else {
2163         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2164     }
2165     add_string_to_table(table, row, "Broadcast bytes transmitted w/o errors", string_buff);
2166
2167     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_FRAMES_XMIT, &uint_value)) {
2168         entries++;
2169         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2170     } else {
2171         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2172     }
2173     add_string_to_table(table, row, "Broadcast packets transmitted w/o errors", string_buff);
2174
2175     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_BYTES_RCV, &uint_value)) {
2176         entries++;
2177         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2178     } else {
2179         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2180     }
2181     add_string_to_table(table, row, "Directed bytes received w/o errors", string_buff);
2182
2183     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_FRAMES_RCV, &uint_value)) {
2184         entries++;
2185         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2186     } else {
2187         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2188     }
2189     add_string_to_table(table, row, "Directed packets received w/o errors", string_buff);
2190
2191     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_BYTES_RCV, &uint_value)) {
2192         entries++;
2193         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2194     } else {
2195         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2196     }
2197     add_string_to_table(table, row, "Multicast bytes received w/o errors", string_buff);
2198
2199     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_FRAMES_RCV, &uint_value)) {
2200         entries++;
2201         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2202     } else {
2203         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2204     }
2205     add_string_to_table(table, row, "Multicast packets received w/o errors", string_buff);
2206
2207     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_BYTES_RCV, &uint_value)) {
2208         entries++;
2209         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2210     } else {
2211         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2212     }
2213     add_string_to_table(table, row, "Broadcast bytes received w/o errors", string_buff);
2214
2215     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_FRAMES_RCV, &uint_value)) {
2216         entries++;
2217         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2218     } else {
2219         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2220     }
2221     add_string_to_table(table, row, "Broadcast packets received w/o errors", string_buff);
2222
2223     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_CRC_ERROR, &uint_value)) {
2224         entries++;
2225         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2226     } else {
2227         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2228     }
2229     add_string_to_table(table, row, "Packets received with CRC or FCS errors", string_buff);
2230
2231     if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_QUEUE_LENGTH, &uint_value)) {
2232         entries++;
2233         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
2234     } else {
2235         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
2236     }
2237     add_string_to_table(table, row, "Packets queued for transmission", string_buff);
2238
2239     return entries;
2240 }
2241
2242
2243 static GtkWidget *
2244 capture_if_details_page_new(GtkWidget **table)
2245 {
2246     GtkWidget *main_vb;
2247
2248     main_vb = gtk_vbox_new(FALSE, 6);
2249     gtk_container_border_width(GTK_CONTAINER(main_vb), 12);
2250
2251     /* table */
2252     *table = gtk_table_new(1, 2, FALSE);
2253     gtk_table_set_col_spacings(GTK_TABLE(*table), 6);
2254     gtk_table_set_row_spacings(GTK_TABLE(*table), 3);
2255     gtk_container_add(GTK_CONTAINER(main_vb), *table);
2256
2257     return main_vb;
2258 }
2259
2260
2261 static void
2262 capture_if_details_open_win(char *iface)
2263 {
2264     GtkWidget   *details_open_w,
2265                 *main_vb, *bbox, *close_bt, *help_bt;
2266     GtkWidget   *page_general, *page_stats, *page_802_3, *page_802_11, *page_task_offload;
2267     GtkWidget   *page_lb;
2268     GtkWidget   *table, *notebook, *label;
2269     guint       row;
2270     LPADAPTER   adapter;
2271     int         entries;
2272
2273
2274     /* open the network adapter */
2275     adapter = wpcap_packet_open(iface);
2276     if(adapter == NULL) {
2277         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2278             "%sCould not open adapter: %s!%s"
2279             "\n\nThe adapter might be removed from the system in the meantime!", 
2280             simple_dialog_primary_start(), iface, simple_dialog_primary_end());
2281         return;
2282     }
2283
2284     /* open a new window */
2285     details_open_w = window_new(GTK_WINDOW_TOPLEVEL, "Wireshark: Interface Details");
2286
2287     /* Container for the window contents */
2288     main_vb = gtk_vbox_new(FALSE, 12);
2289     gtk_container_border_width(GTK_CONTAINER(main_vb), 12);
2290     gtk_container_add(GTK_CONTAINER(details_open_w), main_vb);
2291
2292     /* notebook */
2293     notebook = gtk_notebook_new();
2294     gtk_box_pack_start(GTK_BOX(main_vb), notebook, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/);
2295
2296     /* General page */
2297     page_general = capture_if_details_page_new(&table);
2298     page_lb = gtk_label_new("Characteristics");
2299     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_general, page_lb);
2300     row = 0;
2301     entries = capture_if_details_general(table, page_general, &row, adapter, iface);
2302     if(entries == 0) {
2303         gtk_widget_set_sensitive(page_lb, FALSE);
2304     }
2305
2306     /* Statistics page */
2307     page_stats = capture_if_details_page_new(&table);
2308     page_lb = gtk_label_new("Statistics");
2309     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_stats, page_lb);
2310     row = 0;
2311     entries = capture_if_details_stats(table, page_stats, &row, adapter);
2312     if(entries == 0) {
2313         gtk_widget_set_sensitive(page_lb, FALSE);
2314     }
2315
2316     /* 802.3 (Ethernet) page */
2317     page_802_3 = capture_if_details_page_new(&table);
2318     page_lb = gtk_label_new("802.3 (Ethernet)");
2319     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_802_3, page_lb);
2320     row = 0;
2321     entries = capture_if_details_802_3(table, page_802_3, &row, adapter);
2322     if(entries == 0) {
2323         gtk_widget_set_sensitive(page_lb, FALSE);
2324     }
2325
2326     /* 802_11 (WI-FI) page */
2327     page_802_11 = capture_if_details_page_new(&table);
2328     page_lb = gtk_label_new("802.11 (WLAN)");
2329     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_802_11, page_lb);
2330     row = 0;
2331     entries = capture_if_details_802_11(table, page_802_11, &row, adapter);
2332     if(entries == 0) {
2333         gtk_widget_set_sensitive(page_lb, FALSE);
2334     }
2335
2336     /* Task offload page */
2337     page_task_offload = capture_if_details_page_new(&table);
2338     page_lb = gtk_label_new("Task Offload");
2339     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_task_offload, page_lb);
2340     row = 0;
2341     entries = capture_if_details_task_offload(table, page_task_offload, &row, adapter);
2342     if(entries == 0) {
2343         gtk_widget_set_sensitive(page_lb, FALSE);
2344     }
2345
2346     wpcap_packet_close(adapter);
2347
2348     label = gtk_label_new("Note: accuracy of all of these values are only relying on the network card driver!");
2349     gtk_box_pack_start(GTK_BOX(main_vb), label, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
2350
2351     /* Button row. */
2352     if(topic_available(HELP_CAPTURE_INTERFACES_DETAILS_DIALOG)) {
2353         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
2354     } else {
2355         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
2356     }
2357     gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
2358
2359     close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
2360     window_set_cancel_button(details_open_w, close_bt, window_cancel_button_cb);
2361
2362     if(topic_available(HELP_CAPTURE_INTERFACES_DETAILS_DIALOG)) {
2363         help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
2364         g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer) (HELP_CAPTURE_INTERFACES_DETAILS_DIALOG));
2365     }
2366
2367     gtk_widget_grab_focus(close_bt);
2368
2369     g_signal_connect(details_open_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
2370
2371     gtk_widget_show_all(details_open_w);
2372     window_present(details_open_w);
2373 }
2374
2375
2376 static void capture_if_details_open_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
2377 {
2378     switch(btn) {
2379     case(ESD_BTN_OK):
2380         capture_if_details_open_win(data);
2381         break;
2382     case(ESD_BTN_CANCEL):
2383         break;
2384     default:
2385         g_assert_not_reached();
2386     }
2387 }
2388
2389
2390 void
2391 capture_if_details_open(char *iface)
2392 {
2393     char        *version;
2394     gboolean    version_ok = FALSE;
2395     gpointer    dialog;
2396
2397
2398     /* check packet.dll version */
2399     version = wpcap_packet_get_version();
2400
2401     if(version == NULL) {
2402         /* couldn't even get the packet.dll version, must be a very old one or just not existing -> give up */
2403         /* (this seems to be the case for 2.3 beta and all previous releases) */
2404         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2405             "%sCouldn't obtain WinPcap packet.dll version!%s"
2406             "\n\nThe WinPcap packet.dll is not installed or the version you use seems to be very old!"
2407             "\n\nPlease update/install WinPcap.",
2408             simple_dialog_primary_start(), simple_dialog_primary_end());
2409         return;
2410     }
2411
2412     /* XXX - add more known DLL versions here */
2413     /* (all versions since the 2.3 release seems to be working (although the 2.3 beta did not) */
2414     if(
2415         /*
2416          * 4.0 version strings:
2417          * 4.0.0.703:  4.0 beta 3
2418          * 4.0.0.655:  4.0 beta 2
2419          * 4.0.0.592:  4.0 beta 1
2420          */
2421         strcmp(version, "3"          ) >  0 ||       /* 4.0 and above (including betas) */
2422         strcmp(version, "3, 2, 0, 29") == 0 ||       /* 3.2 beta 1 */
2423         strcmp(version, "3, 1, 0, 27") == 0 ||       /* 3.1 release */
2424         strcmp(version, "3, 1, 0, 24") == 0 ||       /* 3.1 beta 4 */
2425         strcmp(version, "3, 1, 0, 23") == 0 ||       /* 3.1 beta 3 */
2426         strcmp(version, "3, 1, 0, 22") == 0 ||       /* 3.1 beta 2 */
2427         strcmp(version, "3, 1, 0, 20") == 0 ||       /* 3.1 beta */
2428         strcmp(version, "3.0 alpha3" ) == 0 ||       /* 3.0 release or 3.0 beta (yes, both versions report alpha3!) */
2429         strcmp(version, "2.3"        ) == 0          /* 2.3 release */
2430         ) {
2431             version_ok = TRUE;
2432     }
2433
2434     if(!version_ok) {
2435         /* packet.dll version not known to us, warn user but try to continue */
2436         dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK | ESD_BTN_CANCEL,
2437             "%sUnknown WinPcap version might crash or fail!%s"
2438             "\n\nThe WinPcap packet.dll version \"%s\" is unknown if it supports required functions!"
2439             "\n\nOnly WinPcap versions 3.0 and 3.1 are known to work with this feature."
2440             "\n\nCrashes or unexpected behaviour might occur, you have been warned!"
2441             "\n\nContinue anyway?",
2442             simple_dialog_primary_start(), simple_dialog_primary_end(), version);
2443         simple_dialog_set_cb(dialog, capture_if_details_open_answered_cb, iface);
2444     } else {
2445         capture_if_details_open_win(iface);
2446     }
2447 }
2448
2449
2450 #endif /* HAVE_LIBPCAP && _WIN32 */