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