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