enhance simple dialog: add the possibility to use no buttons at all and add a stop...
[obnox/wireshark/wip.git] / gtk / capture_if_details_dlg.c
1 /* capture_if_details_dlg.c
2  * Routines for capture interface details window (only Win32!)
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29
30 #if defined HAVE_LIBPCAP && defined _WIN32
31
32 #include <string.h>
33
34 #include <gtk/gtk.h>
35
36 #include <wtap.h>
37 #include <time.h>
38
39 #include "globals.h"
40 #include "file.h"
41 #include <pcap.h>
42 #include "capture.h"
43 #include "main.h"
44 #include "dlg_utils.h"
45 #include "gui_utils.h"
46 #include "compat_macros.h"
47 #include "help_dlg.h"
48
49 #include <epan/value_string.h>
50 #include <epan/addr_resolv.h>
51
52 #ifndef HAVE_SOCKADDR_STORAGE
53 /* packet32.h requires sockaddr_storage (usually defined in Platform SDK)
54  * copied from RFC2553 (and slightly modified because of datatypes) ... */
55 /*
56  * Desired design of maximum size and alignment
57  */
58 #define ETH_SS_MAXSIZE    128  /* Implementation specific max size */
59 #define ETH_SS_ALIGNSIZE  (sizeof (gint64 /*int64_t*/))
60                          /* Implementation specific desired alignment */
61 /*
62  * Definitions used for sockaddr_storage structure paddings design.
63  */
64 #define ETH_SS_PAD1SIZE   (ETH_SS_ALIGNSIZE - sizeof (sa_family_t))
65 #define ETH_SS_PAD2SIZE   (ETH_SS_MAXSIZE - (sizeof (sa_family_t) + \
66                               ETH_SS_PAD1SIZE + ETH_SS_ALIGNSIZE))
67
68 struct sockaddr_storage {
69     sa_family_t  __ss_family;     /* address family */
70     /* Following fields are implementation specific */
71     char      __ss_pad1[ETH_SS_PAD1SIZE];
72               /* 6 byte pad, this is to make implementation
73               /* specific pad up to alignment field that */
74               /* follows explicit in the data structure */
75     gint64 /*int64_t*/   __ss_align;     /* field to force desired structure */
76                /* storage alignment */
77     char      __ss_pad2[ETH_SS_PAD2SIZE];
78               /* 112 byte pad to achieve desired size, */
79               /* _SS_MAXSIZE value minus size of ss_family */
80               /* __ss_pad1, __ss_align fields is 112 */
81 };
82 /* ... copied from RFC2553 */
83 #endif
84
85
86 #include <Packet32.h>
87 #include <windows.h>
88 #include <windowsx.h>
89 #include <Ntddndis.h>
90
91 #include "capture_wpcap_packet.h"
92 #include "capture_if_details_dlg.h"
93
94 #include "simple_dialog.h"
95
96 #define DETAILS_STR_MAX     1024
97
98
99
100 /******************************************************************************************************************************/
101 /* definitions that would usually come from the windows DDK (device driver kit) */
102 /* and are not part of the ntddndis.h file delivered with WinPcap */
103
104 /* Required OIDs (from ndiswrapper) */
105 #define OID_GEN_VLAN_ID                         0x0001021C
106
107 /* Optional OIDs (from ndiswrapper) */
108 #define OID_GEN_MEDIA_CAPABILITIES              0x00010201
109 #define OID_GEN_PHYSICAL_MEDIUM                 0x00010202
110
111
112 /* Physical medium (OID_GEN_PHYSICAL_MEDIUM) (from ndiswrapper) */
113 typedef enum ndis_phys_medium {
114         NdisPhysicalMediumUnspecified,
115         NdisPhysicalMediumWirelessLan,
116         NdisPhysicalMediumCableModem,
117         NdisPhysicalMediumPhoneLine,
118         NdisPhysicalMediumPowerLine,
119         NdisPhysicalMediumDSL,
120         NdisPhysicalMediumFibreChannel,
121         NdisPhysicalMedium1394,
122         NdisPhysicalMediumWirelessWan,
123         NdisPhysicalMediumMax
124 };
125
126
127 /* 802.11 OIDs (from ndiswrapper), see also: */
128 /* http://www.ndis.com/papers/ieee802_11_log.htm */
129 /* http://lists.freebsd.org/pipermail/p4-projects/2004-January/003433.html */
130 #define OID_802_11_BSSID                        0x0D010101
131 #define OID_802_11_SSID                         0x0D010102
132 #define OID_802_11_NETWORK_TYPES_SUPPORTED      0x0D010203
133 #define OID_802_11_NETWORK_TYPE_IN_USE          0x0D010204
134 #define OID_802_11_TX_POWER_LEVEL               0x0D010205
135 #define OID_802_11_RSSI                         0x0D010206
136 #define OID_802_11_RSSI_TRIGGER                 0x0D010207
137 #define OID_802_11_INFRASTRUCTURE_MODE          0x0D010108
138 #define OID_802_11_FRAGMENTATION_THRESHOLD      0x0D010209
139 #define OID_802_11_RTS_THRESHOLD                0x0D01020A
140 #define OID_802_11_NUMBER_OF_ANTENNAS           0x0D01020B
141 #define OID_802_11_RX_ANTENNA_SELECTED          0x0D01020C
142 #define OID_802_11_TX_ANTENNA_SELECTED          0x0D01020D
143 #define OID_802_11_SUPPORTED_RATES              0x0D01020E
144 #define OID_802_11_DESIRED_RATES                0x0D010210
145 #define OID_802_11_CONFIGURATION                0x0D010211
146 #define OID_802_11_STATISTICS                   0x0D020212
147 #define OID_802_11_ADD_WEP                      0x0D010113
148 #define OID_802_11_REMOVE_WEP                   0x0D010114
149 #define OID_802_11_DISASSOCIATE                 0x0D010115
150 #define OID_802_11_POWER_MODE                   0x0D010216
151 #define OID_802_11_BSSID_LIST                   0x0D010217
152 #define OID_802_11_AUTHENTICATION_MODE          0x0D010118
153 #define OID_802_11_PRIVACY_FILTER               0x0D010119
154 #define OID_802_11_BSSID_LIST_SCAN              0x0D01011A
155 #define OID_802_11_WEP_STATUS                   0x0D01011B
156 #define OID_802_11_ENCRYPTION_STATUS            OID_802_11_WEP_STATUS
157 #define OID_802_11_RELOAD_DEFAULTS              0x0D01011C
158 #define OID_802_11_ADD_KEY                      0x0D01011D
159 #define OID_802_11_REMOVE_KEY                   0x0D01011E
160 #define OID_802_11_ASSOCIATION_INFORMATION      0x0D01011F
161 #define OID_802_11_TEST                         0x0D010120
162 #define OID_802_11_CAPABILITY                   0x0D010122
163 #define OID_802_11_PMKID                        0x0D010123
164
165 /* Currently associated SSID (OID_802_11_SSID) (from ndiswrapper) */
166 #define NDIS_ESSID_MAX_SIZE 32
167 struct ndis_essid {
168         ULONG length;
169         UCHAR essid[NDIS_ESSID_MAX_SIZE];
170 };
171
172 /* Current infrastructure mode (OID_802_11_INFRASTRUCTURE_MODE) (from ndiswrapper) */
173 enum network_infrastructure {
174         Ndis802_11IBSS,
175         Ndis802_11Infrastructure,
176         Ndis802_11AutoUnknown,
177         Ndis802_11InfrastructureMax
178 };
179
180 /* Current authentication mode (OID_802_11_AUTHENTICATION_MODE) (from ndiswrapper) */
181 enum authentication_mode {
182         Ndis802_11AuthModeOpen,
183         Ndis802_11AuthModeShared,
184         Ndis802_11AuthModeAutoSwitch,
185         Ndis802_11AuthModeWPA,
186         Ndis802_11AuthModeWPAPSK,
187         Ndis802_11AuthModeWPANone,
188         Ndis802_11AuthModeWPA2,
189         Ndis802_11AuthModeWPA2PSK,
190         Ndis802_11AuthModeMax
191 };
192
193 /* Current network type (OID_802_11_NETWORK_TYPES_SUPPORTED / OID_802_11_NETWORK_TYPE_IN_USE) (from ndiswrapper) */
194 enum network_type {
195         Ndis802_11FH,
196         Ndis802_11DS,
197         Ndis802_11OFDM5,
198         Ndis802_11OFDM24,
199         /* MSDN site uses Ndis802_11Automode, which is not mentioned
200          * in DDK, so add one and assign it to
201          * Ndis802_11NetworkTypeMax */
202         Ndis802_11Automode,
203         Ndis802_11NetworkTypeMax = Ndis802_11Automode
204 };
205
206 /* Current encryption status (OID_802_11_ENCRYPTION_STATUS) (from ndiswrapper) */
207 enum encryption_status {
208         Ndis802_11WEPEnabled,
209         Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
210         Ndis802_11WEPDisabled,
211         Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
212         Ndis802_11WEPKeyAbsent,
213         Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
214         Ndis802_11WEPNotSupported,
215         Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
216         Ndis802_11Encryption2Enabled,
217         Ndis802_11Encryption2KeyAbsent,
218         Ndis802_11Encryption3Enabled,
219         Ndis802_11Encryption3KeyAbsent
220 };
221
222
223 /* some definitions needed for the following structs (from ndiswrapper) */
224 #define NDIS_MAX_RATES_EX 16
225 typedef UCHAR mac_address[/* ETH_ALEN */ 6];
226 typedef UCHAR ndis_rates[NDIS_MAX_RATES_EX];
227
228 /* configuration, e.g. frequency (OID_802_11_CONFIGURATION / OID_802_11_BSSID_LIST) (from ndiswrapper) */
229 struct /*packed*/ ndis_configuration {
230         ULONG length;
231         ULONG beacon_period;
232         ULONG atim_window;
233         ULONG ds_config;
234         struct ndis_configuration_fh {
235                 ULONG length;
236                 ULONG hop_pattern;
237                 ULONG hop_set;
238                 ULONG dwell_time;
239         } fh_config;
240 };
241
242 /* bssid list item (OID_802_11_BSSID_LIST) (from ndiswrapper) */
243 struct ndis_ssid_item {
244         ULONG length;
245         mac_address mac;
246         UCHAR reserved[2];
247         struct ndis_essid ssid;
248         ULONG privacy;
249         LONG rssi;
250         UINT net_type;
251         struct ndis_configuration config;
252         UINT mode;
253         ndis_rates rates;
254         ULONG ie_length;
255         UCHAR ies[1];
256 };
257
258
259 /* bssid list (OID_802_11_BSSID_LIST) (from ndiswrapper) */
260 struct ndis_bssid_list {
261         ULONG num_items;
262         struct ndis_ssid_item items[1];
263 };
264
265
266 /******************************************************************************************************************************/
267 /* value_string's for info functions */
268
269
270 /* NDIS driver medium (OID_GEN_MEDIA_SUPPORTED / OID_GEN_MEDIA_IN_USE) */
271 static const value_string win32_802_3_medium_vals[] = {
272         { NdisMedium802_3,      "802.3 (Ethernet)" },    /* might as well be WLAN, ... (see NDIS_PHYSICAL_MEDIUM) */
273         { NdisMedium802_5,      "802.5 (Token Ring)" },
274         { NdisMediumFddi,       "FDDI" },
275         { NdisMediumWan,        "WAN" },
276         { NdisMediumLocalTalk,  "Local Talk" },
277         { NdisMediumDix,        "Dix" },
278         { NdisMediumArcnetRaw,  "Arcnet Raw" },
279         { NdisMediumArcnet878_2,"Arcnet 878_2" },
280         { NdisMediumAtm,        "ATM" },
281         { NdisMediumWirelessWan,"Wireless WAN" },
282         { NdisMediumIrda,       "Irda" },
283     { 0, NULL }
284 };
285
286 /* NDIS physical driver medium (OID_GEN_PHYSICAL_MEDIUM) */
287 static const value_string win32_802_3_physical_medium_vals[] = {
288         { NdisPhysicalMediumUnspecified,    "Unspecified" },
289         { NdisPhysicalMediumWirelessLan,    "Wireless LAN" },
290         { NdisPhysicalMediumCableModem,     "Cable Modem" },
291         { NdisPhysicalMediumPhoneLine,      "Phone Line" },
292         { NdisPhysicalMediumPowerLine,      "Power Line" },
293         { NdisPhysicalMediumDSL,            "DSL" },
294         { NdisPhysicalMediumFibreChannel,   "Fibre Channel" },
295         { NdisPhysicalMedium1394,           "IEEE 1394" },
296         { NdisPhysicalMediumWirelessWan,    "Wireless WAN" },
297     { 0, NULL }
298 };
299
300 static const value_string win32_802_11_infra_mode_vals[] = {
301         { Ndis802_11IBSS,           "Ad Hoc" },
302         { Ndis802_11Infrastructure, "Access Point" },
303         { Ndis802_11AutoUnknown,    "Auto or unknown" },
304     { 0, NULL }
305 };
306
307 static const value_string win32_802_11_auth_mode_vals[] = {
308         { Ndis802_11AuthModeOpen,       "Open System" },
309         { Ndis802_11AuthModeShared,     "Shared Key" },
310         { Ndis802_11AuthModeAutoSwitch, "Auto Switch" },
311         { Ndis802_11AuthModeWPA,        "WPA" },
312         { Ndis802_11AuthModeWPAPSK,     "WPA (pre shared key)" },
313         { Ndis802_11AuthModeWPANone,    "WPA (ad hoc)" },
314         { Ndis802_11AuthModeWPA2,       "WPA2" },
315         { Ndis802_11AuthModeWPA2PSK,    "WPA2 (pre shared key)" },
316     { 0, NULL }
317 };
318
319 static const value_string win32_802_11_network_type_vals[] = {
320         { Ndis802_11FH,         "FH (frequency-hopping spread-spectrum)" },
321         { Ndis802_11DS,         "DS (direct-sequence spread-spectrum)" },
322         { Ndis802_11OFDM5,      "5-GHz OFDM" },
323         { Ndis802_11OFDM24,     "2.4-GHz OFDM" },
324         { Ndis802_11Automode,   "Auto" },
325     { 0, NULL }
326 };
327
328 /* XXX - add some explanations */
329 static const value_string win32_802_11_encryption_status_vals[] = {
330         { Ndis802_11Encryption1Enabled,     "Encryption 1 Enabled" },
331         { Ndis802_11EncryptionDisabled,     "Encryption Disabled" },
332         { Ndis802_11Encryption1KeyAbsent,   "Encryption 1 Key Absent" },
333         { Ndis802_11EncryptionNotSupported, "Encryption Not Supported" },
334         { Ndis802_11Encryption2Enabled,     "Encryption 2 Enabled" },
335         { Ndis802_11Encryption2KeyAbsent,   "Encryption 2 Key Absent" },
336         { Ndis802_11Encryption3Enabled,     "Encryption 3 Enabled" },
337         { Ndis802_11Encryption3KeyAbsent,   "Encryption 3 Key Absent" },
338     { 0, NULL }
339 };
340
341 /* frequency to channel mapping (OID_802_11_CONFIGURATION) */
342 static const value_string win32_802_11_channel_vals[] = {
343         { 2412000, "1 (2412000 kHz)" },
344         { 2417000, "2 (2417000 kHz)" },
345         { 2422000, "3 (2422000 kHz)" },
346         { 2427000, "4 (2427000 kHz)" },
347         { 2432000, "5 (2432000 kHz)" },
348         { 2437000, "6 (2437000 kHz)" },
349         { 2442000, "7 (2442000 kHz)" },
350         { 2447000, "8 (2447000 kHz)" },
351         { 2452000, "9 (2452000 kHz)" },
352         { 2457000, "10 (2457000 kHz)" },
353         { 2462000, "11 (2462000 kHz)" },
354         { 2467000, "12 (2467000 kHz)" },
355         { 2472000, "13 (2472000 kHz)" },
356         { 2484000, "14 (2484000 kHz)" },
357     { 0, NULL }
358 };
359
360
361 /******************************************************************************************************************************/
362 /* info functions, get and display various NDIS driver values */
363
364
365 static void
366 add_row_to_table(GtkWidget *list, guint *row, gchar *title, const gchar *value, gboolean sensitive)
367 {
368     GtkWidget *label;
369     gchar     *indent;
370
371     if(strlen(value) != 0) {
372         indent = g_strdup_printf("   %s", title);
373     } else {
374         indent = g_strdup(title);
375     }
376     label = gtk_label_new(indent);
377     g_free(indent);
378     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
379     gtk_widget_set_sensitive(label, sensitive);
380     gtk_table_attach_defaults(GTK_TABLE(list), label, 0, 1, *row, *row+1);
381
382     label = gtk_label_new(value);
383     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
384     gtk_widget_set_sensitive(label, sensitive);
385     gtk_table_attach_defaults(GTK_TABLE(list), label, 1, 2, *row, *row+1);
386
387     *row = *row + 1;
388 }
389
390
391 static void
392 add_string_to_table_sensitive(GtkWidget *list, guint *row, gchar *title, gchar *value, gboolean sensitive)
393 {
394     add_row_to_table(list, row, title, value, sensitive);
395 }
396
397
398 static void
399 add_string_to_table(GtkWidget *list, guint *row, gchar *title, const gchar *value)
400 {
401     add_row_to_table(list, row, title, value, TRUE);
402 }
403
404
405 static void
406 ssid_details(GtkWidget *table, guint *row, struct ndis_essid *ssid_in) {
407     struct ndis_essid   ssid[2]; /* prevent an off by one error */
408
409
410     ssid[0] = *ssid_in;
411     g_assert(ssid->length <= NDIS_ESSID_MAX_SIZE);
412
413     if(ssid->length != 0) {
414         ssid->essid[ssid->length] = '\0';
415         add_string_to_table(table, row, "SSID", ssid->essid);
416     } else {
417         add_string_to_table(table, row, "SSID", "(currently not associated with an SSID)");
418     }
419 }
420
421
422 static GString *
423 rates_details(unsigned char *values, int length) {
424     int                 i;
425     GString             *Rates;
426     float               float_value;
427
428
429     Rates = g_string_new("");
430
431     if(length != 0) {
432         i = 0;
433         while(length--) {
434             if(values[i]) {
435                 float_value = (float) ((values[i] & 0x7F) / 2);
436                 if(i == 0) {
437                     g_string_sprintfa(Rates, "%.1f", float_value);
438                 } else {
439                     g_string_sprintfa(Rates, " / %.1f", float_value);
440                 }
441             }
442             i++;
443         }
444         Rates = g_string_append(Rates, " MBits/s");
445     } else {
446         Rates = g_string_append(Rates, "-");
447     }
448
449     return Rates;
450 }
451
452
453 static void
454 capture_if_details_802_11_bssid_list(GtkWidget *main_vb, struct ndis_bssid_list *bssid_list)
455 {
456     struct ndis_ssid_item   *bssid_item;
457     unsigned char           mac[6];
458     const gchar             *manuf_name;
459     GString                 *Rates;
460
461
462     if(bssid_list->num_items != 0) {
463         char *titles[] = { "SSID", "MAC", "Vendor", "RSSI" , "Network Type" , "Infra. Mode" , "Channel" , "Rates" };
464         GtkWidget     *list;
465
466         gchar ssid_buff[DETAILS_STR_MAX];
467         gchar mac_buff[DETAILS_STR_MAX];
468         gchar vendor_buff[DETAILS_STR_MAX];
469         gchar rssi_buff[DETAILS_STR_MAX];
470         gchar nettype_buff[DETAILS_STR_MAX];
471         gchar infra_buff[DETAILS_STR_MAX];
472         gchar freq_buff[DETAILS_STR_MAX];
473
474         list = simple_list_new(8, titles);
475         gtk_container_add(GTK_CONTAINER(main_vb), list);
476
477         bssid_item = &bssid_list->items[0];
478
479         while(bssid_list->num_items--) {
480
481             /* SSID */
482             if(bssid_item->ssid.length > DETAILS_STR_MAX-1) {
483                 bssid_item->ssid.length = DETAILS_STR_MAX-1;
484             }
485             memcpy(ssid_buff, bssid_item->ssid.essid, bssid_item->ssid.length);
486             ssid_buff[bssid_item->ssid.length] = '\0';
487
488             /* MAC */
489             memcpy(mac, &bssid_item->mac, sizeof(mac));
490             g_snprintf(mac_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
491                 mac[0], mac[1], mac[2], 
492                 mac[3], mac[4], mac[5]);
493
494             /* Vendor */
495             manuf_name = get_manuf_name_if_known(mac);
496             if(manuf_name != NULL) {
497                 strcpy(vendor_buff, manuf_name);
498             } else {
499                 strcpy(vendor_buff, "");
500             }
501
502             /* Supported Rates */
503             Rates = rates_details(bssid_item->rates, NDIS_MAX_RATES_EX);
504
505             /* RSSI */
506             g_snprintf(rssi_buff, DETAILS_STR_MAX, "%d dBm", bssid_item->rssi);
507
508             /* Network Type */
509             g_snprintf(nettype_buff, sizeof(nettype_buff), "%s",
510                 val_to_str(bssid_item->net_type, win32_802_11_network_type_vals, "(0x%x)"));
511
512             /* Infrastructure Mode */
513             g_snprintf(infra_buff, sizeof(infra_buff), "%s",
514                 val_to_str(bssid_item->mode, win32_802_11_infra_mode_vals, "(0x%x)"));
515
516             /* Channel */
517             g_snprintf(freq_buff, sizeof(freq_buff), "%s",
518                 val_to_str(bssid_item->config.ds_config, win32_802_11_channel_vals, "(%u kHz)"));
519
520             /* IE Length  (XXX - add decoding) */
521             /* g_warning ("802.11 IE Length          : %u", bssid_item->ie_length); */
522
523             simple_list_append(list, 
524                 0, ssid_buff,
525                 1, mac_buff,
526                 2, vendor_buff,
527                 3, rssi_buff,
528                 4, nettype_buff,
529                 5, infra_buff, 
530                 6, freq_buff, 
531                 7, Rates->str,
532                 -1);
533
534             g_string_free(Rates, TRUE /* free_segment */);
535
536             /* the bssid_list isn't an array, but a sequence of variable length items */
537             bssid_item = (struct ndis_ssid_item *) (((char *) bssid_item) + bssid_item->length);
538         }
539     }
540 }
541
542 static int
543 capture_if_details_802_11(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) {
544     ULONG               ulong_value;
545     LONG                long_value;
546     unsigned int        uint_value;
547     unsigned char       values[100];
548     struct ndis_essid   ssid;
549     int                 length;
550     struct ndis_bssid_list      *bssid_list;
551     struct ndis_configuration   *configuration;
552     gchar               string_buff[DETAILS_STR_MAX];
553     GString             *Rates;
554     int                 entries = 0;
555
556
557     add_string_to_table(table, row, "Characteristics", "");
558
559     /* BSSID */
560     length = sizeof(values);
561     memset(values, 0, 6);
562     if (wpcap_packet_request(adapter, OID_802_11_BSSID, FALSE /* !set */, values, &length)) {
563         g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
564             values[0], values[1], values[2], 
565             values[3], values[4], values[5]);
566         entries++;
567     } else {
568         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
569     }
570     add_string_to_table(table, row, "BSSID", string_buff);
571
572     /* SSID */
573     length = sizeof(struct ndis_essid);
574     memset(&ssid, 0, length);
575     if (wpcap_packet_request(adapter, OID_802_11_SSID, FALSE /* !set */, (char *) &ssid, &length)) {
576         ssid_details(table, row, &ssid);
577         entries++;
578     } else {
579         add_string_to_table(table, row, "SSID", "-");
580     }
581
582     /* Network type in use */
583     if (wpcap_packet_request_uint(adapter, OID_802_11_NETWORK_TYPE_IN_USE, &uint_value)) {
584         add_string_to_table(table, row, "Network type used", 
585             val_to_str(uint_value, win32_802_11_network_type_vals, "(0x%x)"));
586         entries++;
587     } else {
588         add_string_to_table(table, row, "Network type used", "-");
589     }
590
591     /* Infrastructure mode */
592     if (wpcap_packet_request_ulong(adapter, OID_802_11_INFRASTRUCTURE_MODE, &uint_value)) {
593         add_string_to_table(table, row, "Infrastructure mode", 
594             val_to_str(uint_value, win32_802_11_infra_mode_vals, "(0x%x)"));
595         entries++;
596     } else {
597         add_string_to_table(table, row, "Infrastructure mode", "-");
598     }
599
600     /* Authentication mode */
601     if (wpcap_packet_request_ulong(adapter, OID_802_11_AUTHENTICATION_MODE, &uint_value)) {
602         add_string_to_table(table, row, "Authentication mode", 
603             val_to_str(uint_value, win32_802_11_auth_mode_vals, "(0x%x)"));
604         entries++;
605     } else {
606         add_string_to_table(table, row, "Authentication mode", "-");
607     }
608
609     /* Encryption (WEP) status */
610     if (wpcap_packet_request_ulong(adapter, OID_802_11_ENCRYPTION_STATUS, &uint_value)) {
611         add_string_to_table(table, row, "Encryption status", 
612             val_to_str(uint_value, win32_802_11_encryption_status_vals, "(0x%x)"));
613         entries++;
614     } else {
615         add_string_to_table(table, row, "Encryption status", "-");
616     }
617
618     /* TX power */
619     if (wpcap_packet_request_ulong(adapter, OID_802_11_TX_POWER_LEVEL, &ulong_value)) {
620         g_snprintf(string_buff, DETAILS_STR_MAX, "%ld mW", ulong_value);
621         add_string_to_table(table, row, "TX power", string_buff);
622         entries++;
623     } else {
624         add_string_to_table(table, row, "TX power", "-");
625     }
626
627     /* RSSI */
628     if (wpcap_packet_request_ulong(adapter, OID_802_11_RSSI, &long_value)) {
629         g_snprintf(string_buff, DETAILS_STR_MAX, "%ld dBm", long_value);
630         add_string_to_table(table, row, "RSSI", string_buff);
631         entries++;
632     } else {
633         add_string_to_table(table, row, "RSSI", "-");
634     }
635
636     /* Supported Rates */
637     length = sizeof(values);
638     if (!wpcap_packet_request(adapter, OID_802_11_SUPPORTED_RATES, FALSE /* !set */, values, &length)) {
639         length = 0;
640     } else {
641         entries++;
642     }
643
644     Rates = rates_details(values, length);
645     add_string_to_table(table, row, "Supported Rates", Rates->str);
646     g_string_free(Rates, TRUE /* free_segment */);
647
648     /* Desired Rates */
649     length = sizeof(values);
650     if (!wpcap_packet_request(adapter, OID_802_11_DESIRED_RATES, FALSE /* !set */, values, &length)) {
651         length = 0;
652     } else {
653         entries++;
654     }
655
656     Rates = rates_details(values, length);
657     add_string_to_table(table, row, "Desired Rates", Rates->str);
658     g_string_free(Rates, TRUE /* free_segment */);
659
660     /* Configuration (e.g. frequency) */
661     length = sizeof(values);
662     if (wpcap_packet_request(adapter, OID_802_11_CONFIGURATION, FALSE /* !set */, (char *) values, &length)) {
663         configuration = (struct ndis_configuration *) values;
664
665         add_string_to_table(table, row, "Channel",
666             val_to_str(configuration->ds_config, win32_802_11_channel_vals, "(%u kHz)"));
667         entries++;
668     } else {
669         add_string_to_table(table, row, "Channel", "-");
670     }
671
672     /* BSSID list: first trigger a scan */
673     length = sizeof(uint_value);
674     if (wpcap_packet_request(adapter, OID_802_11_BSSID_LIST_SCAN, TRUE /* set */, (char *) &uint_value, &length)) {
675 #if 0
676         g_warning("BSSID list scan done");
677     } else {
678         g_warning("BSSID list scan failed");
679 #endif
680     }
681
682     /* BSSID list: get scan results */
683     /* XXX - we might have to wait up to 7 seconds! */
684         length = sizeof(ULONG) + sizeof(struct ndis_ssid_item) * 16;
685         bssid_list = g_malloc(length);
686         /* some drivers don't set bssid_list->num_items to 0 if
687            OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */
688         memset(bssid_list, 0, length);
689
690     if (wpcap_packet_request(adapter, OID_802_11_BSSID_LIST, FALSE /* !set */, (char *) bssid_list, &length)) {
691         add_string_to_table(table, row, "", "");
692         add_string_to_table(table, row, "BSSID list", "");
693
694         capture_if_details_802_11_bssid_list(main_vb, bssid_list);
695         entries += bssid_list->num_items;
696     } else {
697         add_string_to_table(table, row, "802.11 BSSID list", "-");
698     }
699
700     g_free(bssid_list);
701
702     return entries;
703 }
704
705
706 static int
707 capture_if_details_802_3(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter) {
708     unsigned int    uint_value;
709     unsigned char   values[100];
710     int             length;
711     gchar           string_buff[DETAILS_STR_MAX];
712     const gchar     *manuf_name;
713     int             entries = 0;
714
715
716     add_string_to_table(table, row, "Characteristics", "");
717
718     length = sizeof(values);
719     if (wpcap_packet_request(adapter, OID_802_3_PERMANENT_ADDRESS, FALSE /* !set */, values, &length)) {
720         manuf_name = get_manuf_name_if_known(values);
721         if(manuf_name != NULL) {
722             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
723                 values[0], values[1], values[2], 
724                 values[3], values[4], values[5],
725                 manuf_name);
726         } else {
727             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
728                 values[0], values[1], values[2], 
729                 values[3], values[4], values[5]);
730         }
731         entries++;
732     } else {
733         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
734     }
735     add_string_to_table(table, row, "Permanent station address", string_buff);
736
737     length = sizeof(values);
738     if (wpcap_packet_request(adapter, OID_802_3_CURRENT_ADDRESS, FALSE /* !set */, values, &length)) {
739         manuf_name = get_manuf_name_if_known(values);
740         if(manuf_name != NULL) {
741             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
742                 values[0], values[1], values[2], 
743                 values[3], values[4], values[5],
744                 manuf_name);
745         } else {
746             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X:%02X:%02X:%02X",
747                 values[0], values[1], values[2], 
748                 values[3], values[4], values[5]);
749         }
750         entries++;
751     } else {
752         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
753     }
754     add_string_to_table(table, row, "Current station address", string_buff);
755
756
757     add_string_to_table(table, row, "", "");
758     add_string_to_table(table, row, "Statistics", "");
759
760     if (wpcap_packet_request_uint(adapter, OID_802_3_RCV_ERROR_ALIGNMENT, &uint_value)) {
761         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
762         entries++;
763     } else {
764         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
765     }
766     add_string_to_table(table, row, "Packets received with alignment error", string_buff);
767
768     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_ONE_COLLISION, &uint_value)) {
769         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
770         entries++;
771     } else {
772         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
773     }
774     add_string_to_table(table, row, "Packets transmitted with one collision", string_buff);
775
776     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_MORE_COLLISIONS, &uint_value)) {
777         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
778         entries++;
779     } else {
780         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
781     }
782     add_string_to_table(table, row, "Packets transmitted with more than one collision", string_buff);
783
784     if (wpcap_packet_request_uint(adapter, OID_802_3_RCV_OVERRUN, &uint_value)) {
785         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
786         entries++;
787     } else {
788         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
789     }
790     add_string_to_table(table, row, "Packets not received due to overrun", string_buff);
791
792     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_DEFERRED, &uint_value)) {
793         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
794         entries++;
795     } else {
796         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
797     }
798     add_string_to_table(table, row, "Packets transmitted after deferred", string_buff);
799
800     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_MAX_COLLISIONS, &uint_value)) {
801         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
802         entries++;
803     } else {
804         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
805     }
806     add_string_to_table(table, row, "Packets not transmitted due to collisions", string_buff);
807
808     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_UNDERRUN, &uint_value)) {
809         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
810         entries++;
811     } else {
812         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
813     }
814     add_string_to_table(table, row, "Packets not transmitted due to underrun", string_buff);
815
816     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_HEARTBEAT_FAILURE, &uint_value)) {
817         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
818         entries++;
819     } else {
820         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
821     }
822     add_string_to_table(table, row, "Packets transmitted with heartbeat failure", string_buff);
823
824     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_TIMES_CRS_LOST, &uint_value)) {
825         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
826         entries++;
827     } else {
828         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
829     }
830     add_string_to_table(table, row, "Times carrier sense signal lost during transmission", string_buff);
831
832     if (wpcap_packet_request_uint(adapter, OID_802_3_XMIT_LATE_COLLISIONS, &uint_value)) {
833         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
834         entries++;
835     } else {
836         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
837     }
838     add_string_to_table(table, row, "Times late collisions detected", string_buff);
839
840     return entries;
841 }
842
843
844 static void
845 capture_if_details_general(GtkWidget *table, GtkWidget *main_vb, guint *row, LPADAPTER adapter, gchar *iface) {
846     gchar           string_buff[DETAILS_STR_MAX];
847     const gchar     *manuf_name;
848     unsigned int    uint_value;
849     unsigned int    uint_array[50];
850     int             uint_array_size;
851     unsigned int    physical_medium;
852     int             i;
853     unsigned char   values[100];
854     int             length;
855     unsigned short  ushort_value;
856
857
858     /* general */
859     add_string_to_table(table, row, "Characteristics", "");
860
861     /* Vendor description */
862     length = sizeof(values);
863     if (wpcap_packet_request(adapter, OID_GEN_VENDOR_DESCRIPTION, FALSE /* !set */, values, &length)) {
864         g_snprintf(string_buff, DETAILS_STR_MAX, "%s", values);
865     } else {
866         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
867     }
868     add_string_to_table(table, row, "Vendor description", string_buff);
869
870     /* Interface */
871     add_string_to_table(table, row, "Interface", iface);
872
873     /* link status (connected/disconnected) */
874     if (wpcap_packet_request_uint(adapter, OID_GEN_MEDIA_CONNECT_STATUS, &uint_value)) {
875         if(uint_value == 0) {
876             add_string_to_table(table, row, "Link status", "Connected");
877         } else {
878             add_string_to_table(table, row, "Link status", "Disconnected");
879         }
880     } else {
881         add_string_to_table(table, row, "Link status", "-");
882     }
883
884     /* link speed */
885     if (wpcap_packet_request_uint(adapter, OID_GEN_LINK_SPEED, &uint_value)) {
886         uint_value *= 100;
887         if(uint_value >= 1000 * 1000) {
888             g_snprintf(string_buff, DETAILS_STR_MAX, "%d MBits/s", uint_value / 1000 / 1000);
889         } else {
890             if(uint_value >= 1000) {
891                 g_snprintf(string_buff, DETAILS_STR_MAX, "%d KBits/s", uint_value / 1000);
892             } else {
893                 g_snprintf(string_buff, DETAILS_STR_MAX, "%d Bits/s", uint_value);
894             }
895         }
896     } else {
897         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
898     }
899     add_string_to_table(table, row, "Link speed", string_buff);
900
901
902
903     uint_array_size = sizeof(uint_array);
904     if (wpcap_packet_request(adapter, OID_GEN_MEDIA_SUPPORTED, FALSE /* !set */, (char *) uint_array, &uint_array_size)) {
905         uint_array_size /= sizeof(unsigned int);
906         i=0;
907         while(uint_array_size--) {
908             add_string_to_table(table, row, "Media supported", 
909                 val_to_str(uint_array[i], win32_802_3_medium_vals, "(0x%x)"));
910             i++;
911         }
912     } else {
913         add_string_to_table(table, row, "Media supported", "-");
914     }
915
916     uint_array_size = sizeof(uint_array);
917     if (wpcap_packet_request(adapter, OID_GEN_MEDIA_IN_USE, FALSE /* !set */, (char *) uint_array, &uint_array_size)) {
918         uint_array_size /= sizeof(unsigned int);
919         i=0;
920         while(uint_array_size--) {
921             add_string_to_table(table, row, "Medium in use", 
922                   val_to_str(uint_array[i], win32_802_3_medium_vals, "(0x%x)"));
923             i++;
924         }
925     } else {
926         add_string_to_table(table, row, "Medium in use", "-");
927     }
928
929     if (wpcap_packet_request_uint(adapter, OID_GEN_PHYSICAL_MEDIUM, &physical_medium)) {
930         add_string_to_table(table, row, "Physical medium", 
931             val_to_str(physical_medium, win32_802_3_physical_medium_vals, "(0x%x)"));
932     } else {
933         add_string_to_table(table, row, "Physical medium", "-");
934     }
935
936     length = sizeof(ushort_value);
937     if (wpcap_packet_request(adapter, OID_GEN_DRIVER_VERSION, FALSE /* !set */, (char *) &ushort_value, &length)) {
938         g_assert(length == 2);
939         g_snprintf(string_buff, DETAILS_STR_MAX, "%u.%u", ushort_value / 0x100, ushort_value % 0x100);
940     } else {
941         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
942     }
943     add_string_to_table(table, row, "NDIS Driver Version", string_buff);
944
945     length = sizeof(uint_value);
946     if (wpcap_packet_request(adapter, OID_GEN_VENDOR_DRIVER_VERSION, FALSE /* !set */, (char *) &uint_value, &length)) {
947         g_assert(length == 4);
948         /* XXX - what's the correct output format? */
949         g_snprintf(string_buff, DETAILS_STR_MAX, "%u.%u (Hex: %X.%X)", 
950             (uint_value / 0x10000  ) % 0x10000,
951              uint_value              % 0x10000,
952             (uint_value / 0x10000  ) % 0x10000,
953              uint_value              % 0x10000);
954     } else {
955         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
956     }
957     add_string_to_table(table, row, "Vendor Driver Version", string_buff);
958
959     length = sizeof(values);
960     if (wpcap_packet_request(adapter, OID_GEN_VENDOR_ID, FALSE /* !set */, values, &length)) {
961         manuf_name = get_manuf_name_if_known(values);
962         if(manuf_name != NULL) {
963             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X (%s) NIC: %02X", 
964                 values[0], values[1], values[2], manuf_name, values[3]);
965         } else {
966             g_snprintf(string_buff, DETAILS_STR_MAX, "%02X:%02X:%02X NIC: %02X", 
967                 values[0], values[1], values[2], values[3]);
968         }
969     } else {
970         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
971     }
972     add_string_to_table(table, row, "Vendor ID", string_buff);
973
974     if (wpcap_packet_request_uint(adapter, OID_GEN_VLAN_ID, &uint_value)) {
975         g_snprintf(string_buff, DETAILS_STR_MAX, "%u", uint_value);
976     } else {
977         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
978     }
979     add_string_to_table(table, row, "VLAN ID", string_buff);
980
981
982     /* XXX - OID_GEN_MAC_OPTIONS (bitfield, VLAN, ...) */
983     
984     if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_BUFFER_SPACE, &uint_value)) {
985         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
986     } else {
987         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
988     }
989     add_string_to_table(table, row, "Transmit Buffer Space", string_buff);
990
991     if (wpcap_packet_request_uint(adapter, OID_GEN_RECEIVE_BUFFER_SPACE, &uint_value)) {
992         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
993     } else {
994         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
995     }
996     add_string_to_table(table, row, "Receive Buffer Space", string_buff);
997
998     if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_BLOCK_SIZE , &uint_value)) {
999         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1000     } else {
1001         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1002     }
1003     add_string_to_table(table, row, "Transmit Block Size", string_buff);
1004
1005     if (wpcap_packet_request_uint(adapter, OID_GEN_RECEIVE_BLOCK_SIZE, &uint_value)) {
1006         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1007     } else {
1008         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1009     }
1010     add_string_to_table(table, row, "Receive Block Size", string_buff);
1011
1012     if (wpcap_packet_request_uint(adapter, OID_GEN_MAXIMUM_TOTAL_SIZE, &uint_value)) {
1013         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1014     } else {
1015         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1016     }
1017     add_string_to_table(table, row, "Maximum Packet Size", string_buff);
1018
1019
1020     /* Statistics */
1021     add_string_to_table(table, row, "", "");
1022     add_string_to_table(table, row, "Statistics", "");
1023
1024     if (wpcap_packet_request_uint(adapter, OID_GEN_XMIT_OK, &uint_value)) {
1025         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1026     } else {
1027         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1028     }
1029     add_string_to_table(table, row, "Transmit OK", string_buff);
1030
1031     if (wpcap_packet_request_uint(adapter, OID_GEN_XMIT_ERROR, &uint_value)) {
1032         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1033     } else {
1034         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1035     }
1036     add_string_to_table(table, row, "Transmit Error", string_buff);
1037
1038
1039     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_OK, &uint_value)) {
1040         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1041     } else {
1042         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1043     }
1044     add_string_to_table(table, row, "Receive OK", string_buff);
1045
1046     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_ERROR, &uint_value)) {
1047         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1048     } else {
1049         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1050     }
1051     add_string_to_table(table, row, "Receive Error", string_buff);
1052
1053     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_NO_BUFFER, &uint_value)) {
1054         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1055     } else {
1056         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1057     }
1058     add_string_to_table(table, row, "Receive but no Buffer", string_buff);
1059
1060     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_BYTES_XMIT, &uint_value)) {
1061         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1062     } else {
1063         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1064     }
1065     add_string_to_table(table, row, "Directed bytes transmitted w/o errors", string_buff);
1066
1067     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_FRAMES_XMIT, &uint_value)) {
1068         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1069     } else {
1070         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1071     }
1072     add_string_to_table(table, row, "Directed packets transmitted w/o errors", string_buff);
1073
1074     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_BYTES_XMIT, &uint_value)) {
1075         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1076     } else {
1077         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1078     }
1079     add_string_to_table(table, row, "Multicast bytes transmitted w/o errors", string_buff);
1080
1081     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_FRAMES_XMIT, &uint_value)) {
1082         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1083     } else {
1084         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1085     }
1086     add_string_to_table(table, row, "Multicast packets transmitted w/o errors", string_buff);
1087
1088     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_BYTES_XMIT, &uint_value)) {
1089         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1090     } else {
1091         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1092     }
1093     add_string_to_table(table, row, "Broadcast bytes transmitted w/o errors", string_buff);
1094
1095     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_FRAMES_XMIT, &uint_value)) {
1096         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1097     } else {
1098         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1099     }
1100     add_string_to_table(table, row, "Broadcast packets transmitted w/o errors", string_buff);
1101
1102     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_BYTES_RCV, &uint_value)) {
1103         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1104     } else {
1105         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1106     }
1107     add_string_to_table(table, row, "Directed bytes received w/o errors", string_buff);
1108
1109     if (wpcap_packet_request_uint(adapter, OID_GEN_DIRECTED_FRAMES_RCV, &uint_value)) {
1110         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1111     } else {
1112         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1113     }
1114     add_string_to_table(table, row, "Directed packets received w/o errors", string_buff);
1115
1116     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_BYTES_RCV, &uint_value)) {
1117         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1118     } else {
1119         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1120     }
1121     add_string_to_table(table, row, "Multicast bytes received w/o errors", string_buff);
1122
1123     if (wpcap_packet_request_uint(adapter, OID_GEN_MULTICAST_FRAMES_RCV, &uint_value)) {
1124         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1125     } else {
1126         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1127     }
1128     add_string_to_table(table, row, "Multicast packets received w/o errors", string_buff);
1129
1130     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_BYTES_RCV, &uint_value)) {
1131         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1132     } else {
1133         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1134     }
1135     add_string_to_table(table, row, "Broadcast bytes received w/o errors", string_buff);
1136
1137     if (wpcap_packet_request_uint(adapter, OID_GEN_BROADCAST_FRAMES_RCV, &uint_value)) {
1138         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1139     } else {
1140         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1141     }
1142     add_string_to_table(table, row, "Broadcast packets received w/o errors", string_buff);
1143
1144     if (wpcap_packet_request_uint(adapter, OID_GEN_RCV_CRC_ERROR, &uint_value)) {
1145         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1146     } else {
1147         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1148     }
1149     add_string_to_table(table, row, "Packets received with CRC or FCS errors", string_buff);
1150
1151     if (wpcap_packet_request_uint(adapter, OID_GEN_TRANSMIT_QUEUE_LENGTH, &uint_value)) {
1152         g_snprintf(string_buff, DETAILS_STR_MAX, "%d", uint_value);
1153     } else {
1154         g_snprintf(string_buff, DETAILS_STR_MAX, "-");
1155     }
1156     add_string_to_table(table, row, "Packets queued for transmission", string_buff);
1157
1158 }
1159
1160
1161 static GtkWidget *
1162 capture_if_details_page_new(GtkWidget **table)
1163 {
1164     GtkWidget *main_vb;
1165
1166     main_vb = gtk_vbox_new(FALSE, 6);
1167     gtk_container_border_width(GTK_CONTAINER(main_vb), 12);
1168
1169     /* table */
1170     *table = gtk_table_new(1, 2, FALSE);
1171     gtk_table_set_col_spacings(GTK_TABLE(*table), 6);
1172     gtk_table_set_row_spacings(GTK_TABLE(*table), 3);
1173     gtk_container_add(GTK_CONTAINER(main_vb), *table);
1174
1175     return main_vb;
1176 }
1177
1178
1179 static void
1180 capture_if_details_open_win(char *iface)
1181 {
1182     GtkWidget   *details_open_w,
1183                 *main_vb, *bbox, *close_bt, *help_bt;
1184     GtkWidget   *page_general, *page_802_3, *page_802_11;
1185     GtkWidget   *page_lb;
1186     GtkWidget   *table, *notebook, *label;
1187     guint       row;
1188     LPADAPTER   adapter;
1189     int         entries;
1190
1191
1192     /* open the network adapter */
1193     adapter = wpcap_packet_open(iface);
1194
1195     /* open a new window */
1196     details_open_w = window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: Interface Details");
1197
1198     /* Container for the window contents */
1199     main_vb = gtk_vbox_new(FALSE, 12);
1200     gtk_container_border_width(GTK_CONTAINER(main_vb), 12);
1201     gtk_container_add(GTK_CONTAINER(details_open_w), main_vb);
1202
1203     /* notebook */
1204     notebook = gtk_notebook_new();
1205     gtk_container_add(GTK_CONTAINER(main_vb), notebook);
1206
1207     /* General page */
1208     page_general = capture_if_details_page_new(&table);
1209     page_lb = gtk_label_new("General");
1210     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_general, page_lb);
1211     row = 0;
1212     capture_if_details_general(table, page_general, &row, adapter, iface);
1213
1214     /* 802.3 (Ethernet) page */
1215     page_802_3 = capture_if_details_page_new(&table);
1216     page_lb = gtk_label_new("802.3 (Ethernet)");
1217     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_802_3, page_lb);
1218     row = 0;
1219     entries = capture_if_details_802_3(table, page_802_3, &row, adapter);
1220     if(entries == 0) {
1221         gtk_widget_set_sensitive(page_lb, FALSE);
1222     }
1223
1224     /* 802_11 (WI-FI) page */
1225     page_802_11 = capture_if_details_page_new(&table);
1226     page_lb = gtk_label_new("802.11 (WLAN)");
1227     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_802_11, page_lb);
1228     row = 0;
1229     entries = capture_if_details_802_11(table, page_802_11, &row, adapter);
1230     if(entries == 0) {
1231         gtk_widget_set_sensitive(page_lb, FALSE);
1232     }
1233
1234     wpcap_packet_close(adapter);
1235
1236     label = gtk_label_new("Note: accuracy of all of these values are only relying on the network card driver!");
1237     gtk_container_add(GTK_CONTAINER(main_vb), label);
1238
1239     /* Button row. */
1240     if(topic_available(HELP_STATS_SUMMARY_DIALOG)) {
1241         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
1242     } else {
1243         bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
1244     }
1245     gtk_container_add(GTK_CONTAINER(main_vb), bbox);
1246
1247     close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
1248     window_set_cancel_button(details_open_w, close_bt, window_cancel_button_cb);
1249
1250     if(topic_available(HELP_STATS_SUMMARY_DIALOG)) {
1251         help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
1252         SIGNAL_CONNECT(help_bt, "clicked", topic_cb, HELP_STATS_SUMMARY_DIALOG);
1253     }
1254
1255     gtk_widget_grab_focus(close_bt);
1256
1257     SIGNAL_CONNECT(details_open_w, "delete_event", window_delete_event_cb, NULL);
1258
1259     gtk_widget_show_all(details_open_w);
1260     window_present(details_open_w);
1261 }
1262
1263
1264 static void capture_if_details_open_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
1265 {
1266     switch(btn) {
1267     case(ESD_BTN_OK):
1268         capture_if_details_open_win(data);
1269         break;
1270     case(ESD_BTN_CANCEL):
1271         break;
1272     default:
1273         g_assert_not_reached();
1274     }
1275 }
1276
1277
1278 void
1279 capture_if_details_open(char *iface)
1280 {
1281     char        *version;
1282     gboolean    version_ok = FALSE;
1283     gpointer    dialog;
1284
1285
1286     /* check packet.dll version */
1287     version = wpcap_packet_get_version();
1288
1289     if(version == NULL) {
1290         /* couldn't even get the packet.dll version, must be a very old one or just not existing -> give up */
1291         /* (this seems to be the case for 2.3 beta and all previous releases) */
1292         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, 
1293             PRIMARY_TEXT_START "Couldn't optain WinPcap packet.dll version!" PRIMARY_TEXT_END
1294             "\n\nThe WinPcap packet.dll is not installed or the version you use seems to be very old!"
1295             "\n\nPlease update/install WinPcap.");
1296         return;
1297     }
1298
1299     /* XXX - add more known DLL versions here */
1300     /* (all versions since the 2.3 release seems to be working (although the 2.3 beta did not) */
1301     if( strcmp(version, "3, 1, 0, 27") == 0 ||       /* 3.1 release */
1302         strcmp(version, "3, 1, 0, 24") == 0 ||       /* 3.1 beta 4 */
1303         strcmp(version, "3, 1, 0, 23") == 0 ||       /* 3.1 beta 3 */
1304         strcmp(version, "3, 1, 0, 22") == 0 ||       /* 3.1 beta 2 */
1305         strcmp(version, "3, 1, 0, 20") == 0 ||       /* 3.1 beta */
1306         strcmp(version, "3.0 alpha3" ) == 0 ||       /* 3.0 release or 3.0 beta (yes, both versions report alpha3!) */
1307         strcmp(version, "2.3"        ) == 0          /* 2.3 release */
1308         ) {   
1309             version_ok = TRUE;
1310     }
1311
1312     if(!version_ok) {
1313         /* packet.dll version not known to us, warn user but try to continue */
1314         dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK | ESD_BTN_CANCEL, 
1315             PRIMARY_TEXT_START "Unknown WinPcap version might crash or fail!" PRIMARY_TEXT_END
1316             "\n\nThe WinPcap packet.dll version \"%s\" is unknown if it supports required functions!"
1317             "\n\nOnly WinPcap versions 3.0 and 3.1 are known to work with this feature."
1318             "\n\nCrashes or unexpected behaviour might occur, you have been warned!"
1319             "\n\nContinue anyway?",
1320             version);
1321         simple_dialog_set_cb(dialog, capture_if_details_open_answered_cb, iface);
1322     } else {
1323         capture_if_details_open_win(iface);
1324     }
1325 }
1326
1327
1328 #endif /* HAVE_LIBPCAP && _WIN32 */