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