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