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