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