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