Install the GUI xml files. I'm not sure about the Makefile.am changes pkease check.
[obnox/wireshark/wip.git] / airpcap_loader.c
1 /* airpcap_loader.c
2  *
3  * $Id$
4  *
5  * Giorgio Tino <giorgio.tino@cacetech.com>
6  * Copyright (c) CACE Technologies, LLC 2006
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 2000 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #ifdef HAVE_AIRPCAP
32
33 #ifdef HAVE_LIBPCAP
34 #include <glib.h>
35 #include <gmodule.h>
36
37
38 #include <wtap.h>
39 #include <pcap.h>
40 #endif
41
42 #include <epan/packet.h>
43 #include <epan/prefs.h>
44 #include <epan/prefs-int.h>
45 #include <epan/crypt/wep-wpadefs.h>
46 #include <epan/crypt/airpdcap_ws.h>
47 #include <epan/strutil.h>
48 #include <epan/frequency-utils.h>
49 #include "capture_ui_utils.h"
50 #include <wsutil/file_util.h>
51
52 #include "simple_dialog.h"
53
54 #include <airpcap.h>
55 #include "airpcap_loader.h"
56
57
58 /*
59  * Set to TRUE if the DLL was successfully loaded AND all functions
60  * are present.
61  */
62 static gboolean AirpcapLoaded = FALSE;
63
64 #ifdef _WIN32
65 /*
66  * We load dynamically the dag library in order link it only when
67  * it's present on the system
68  */
69 static void * AirpcapLib = NULL;
70
71 static AirpcapGetLastErrorHandler g_PAirpcapGetLastError;
72 static AirpcapSetKernelBufferHandler g_PAirpcapSetKernelBuffer;
73 static AirpcapSetFilterHandler g_PAirpcapSetFilter;
74 static AirpcapGetMacAddressHandler g_PAirpcapGetMacAddress;
75 static AirpcapSetMinToCopyHandler g_PAirpcapSetMinToCopy;
76 static AirpcapGetReadEventHandler g_PAirpcapGetReadEvent;
77 static AirpcapReadHandler g_PAirpcapRead;
78 static AirpcapGetStatsHandler g_PAirpcapGetStats;
79 #endif
80
81 static int AirpcapVersion = 3;
82
83 static AirpcapGetDeviceListHandler g_PAirpcapGetDeviceList;
84 static AirpcapFreeDeviceListHandler g_PAirpcapFreeDeviceList;
85 static AirpcapOpenHandler g_PAirpcapOpen;
86 static AirpcapCloseHandler g_PAirpcapClose;
87 static AirpcapGetLinkTypeHandler g_PAirpcapGetLinkType;
88 static AirpcapSetLinkTypeHandler g_PAirpcapSetLinkType;
89 static AirpcapTurnLedOnHandler g_PAirpcapTurnLedOn;
90 static AirpcapTurnLedOffHandler g_PAirpcapTurnLedOff;
91 static AirpcapGetDeviceChannelHandler g_PAirpcapGetDeviceChannel;
92 static AirpcapSetDeviceChannelHandler g_PAirpcapSetDeviceChannel;
93 static AirpcapGetFcsPresenceHandler g_PAirpcapGetFcsPresence;
94 static AirpcapSetFcsPresenceHandler g_PAirpcapSetFcsPresence;
95 static AirpcapGetFcsValidationHandler g_PAirpcapGetFcsValidation;
96 static AirpcapSetFcsValidationHandler g_PAirpcapSetFcsValidation;
97 static AirpcapGetDeviceKeysHandler g_PAirpcapGetDeviceKeys;
98 static AirpcapSetDeviceKeysHandler g_PAirpcapSetDeviceKeys;
99 static AirpcapGetDriverKeysHandler g_PAirpcapGetDriverKeys;
100 static AirpcapSetDriverKeysHandler g_PAirpcapSetDriverKeys;
101 static AirpcapGetDecryptionStateHandler g_PAirpcapGetDecryptionState;
102 static AirpcapSetDecryptionStateHandler g_PAirpcapSetDecryptionState;
103 static AirpcapGetDriverDecryptionStateHandler g_PAirpcapGetDriverDecryptionState;
104 static AirpcapSetDriverDecryptionStateHandler g_PAirpcapSetDriverDecryptionState;
105 static AirpcapStoreCurConfigAsAdapterDefaultHandler g_PAirpcapStoreCurConfigAsAdapterDefault;
106 static AirpcapGetVersionHandler g_PAirpcapGetVersion;
107 static AirpcapSetDeviceChannelExHandler g_PAirpcapSetDeviceChannelEx;
108 static AirpcapGetDeviceChannelExHandler g_PAirpcapGetDeviceChannelEx;
109 static AirpcapGetDeviceSupportedChannelsHandler g_PAirpcapGetDeviceSupportedChannels;
110
111 /* Airpcap interface list */
112 GList *airpcap_if_list = NULL;
113
114 /* Airpcap current selected interface */
115 airpcap_if_info_t *airpcap_if_selected = NULL;
116
117 /* Airpcap current active interface */
118 airpcap_if_info_t *airpcap_if_active = NULL;
119
120 /* WLAN preferences pointer */
121 module_t *wlan_prefs = NULL;
122
123 Dot11Channel *pSupportedChannels;
124 guint numSupportedChannels;
125
126 static AirpcapChannelInfo LegacyChannels[] =
127 {
128         {2412, 0, {0,0,0}},
129         {2417, 0, {0,0,0}},
130         {2422, 0, {0,0,0}},
131         {2427, 0, {0,0,0}},
132         {2432, 0, {0,0,0}},
133         {2437, 0, {0,0,0}},
134         {2442, 0, {0,0,0}},
135         {2447, 0, {0,0,0}},
136         {2452, 0, {0,0,0}},
137         {2457, 0, {0,0,0}},
138         {2462, 0, {0,0,0}},
139         {2467, 0, {0,0,0}},
140         {2472, 0, {0,0,0}},
141         {2484, 0, {0,0,0}},
142 };
143
144 static guint num_legacy_channels = 14;
145
146 /*
147  * Callback used by the load_wlan_keys() routine in order to read a WEP decryption key
148  */
149 static guint
150 get_wep_key(pref_t *pref, gpointer ud)
151 {
152     gchar *key_string = NULL;
153     guint8 key_type = AIRPDCAP_KEY_TYPE_WEP;
154     keys_cb_data_t* user_data;
155
156     decryption_key_t* new_key;
157
158     /* Retrieve user data info */
159     user_data = (keys_cb_data_t*)ud;
160
161     if (g_ascii_strncasecmp(pref->name, "wep_key", 7) == 0 && pref->type == PREF_STRING)
162     {
163         /* strip out key type */
164         if (g_ascii_strncasecmp(*pref->varp.string, STRING_KEY_TYPE_WEP ":", 4) == 0) {
165                key_string = (gchar*)(*pref->varp.string)+4;
166         }
167         else if (g_ascii_strncasecmp(*pref->varp.string, STRING_KEY_TYPE_WPA_PWD ":", 8) == 0) {
168                key_string = (gchar*)(*pref->varp.string)+8;
169           key_type = AIRPDCAP_KEY_TYPE_WPA_PWD;
170         }
171         else if (g_ascii_strncasecmp(*pref->varp.string, STRING_KEY_TYPE_WPA_PSK ":", 8) == 0) {
172                key_string = (gchar*)(*pref->varp.string)+8;
173           key_type = AIRPDCAP_KEY_TYPE_WPA_PSK;
174         }
175         else {
176           key_type = AIRPDCAP_KEY_TYPE_WEP;
177                key_string = (gchar*)*pref->varp.string;
178         }
179
180             /* Here we have the string describing the key... */
181             new_key = parse_key_string(key_string, key_type);
182
183             if( new_key != NULL)
184             {
185                /* Key is added only if not null ... */
186                user_data->list = g_list_append(user_data->list,new_key);
187                user_data->number_of_keys++;
188                user_data->current_index++;
189             }
190     }
191     return 0;
192 }
193
194 /* Returs TRUE if the WEP key is valid, false otherwise */
195 gboolean
196 wep_key_is_valid(char* key)
197 {
198     GString *new_key_string;
199     guint i=0;
200
201     if(key == NULL)
202         return FALSE;
203
204     new_key_string = g_string_new(key);
205
206     if( ((new_key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((new_key_string->len) < 2))
207     {
208         g_string_free(new_key_string,FALSE);
209         return FALSE;
210     }
211     if((new_key_string->len % 2) != 0)
212     {
213         g_string_free(new_key_string,FALSE);
214         return FALSE;
215     }
216     for(i = 0; i < new_key_string->len; i++)
217     {
218         if(!g_ascii_isxdigit(new_key_string->str[i]))
219         {
220             g_string_free(new_key_string,FALSE);
221             return FALSE;
222         }
223     }
224
225     g_string_free(new_key_string,FALSE);
226     return TRUE;
227 }
228
229 /* Callback used by the save_wlan_keys() routine in order to write a decryption key */
230 static guint
231 set_wep_key(pref_t *pref, gpointer ud _U_)
232 {
233     gchar *my_string = NULL;
234     keys_cb_data_t* user_data;
235     gint wep_key_number = 0;
236
237     decryption_key_t* new_key;
238
239     /* Retrieve user data info */
240     user_data = (keys_cb_data_t*)ud;
241
242     if (g_ascii_strncasecmp(pref->name, "wep_key", 7) == 0 && pref->type == PREF_STRING)
243     {
244         /* Ok, the pref we're gonna set is a wep_key ... but what number? */
245         sscanf(pref->name,"wep_key%d",&wep_key_number);
246
247         if(user_data->current_index < user_data->number_of_keys)
248         {
249             if(wep_key_number == (user_data->current_index+1))
250             {
251                 /* Retrieve the nth decryption_key_t structure pointer */
252                 new_key = (decryption_key_t*)g_list_nth_data(user_data->list,user_data->current_index);
253
254                 /* Free the old key string */
255                 g_free((void *)*pref->varp.string);
256
257                 /* Create the new string describing the decryption key */
258                 my_string = get_key_string(new_key);
259
260                 /* Duplicate the string, and assign it to the variable pointer */
261                 *pref->varp.string = (void *)g_strdup(my_string);
262
263                 /* Free the previously allocated string */
264                 g_free(my_string);
265             }
266         }
267         else /* If the number of keys has been reduced somehow, we need to delete all the other keys
268               * (remember that the new ones have been probably overwritten)
269               */
270         {
271             g_free((void *)*pref->varp.string);
272             *pref->varp.string = (void *)g_strdup("");  /* Do not just free memory!!! Put an 'empty' string! */
273         }
274         user_data->current_index++;
275     }
276
277     return 0;
278 }
279
280 /*
281  * Function used to read the Decryption Keys from the preferences and store them
282  * properly into the airpcap adapter.
283  */
284 gboolean
285 load_wlan_driver_wep_keys(void)
286 {
287     keys_cb_data_t* user_data;
288     guint i;
289
290     /* Retrieve the wlan preferences */
291     wlan_prefs = prefs_find_module("wlan");
292
293     /* Allocate a structure used to keep infos  between the callbacks */
294     user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
295
296     /* Fill the structure */
297     user_data->list = NULL;
298     user_data->current_index = 0;
299     user_data->number_of_keys= 0; /* Still unknown */
300
301     /* Run the callback on each 802.11 preference */
302     prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)user_data);
303
304     /* Now the key list should be filled */
305
306     /*
307      * Signal that we've changed things, and run the 802.11 dissector's
308      * callback
309      */
310     wlan_prefs->prefs_changed = TRUE;
311
312     prefs_apply(wlan_prefs);
313
314     write_wlan_driver_wep_keys_to_registry(user_data->list);
315
316     /* FREE MEMORY */
317     /* free the WEP key string */
318     for(i=0;i<g_list_length(user_data->list);i++)
319     {
320         g_free(g_list_nth(user_data->list,i)->data);
321     }
322
323     /* free the (empty) list */
324     g_list_free(user_data->list);
325
326     /* free the user_data structure */
327     g_free(user_data);
328
329     /* airpcap_if_info_free(fake_info_if); */
330
331     return TRUE;
332 }
333
334 /*
335  * This function will tell the airpcap driver the key list to use
336  * This will be stored into the registry...
337  */
338 gboolean
339 write_wlan_wep_keys_to_registry(airpcap_if_info_t* info_if, GList* key_list)
340 {
341     guint i,j;
342     GString *new_key;
343     gchar s[3];
344     PAirpcapKeysCollection KeysCollection;
345     guint KeysCollectionSize;
346     guint8 KeyByte;
347     guint keys_in_list = 0;
348     decryption_key_t* key_item = NULL;
349
350     keys_in_list = g_list_length(key_list);
351
352     /*
353      * Save the encryption keys, if we have any of them
354      */
355     KeysCollectionSize = 0;
356
357     /*
358      * Calculate the size of the keys collection
359      */
360     KeysCollectionSize = sizeof(AirpcapKeysCollection) + keys_in_list * sizeof(AirpcapKey);
361
362     /*
363      * Allocate the collection
364      */
365     KeysCollection = (PAirpcapKeysCollection)g_malloc(KeysCollectionSize);
366     if(!KeysCollection)
367     {
368         return FALSE;
369     }
370
371     /*
372      * Populate the key collection
373      */
374     KeysCollection->nKeys = keys_in_list;
375
376     for(i = 0; i < keys_in_list; i++)
377     {
378         KeysCollection->Keys[i].KeyType = AIRPDCAP_KEY_TYPE_WEP;
379
380         /* Retrieve the Item corresponding to the i-th key */
381         key_item = (decryption_key_t*)g_list_nth_data(key_list,i);
382         new_key = g_string_new(key_item->key->str);
383
384         KeysCollection->Keys[i].KeyLen = (guint) new_key->len / 2;
385         memset(&KeysCollection->Keys[i].KeyData, 0, sizeof(KeysCollection->Keys[i].KeyData));
386
387         for(j = 0 ; j < new_key->len; j += 2)
388         {
389             s[0] = new_key->str[j];
390             s[1] = new_key->str[j+1];
391             s[2] = '\0';
392             KeyByte = (guint8)strtol(s, NULL, 16);
393             KeysCollection->Keys[i].KeyData[j / 2] = KeyByte;
394         }
395
396         g_string_free(new_key,TRUE);
397
398     }
399     /*
400      * Free the old adapter key collection!
401      */
402     if(info_if->keysCollection != NULL)
403         g_free(info_if->keysCollection);
404
405     /*
406      * Set this collection ad the new one
407      */
408     info_if->keysCollection = KeysCollection;
409     info_if->keysCollectionSize = KeysCollectionSize;
410
411     /*
412      * Configuration must be saved
413      */
414     info_if->saved = FALSE;
415
416     /*
417      * Write down the changes to the registry
418      */
419     airpcap_save_selected_if_configuration(info_if);
420
421     return TRUE;
422 }
423
424 /*
425  * This function will tell the airpcap driver the key list to use
426  * This will be stored into the registry...
427  */
428 gboolean
429 write_wlan_driver_wep_keys_to_registry(GList* key_list)
430 {
431     guint i,j,k,n,y;
432     GString *new_key;
433     gchar s[3];
434     PAirpcapKeysCollection KeysCollection;
435     guint KeysCollectionSize;
436     guint8 KeyByte;
437     guint keys_in_list = 0;
438     decryption_key_t* key_item = NULL;
439     airpcap_if_info_t* fake_info_if = NULL;
440
441     /* Create the fake_info_if from the first adapter of the list */
442     fake_info_if = airpcap_driver_fake_if_info_new();
443
444     if(fake_info_if == NULL)
445         return FALSE;
446
447     /*
448      * XXX - When WPA will be supported, change this to: keys_in_list = g_list_length(key_list);
449      * but right now we will have to count only the WEP keys (or we will have a malloc-mess :-) )
450      */
451     n = g_list_length(key_list);
452     for(k = 0; k < n; k++ )
453         if(((decryption_key_t*)g_list_nth_data(key_list,k))->type == AIRPDCAP_KEY_TYPE_WEP)
454             keys_in_list++;
455
456     /*
457      * Save the encryption keys, if we have any of them
458      */
459     KeysCollectionSize = 0;
460
461     /*
462      * Calculate the size of the keys collection
463      */
464     KeysCollectionSize = sizeof(AirpcapKeysCollection) + keys_in_list * sizeof(AirpcapKey);
465
466     /*
467      * Allocate the collection
468      */
469     KeysCollection = (PAirpcapKeysCollection)g_malloc(KeysCollectionSize);
470     if(!KeysCollection)
471     {
472         return FALSE;
473     }
474
475     /*
476      * Populate the key collection
477      */
478     KeysCollection->nKeys = keys_in_list;
479
480     /*
481      * XXX - If we have, let's say, six keys, the first three are WEP, then two are WPA, and the
482      * last is WEP, we have to scroll the whole list (n) but increment the array counter only
483      * when a WEP key is found (y) .. When WPA will be supported by the driver, I'll have to change
484      * this
485      */
486     y = 0; /* Current position in the key list */
487
488     for(i = 0; i < n; i++)
489     {
490         /* Retrieve the Item corresponding to the i-th key */
491         key_item = (decryption_key_t*)g_list_nth_data(key_list,i);
492
493         /*
494          * XXX - The AIRPDCAP_KEY_TYPE_WEP is the only supported right now!
495          * We will have to modify the AirpcapKey structure in order to
496          * support the other two types! What happens now, is that simply the
497          * not supported keys will just be discarded (they will be saved in Wireshark though)
498          */
499         if(key_item->type == AIRPDCAP_KEY_TYPE_WEP)
500         {
501             KeysCollection->Keys[y].KeyType = AIRPDCAP_KEY_TYPE_WEP;
502
503             new_key = g_string_new(key_item->key->str);
504
505             KeysCollection->Keys[y].KeyLen = (guint) new_key->len / 2;
506             memset(&KeysCollection->Keys[y].KeyData, 0, sizeof(KeysCollection->Keys[y].KeyData));
507
508             for(j = 0 ; j < new_key->len; j += 2)
509             {
510                 s[0] = new_key->str[j];
511                 s[1] = new_key->str[j+1];
512                 s[2] = '\0';
513                 KeyByte = (guint8)strtol(s, NULL, 16);
514                 KeysCollection->Keys[y].KeyData[j / 2] = KeyByte;
515             }
516             /* XXX - Change when WPA will be supported!!! */
517             y++;
518             g_string_free(new_key,TRUE);
519         }
520         else if(key_item->type == AIRPDCAP_KEY_TYPE_WPA_PWD)
521         {
522             /* XXX - The driver cannot deal with this kind of key yet... */
523         }
524         else if(key_item->type == AIRPDCAP_KEY_TYPE_WPA_PMK)
525         {
526             /* XXX - The driver cannot deal with this kind of key yet... */
527         }
528     }
529
530     /*
531      * Free the old adapter key collection!
532      */
533     if(fake_info_if->keysCollection != NULL)
534         g_free(fake_info_if->keysCollection);
535
536     /*
537      * Set this collection ad the new one
538      */
539     fake_info_if->keysCollection = KeysCollection;
540     fake_info_if->keysCollectionSize = KeysCollectionSize;
541
542     /*
543      * Configuration must be saved
544      */
545     fake_info_if->saved = FALSE;
546
547     /*
548      * Write down the changes to the registry
549      */
550     airpcap_save_driver_if_configuration(fake_info_if);
551
552     airpcap_if_info_free(fake_info_if);
553
554     return TRUE;
555 }
556
557 /*
558  *  Function used to save to the preference file the Decryption Keys.
559  */
560 int
561 save_wlan_driver_wep_keys(void)
562 {
563     GList* key_list = NULL;
564     char* tmp_key = NULL;
565     guint keys_in_list,i;
566     keys_cb_data_t* user_data;
567     airpcap_if_info_t* fake_info_if = NULL;
568
569     /* Create the fake_info_if from the first adapter of the list */
570     fake_info_if = airpcap_driver_fake_if_info_new();
571
572     if(fake_info_if == NULL)
573         return 0;
574
575     /* Retrieve the wlan preferences */
576     wlan_prefs = prefs_find_module("wlan");
577
578     /* Allocate a structure used to keep infos  between the callbacks */
579     user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
580
581     /* Number of keys in key list */
582     if(fake_info_if->keysCollectionSize != 0)
583         keys_in_list = (guint)(fake_info_if->keysCollectionSize -  sizeof(AirpcapKeysCollection))/sizeof(AirpcapKey);
584     else
585         keys_in_list = 0;
586
587     for(i=0; i<keys_in_list; i++)
588     {
589     /* Only if it is a WEP key... */
590         if(fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP)
591         {
592             tmp_key = airpcap_get_key_string(fake_info_if->keysCollection->Keys[i]);
593             key_list = g_list_append(key_list,g_strdup(tmp_key));
594             g_free(tmp_key);
595         }
596     }
597
598     /* Now we know the exact number of WEP keys in the list, so store it ... */
599     keys_in_list = g_list_length(key_list);
600
601     /* Fill the structure */
602     user_data->list = key_list;
603     user_data->current_index = 0;
604     user_data->number_of_keys= keys_in_list;
605
606     /* Retrieve the wlan preferences */
607     wlan_prefs = prefs_find_module("wlan");
608
609     /* Run the callback on each 802.11 preference */
610     prefs_pref_foreach(wlan_prefs, set_wep_key,  (gpointer)user_data);
611
612     /* Signal that we've changed things, and run the 802.11 dissector's
613      * callback */
614     wlan_prefs->prefs_changed = TRUE;
615
616     /* Apply changes for the specified preference */
617     prefs_apply(wlan_prefs);
618
619     /* FREE MEMORY */
620     /* free the WEP key string */
621     for(i=0;i<g_list_length(user_data->list);i++)
622     {
623         g_free(g_list_nth(user_data->list,i)->data);
624     }
625
626     /* free the (empty) list */
627     g_list_free(user_data->list);
628
629     /* free the user_data structure */
630     g_free(user_data);
631
632     airpcap_if_info_free(fake_info_if);
633
634     return keys_in_list;
635 }
636
637 /*
638  *  Function used to save to the preference file the Decryption Keys.
639  */
640 int
641 save_wlan_wireshark_wep_keys(GList* key_ls)
642 {
643     GList* key_list = NULL;
644     guint keys_in_list,i;
645     keys_cb_data_t* user_data;
646     decryption_key_t* tmp_dk;
647
648     /* Retrieve the wlan preferences */
649     wlan_prefs = prefs_find_module("wlan");
650
651     /* Allocate a structure used to keep infos  between the callbacks */
652     user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
653
654     keys_in_list = g_list_length(key_ls);
655
656     key_list = key_ls;
657
658     /* Fill the structure */
659     user_data->list = key_list;
660     user_data->current_index = 0;
661     user_data->number_of_keys= keys_in_list;
662
663     /* Retrieve the wlan preferences */
664     wlan_prefs = prefs_find_module("wlan");
665
666     /* Run the callback on each 802.11 preference */
667     prefs_pref_foreach(wlan_prefs, set_wep_key,  (gpointer)user_data);
668
669     /* Signal that we've changed things, and run the 802.11 dissector's
670      * callback */
671     wlan_prefs->prefs_changed = TRUE;
672
673     /* Apply changes for the specified preference */
674     prefs_apply(wlan_prefs);
675
676     /* FREE MEMORY */
677     /* free the WEP key string */
678     for(i=0;i<g_list_length(user_data->list);i++)
679     {
680         tmp_dk = (decryption_key_t*)g_list_nth(user_data->list,i)->data;
681         g_string_free(tmp_dk->key,TRUE);
682         if(tmp_dk->ssid != NULL) g_byte_array_free(tmp_dk->ssid,TRUE);
683     }
684
685     /* free the (empty) list */
686     g_list_free(user_data->list);
687
688     /* free the user_data structure */
689     g_free(user_data);
690
691     return keys_in_list;
692 }
693
694 /*
695  * Get an error message string for a CANT_GET_INTERFACE_LIST error from
696  * "get_airpcap_interface_list()".
697  */
698 static gchar *
699 cant_get_airpcap_if_list_error_message(const char *err_str)
700 {
701     return g_strdup_printf("Can't get list of Wireless interfaces: %s", err_str);
702 }
703
704 /*
705  * Airpcap wrapper, used to store the current settings for the selected adapter
706  */
707 gboolean
708 airpcap_if_store_cur_config_as_adapter_default(PAirpcapHandle ah)
709 {
710     if (!AirpcapLoaded) return FALSE;
711     return g_PAirpcapStoreCurConfigAsAdapterDefault(ah);
712 }
713
714 /*
715  * Airpcap wrapper, used to open an airpcap adapter
716  */
717 PAirpcapHandle
718 airpcap_if_open(gchar * name, gchar * err)
719 {
720     if (!AirpcapLoaded) return NULL;
721     if (name == NULL) return NULL;
722     return g_PAirpcapOpen(name,err);
723 }
724
725 /*
726  * Airpcap wrapper, used to close an airpcap adapter
727  */
728 void
729 airpcap_if_close(PAirpcapHandle handle)
730 {
731     if (!AirpcapLoaded) return;
732     g_PAirpcapClose(handle);
733 }
734
735 /*
736  * Retrieve the state of the Airpcap DLL
737  */
738 int
739 airpcap_get_dll_state(void)
740 {
741   return AirpcapVersion;
742 }
743
744 /*
745  * Airpcap wrapper, used to turn on the led of an airpcap adapter
746  */
747 gboolean
748 airpcap_if_turn_led_on(PAirpcapHandle AdapterHandle, guint LedNumber)
749 {
750     if (!AirpcapLoaded) return FALSE;
751     return g_PAirpcapTurnLedOn(AdapterHandle,LedNumber);
752 }
753
754 /*
755  * Airpcap wrapper, used to turn off the led of an airpcap adapter
756  */
757 gboolean
758 airpcap_if_turn_led_off(PAirpcapHandle AdapterHandle, guint LedNumber)
759 {
760     if (!AirpcapLoaded) return FALSE;
761     return g_PAirpcapTurnLedOff(AdapterHandle,LedNumber);
762 }
763
764 /*
765  * Airpcap wrapper, used to get the channel of an airpcap adapter
766  */
767 gboolean
768 airpcap_if_get_device_channel(PAirpcapHandle ah, guint * ch)
769 {
770     if (!AirpcapLoaded) return FALSE;
771     return g_PAirpcapGetDeviceChannel(ah,ch);
772 }
773
774 /*
775  * Airpcap wrapper, used to get the supported channels of an airpcap adapter
776  */
777 gboolean
778 airpcap_if_get_device_supported_channels(PAirpcapHandle ah, AirpcapChannelInfo **cInfo, guint * nInfo)
779 {
780     if (!AirpcapLoaded) return FALSE;
781     if (airpcap_get_dll_state() == AIRPCAP_DLL_OLD){
782       *nInfo = num_legacy_channels;
783       *cInfo = (AirpcapChannelInfo*)&LegacyChannels;
784
785       return TRUE;
786     } else if (airpcap_get_dll_state() == AIRPCAP_DLL_OK){
787       return g_PAirpcapGetDeviceSupportedChannels(ah, cInfo, nInfo);
788     }
789     return FALSE;
790 }
791
792 /*
793  * Airpcap wrapper, used to get the supported channels of an airpcap adapter
794  */
795 Dot11Channel*
796 airpcap_if_get_device_supported_channels_array(PAirpcapHandle ah, guint * pNumSupportedChannels)
797 {
798     AirpcapChannelInfo *chanInfo;
799     guint i=0, j=0, numInfo = 0;
800
801     if (!AirpcapLoaded)
802         return NULL;
803     if (airpcap_if_get_device_supported_channels(ah, &chanInfo, &numInfo) == FALSE)
804         return NULL;
805     numSupportedChannels = 0;
806
807     /*
808      * allocate a bigger array
809      */
810     if (numInfo == 0)
811         return NULL;
812
813     pSupportedChannels = g_malloc(numInfo * (sizeof *pSupportedChannels));
814
815     for (i = 0; i < numInfo; i++)
816     {
817         guint supportedChannel = G_MAXUINT;
818
819         /*
820          * search if we have it already
821          */
822         for (j = 0; j < numSupportedChannels; j++)
823         {
824             if (pSupportedChannels[j].Frequency == chanInfo[i].Frequency)
825             {
826                 supportedChannel = j;
827                 break;
828             }
829         }
830
831         if (supportedChannel == G_MAXUINT)
832         {
833             /*
834              * not found, create a new item
835              */
836             pSupportedChannels[numSupportedChannels].Frequency = chanInfo[i].Frequency;
837
838             switch(chanInfo[i].ExtChannel)
839             {
840                 case -1:
841                     pSupportedChannels[numSupportedChannels].Flags = FLAG_CAN_BE_LOW;
842                     break;
843                 case +1:
844                     pSupportedChannels[numSupportedChannels].Flags = FLAG_CAN_BE_HIGH;
845                     break;
846                 case 0:
847                 default:
848                     pSupportedChannels[numSupportedChannels].Flags = 0;
849             }
850
851             /*
852              * Gather channel information
853              */
854
855             pSupportedChannels[numSupportedChannels].Flags |=
856                 FREQ_IS_BG(pSupportedChannels[numSupportedChannels].Frequency) ?
857                     FLAG_IS_BG_CHANNEL : FLAG_IS_A_CHANNEL;
858             pSupportedChannels[numSupportedChannels].Channel =
859                 ieee80211_mhz_to_chan(pSupportedChannels[numSupportedChannels].Frequency);
860             numSupportedChannels++;
861         }
862         else
863         {
864             /*
865              * just update the ext channel flags
866              */
867             switch(chanInfo[i].ExtChannel)
868             {
869                 case -1:
870                     pSupportedChannels[supportedChannel].Flags |= FLAG_CAN_BE_LOW;
871                     break;
872                 case +1:
873                     pSupportedChannels[supportedChannel].Flags |= FLAG_CAN_BE_HIGH;
874                     break;
875                 case 0:
876                 default:
877                     break;
878             }
879         }
880     }
881
882     if (numSupportedChannels < 1)
883         return NULL;
884     /*
885      * Now sort the list by frequency
886      */
887     for (i = 0 ; i < numSupportedChannels - 1; i++)
888     {
889         for (j = i + 1; j < numSupportedChannels; j++)
890         {
891             if (pSupportedChannels[i].Frequency > pSupportedChannels[j].Frequency)
892             {
893                 Dot11Channel temp = pSupportedChannels[i];
894                 pSupportedChannels[i] = pSupportedChannels[j];
895                 pSupportedChannels[j] = temp;
896             }
897         }
898     }
899
900     *pNumSupportedChannels = numSupportedChannels;
901     return pSupportedChannels;
902 }
903
904 /*
905  * Airpcap wrapper, used to set the channel of an airpcap adapter
906  */
907 gboolean
908 airpcap_if_set_device_channel(PAirpcapHandle ah, guint ch)
909 {
910     if (!AirpcapLoaded) return FALSE;
911     return g_PAirpcapSetDeviceChannel(ah,ch);
912 }
913
914 /*
915  * Airpcap wrapper, used to set the frequency of an airpcap adapter
916  */
917 gboolean
918 airpcap_if_set_device_channel_ex(PAirpcapHandle ah, AirpcapChannelInfo ChannelInfo)
919 {
920     if (!AirpcapLoaded) return FALSE;
921     if (airpcap_get_dll_state() == AIRPCAP_DLL_OLD){
922       gint channel = 0;
923       channel = ieee80211_mhz_to_chan(ChannelInfo.Frequency);
924
925       if (channel < 0){
926         return FALSE;
927       } else {
928         return airpcap_if_set_device_channel(ah, channel);
929       }
930     } else if (airpcap_get_dll_state() == AIRPCAP_DLL_OK){
931       return g_PAirpcapSetDeviceChannelEx (ah, ChannelInfo);
932     }
933
934     return FALSE;
935 }
936
937 /*
938  * Airpcap wrapper, used to get the frequency of an airpcap adapter
939  */
940 gboolean
941 airpcap_if_get_device_channel_ex(PAirpcapHandle ah, PAirpcapChannelInfo pChannelInfo)
942 {
943     if (!AirpcapLoaded) return FALSE;
944
945     pChannelInfo->Frequency = 0;
946     pChannelInfo->ExtChannel = 0;
947     pChannelInfo->Reserved[0] = 0;
948     pChannelInfo->Reserved[1] = 0;
949     pChannelInfo->Reserved[2] = 0;
950
951     if (airpcap_get_dll_state() == AIRPCAP_DLL_OLD){
952       guint channel = 0;
953       guint chan_freq = 0;
954
955       if (!airpcap_if_get_device_channel(ah, &channel)) return FALSE;
956
957       chan_freq = ieee80211_chan_to_mhz(channel, TRUE);
958       if (chan_freq == 0) return FALSE;
959       pChannelInfo->Frequency = chan_freq;
960
961       return TRUE;
962     } else if (airpcap_get_dll_state() == AIRPCAP_DLL_OK){
963       return g_PAirpcapGetDeviceChannelEx (ah, pChannelInfo);
964     }
965     return FALSE;
966 }
967
968 /*
969  * Airpcap wrapper, used to get the link type of an airpcap adapter
970  */
971 gboolean
972 airpcap_if_get_link_type(PAirpcapHandle ah, PAirpcapLinkType lt)
973 {
974     if (!AirpcapLoaded) return FALSE;
975     return g_PAirpcapGetLinkType(ah,lt);
976 }
977
978 /*
979  * Airpcap wrapper, used to set the link type of an airpcap adapter
980  */
981 gboolean
982 airpcap_if_set_link_type(PAirpcapHandle ah, AirpcapLinkType lt)
983 {
984     if (!AirpcapLoaded) return FALSE;
985     return g_PAirpcapSetLinkType(ah,lt);
986 }
987
988 /*
989  * Airpcap wrapper, used to get the fcs presence of an airpcap adapter
990  */
991 gboolean
992 airpcap_if_get_fcs_presence(PAirpcapHandle ah, gboolean * fcs)
993 {
994     if (!AirpcapLoaded) return FALSE;
995     return g_PAirpcapGetFcsPresence(ah,fcs);
996 }
997
998 /*
999  * Airpcap wrapper, used to set the fcs presence of an airpcap adapter
1000  */
1001 gboolean
1002 airpcap_if_set_fcs_presence(PAirpcapHandle ah, gboolean fcs)
1003 {
1004     if (!AirpcapLoaded) return FALSE;
1005     return g_PAirpcapSetFcsPresence(ah,fcs);
1006 }
1007
1008 /*
1009  * Airpcap wrapper, used to get the decryption enabling of an airpcap adapter
1010  */
1011 gboolean
1012 airpcap_if_get_decryption_state(PAirpcapHandle ah, PAirpcapDecryptionState PEnable)
1013 {
1014     if (!AirpcapLoaded) return FALSE;
1015     return g_PAirpcapGetDecryptionState(ah,PEnable);
1016 }
1017
1018 /*
1019  * Airpcap wrapper, used to set the decryption enabling of an airpcap adapter
1020  */
1021 gboolean
1022 airpcap_if_set_decryption_state(PAirpcapHandle ah, AirpcapDecryptionState Enable)
1023 {
1024     if (!AirpcapLoaded) return FALSE;
1025     return g_PAirpcapSetDecryptionState(ah,Enable);
1026 }
1027
1028 /*
1029  * Airpcap wrapper, used to get the decryption enabling of an airpcap driver
1030  */
1031 gboolean
1032 airpcap_if_get_driver_decryption_state(PAirpcapHandle ah, PAirpcapDecryptionState PEnable)
1033 {
1034     if (!AirpcapLoaded || (g_PAirpcapGetDriverDecryptionState==NULL)) return FALSE;
1035     return g_PAirpcapGetDriverDecryptionState(ah,PEnable);
1036 }
1037
1038 /*
1039  * Airpcap wrapper, used to set the decryption enabling of an airpcap driver
1040  */
1041 gboolean
1042 airpcap_if_set_driver_decryption_state(PAirpcapHandle ah, AirpcapDecryptionState Enable)
1043 {
1044     if (!AirpcapLoaded || (g_PAirpcapSetDriverDecryptionState==NULL)) return FALSE;
1045     return g_PAirpcapSetDriverDecryptionState(ah,Enable);
1046 }
1047
1048 /*
1049  * Airpcap wrapper, used to get the fcs validation of an airpcap adapter
1050  */
1051 gboolean
1052 airpcap_if_get_fcs_validation(PAirpcapHandle ah, PAirpcapValidationType val)
1053 {
1054     if (!AirpcapLoaded) return FALSE;
1055     return g_PAirpcapGetFcsValidation(ah,val);
1056 }
1057
1058 /*
1059  * Airpcap wrapper, used to set the fcs validation of an airpcap adapter
1060  */
1061 gboolean
1062 airpcap_if_set_fcs_validation(PAirpcapHandle ah, AirpcapValidationType val)
1063 {
1064     if (!AirpcapLoaded) return FALSE;
1065     return g_PAirpcapSetFcsValidation(ah,val);
1066 }
1067
1068 /*
1069  * Airpcap wrapper, used to save the settings for the selected_if
1070  */
1071 gboolean
1072 airpcap_if_set_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection)
1073 {
1074     if (!AirpcapLoaded) return FALSE;
1075     return g_PAirpcapSetDeviceKeys(AdapterHandle,KeysCollection);
1076 }
1077
1078 /*
1079  * Airpcap wrapper, used to save the settings for the selected_if
1080  */
1081 gboolean
1082 airpcap_if_get_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize)
1083 {
1084     if (!AirpcapLoaded) return FALSE;
1085     return g_PAirpcapGetDeviceKeys(AdapterHandle,KeysCollection,PKeysCollectionSize);
1086 }
1087
1088 /*
1089  * Airpcap wrapper, used to save the driver's set of keys
1090  */
1091 gboolean
1092 airpcap_if_set_driver_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection)
1093 {
1094     if (!AirpcapLoaded || (g_PAirpcapSetDriverKeys==NULL)) return FALSE;
1095     return g_PAirpcapSetDriverKeys(AdapterHandle,KeysCollection);
1096 }
1097
1098 /*
1099  * Airpcap wrapper, used to load the driver's set of keys
1100  */
1101 gboolean
1102 airpcap_if_get_driver_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize)
1103 {
1104     if (!AirpcapLoaded || (g_PAirpcapGetDriverKeys==NULL)) return FALSE;
1105     return g_PAirpcapGetDriverKeys(AdapterHandle,KeysCollection,PKeysCollectionSize);
1106 }
1107
1108 /*
1109  * This function will create a new airpcap_if_info_t using a name and a description
1110  */
1111 airpcap_if_info_t *
1112 airpcap_if_info_new(char *name, char *description)
1113 {
1114     PAirpcapHandle ad;
1115     gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1116
1117     airpcap_if_info_t *if_info = NULL;
1118
1119     /* Probably I have to switch on the leds!!! */
1120     ad = airpcap_if_open(name, ebuf);
1121     if(ad)
1122     {
1123                 if_info = g_malloc0(sizeof (airpcap_if_info_t));
1124                 if_info->name = g_strdup(name);
1125                 if (description == NULL){
1126                         if_info->description = NULL;
1127                 }else{
1128                         if_info->description = g_strdup(description);
1129                 }
1130
1131                 if_info->ip_addr = NULL;
1132                 if_info->loopback = FALSE;
1133                 airpcap_if_get_fcs_validation(ad,&(if_info->CrcValidationOn));
1134                 airpcap_if_get_fcs_presence(ad,&(if_info->IsFcsPresent));
1135                 airpcap_if_get_link_type(ad,&(if_info->linkType));
1136                 airpcap_if_get_device_channel_ex(ad,&(if_info->channelInfo));
1137                 if_info->pSupportedChannels = airpcap_if_get_device_supported_channels_array(ad, &(if_info->numSupportedChannels));
1138                 airpcap_if_turn_led_on(ad, 0);
1139                 airpcap_if_get_decryption_state(ad, &(if_info->DecryptionOn));
1140                 if_info->led = TRUE;
1141                 if_info->blinking = FALSE;
1142                 if_info->saved = TRUE; /* NO NEED TO BE SAVED */
1143
1144                 /* get the keys, if everything is ok, close the adapter */
1145                 if(airpcap_if_load_keys(ad,if_info))
1146                 {
1147                         airpcap_if_close(ad);
1148                 }
1149     }
1150     return if_info;
1151 }
1152
1153 /*
1154  * This function will create a new fake drivers' interface, to load global keys...
1155  */
1156 airpcap_if_info_t*
1157 airpcap_driver_fake_if_info_new(void)
1158 {
1159     PAirpcapHandle ad;
1160     gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1161
1162     airpcap_if_info_t *if_info = NULL;
1163     airpcap_if_info_t *fake_if_info = NULL;
1164
1165     /* Maybe for some reason no airpcap adapter is found */
1166     if(airpcap_if_list == NULL)
1167         return NULL;
1168
1169     /*
1170      * Retrieve the first AirPcap adapter available. If no interface is found,
1171      * it is not possible to retrieve the driver's settings, so return NULL.
1172      */
1173     if_info = g_list_nth_data(airpcap_if_list,0);
1174     if(if_info == NULL)
1175         return NULL;
1176
1177     /* Open the 'fake' adapter */
1178     ad = airpcap_if_open(if_info->name, ebuf);
1179     if(ad)
1180     {
1181                 fake_if_info = g_malloc(sizeof (airpcap_if_info_t));
1182                 fake_if_info->name = g_strdup(if_info->name);
1183                 fake_if_info->description = g_strdup(if_info->description);
1184                 fake_if_info->loopback = FALSE;
1185                 fake_if_info->ip_addr = NULL;
1186                 airpcap_if_get_driver_decryption_state(ad, &(fake_if_info->DecryptionOn));
1187                 airpcap_if_get_fcs_validation(ad,&(fake_if_info->CrcValidationOn));
1188                 airpcap_if_get_fcs_presence(ad,&(fake_if_info->IsFcsPresent));
1189                 airpcap_if_get_link_type(ad,&(fake_if_info->linkType));
1190                 airpcap_if_get_device_channel_ex(ad,&(fake_if_info->channelInfo));
1191                 airpcap_if_turn_led_on(ad, 0);
1192                 fake_if_info->led = TRUE;
1193                 fake_if_info->blinking = FALSE;
1194                 fake_if_info->saved = TRUE; /* NO NEED TO BE SAVED */
1195
1196                 /* get the keys, if everything is ok, close the adapter */
1197                 if(airpcap_if_load_driver_keys(ad,fake_if_info))
1198                 {
1199                         airpcap_if_close(ad);
1200                 }
1201     }
1202
1203     return fake_if_info;
1204 }
1205
1206 /*
1207  * USED FOR DEBUG ONLY... PRINTS AN AirPcap ADAPTER STRUCTURE in a fancy way.
1208  */
1209 void
1210 airpcap_if_info_print(airpcap_if_info_t* if_info)
1211 {
1212     guint i;
1213     if(if_info == NULL)
1214     {
1215                 g_print("\nWARNING : AirPcap Interface pointer is NULL!\n");
1216                 return;
1217     }
1218
1219     g_print("\n----------------- AirPcap Interface \n");
1220     g_print("                      NAME: %s\n",if_info->name);
1221     g_print("               DESCRIPTION: %s\n",if_info->description);
1222     g_print("                  BLINKING: %s\n",if_info->blinking ? "TRUE" : "FALSE");
1223     g_print("     channelInfo.Frequency: %u\n",if_info->channelInfo.Frequency);
1224     g_print("    channelInfo.ExtChannel: %d\n",if_info->channelInfo.ExtChannel);
1225     g_print("             CRCVALIDATION: %s\n",if_info->CrcValidationOn ? "ON" : "OFF");
1226     g_print("                DECRYPTION: %s\n",if_info->DecryptionOn ? "ON" : "OFF");
1227     g_print("                   IP ADDR: %s\n",if_info->ip_addr!=NULL ? "NOT NULL" : "NULL");
1228     g_print("                FCSPRESENT: %s\n",if_info->IsFcsPresent ? "TRUE" : "FALSE");
1229     g_print("            KEYSCOLLECTION: %s\n",if_info->keysCollection!=NULL ? "NOT NULL" : "NULL");
1230     g_print("        KEYSCOLLECTIONSIZE: %u\n",if_info->keysCollectionSize);
1231     g_print("                       LED: %s\n",if_info->led ? "ON" : "OFF");
1232     g_print("                  LINKTYPE: %d\n",if_info->linkType);
1233     g_print("                  LOOPBACK: %s\n",if_info->loopback ? "YES" : "NO");
1234     g_print("                 (GTK) TAG: %d\n",if_info->tag);
1235     g_print("SUPPORTED CHANNELS POINTER: %p\n",if_info->pSupportedChannels);
1236     g_print("    NUM SUPPORTED CHANNELS: %u\n",if_info->numSupportedChannels);
1237
1238     for(i=0; i<(if_info->numSupportedChannels); i++){
1239       g_print("\n        SUPPORTED CHANNEL #%u\n",i+1);
1240       g_print("                   CHANNEL: %u\n",if_info->pSupportedChannels[i].Channel);
1241       g_print("                 FREQUENCY: %u\n",if_info->pSupportedChannels[i].Frequency);
1242       g_print("                     FLAGS: %u\n",if_info->pSupportedChannels[i].Flags);
1243     }
1244     g_print("\n\n");
1245 }
1246
1247 /*
1248  * Function used to load the WEP keys for a selected interface
1249  */
1250 gboolean
1251 airpcap_if_load_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info)
1252 {
1253     if(!if_info) return FALSE;
1254
1255     if_info->keysCollectionSize = 0;
1256     if_info->keysCollection = NULL;
1257
1258     if(!airpcap_if_get_device_keys(ad, NULL, &(if_info->keysCollectionSize)))
1259     {
1260         if(if_info->keysCollectionSize == 0)
1261         {
1262             if_info->keysCollection = NULL;
1263             airpcap_if_close(ad);
1264             return FALSE;
1265         }
1266
1267         if_info->keysCollection = (PAirpcapKeysCollection)g_malloc(if_info->keysCollectionSize);
1268         if(!if_info->keysCollection)
1269         {
1270             if_info->keysCollectionSize = 0;
1271             if_info->keysCollection = NULL;
1272             airpcap_if_close(ad);
1273             return FALSE;
1274         }
1275
1276         airpcap_if_get_device_keys(ad, if_info->keysCollection, &(if_info->keysCollectionSize));
1277         return TRUE;
1278     }
1279
1280     airpcap_if_close(ad);
1281     return FALSE;
1282 }
1283
1284 /*
1285  * Function used to load the WEP keys for a selected interface
1286  */
1287 gboolean
1288 airpcap_if_load_driver_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info)
1289 {
1290     if_info->keysCollectionSize = 0;
1291     if_info->keysCollection = NULL;
1292
1293     if(!airpcap_if_get_driver_keys(ad, NULL, &(if_info->keysCollectionSize)))
1294     {
1295         if(if_info->keysCollectionSize == 0)
1296         {
1297             if_info->keysCollection = NULL;
1298             airpcap_if_close(ad);
1299             return FALSE;
1300         }
1301
1302         if_info->keysCollection = (PAirpcapKeysCollection)g_malloc(if_info->keysCollectionSize);
1303         if(!if_info->keysCollection)
1304         {
1305             if_info->keysCollectionSize = 0;
1306             if_info->keysCollection = NULL;
1307             airpcap_if_close(ad);
1308             return FALSE;
1309         }
1310
1311         airpcap_if_get_driver_keys(ad, if_info->keysCollection, &(if_info->keysCollectionSize));
1312         return TRUE;
1313     }
1314
1315     airpcap_if_close(ad);
1316     return FALSE;
1317 }
1318
1319 /*
1320  * Function used to save the WEP keys for a selected interface
1321  */
1322 void
1323 airpcap_if_save_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info)
1324 {
1325     if(!if_info || !AirpcapLoaded) return;
1326
1327     if(if_info->keysCollection != NULL)
1328         g_PAirpcapSetDeviceKeys(ad,if_info->keysCollection);
1329 }
1330
1331 /*
1332  * Function used to save the WEP keys for a selected interface
1333  */
1334 void
1335 airpcap_if_save_driver_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info)
1336 {
1337     if(if_info->keysCollection != NULL)
1338         airpcap_if_set_driver_keys(ad,if_info->keysCollection);
1339 }
1340
1341 /*
1342  * Callback used to free an instance of airpcap_if_info_t
1343  */
1344 static void
1345 free_airpcap_if_cb(gpointer data, gpointer user_data _U_)
1346 {
1347     airpcap_if_info_t *if_info = data;
1348
1349     if (if_info->name != NULL)
1350         g_free(if_info->name);
1351
1352     if (if_info->description != NULL)
1353         g_free(if_info->description);
1354
1355     /* XXX - FREE THE WEP KEY LIST HERE!!!*/
1356     if(if_info->keysCollection != NULL)
1357     {
1358         g_free(if_info->keysCollection);
1359         if_info->keysCollection = NULL;
1360     }
1361
1362     if(if_info->ip_addr != NULL)
1363         g_slist_free(if_info->ip_addr);
1364
1365     if(if_info != NULL)
1366         g_free(if_info);
1367 }
1368
1369 /*
1370  * Function used to free the airpcap interface list
1371  */
1372 void
1373 free_airpcap_interface_list(GList *if_list)
1374 {
1375     g_list_foreach(if_list, free_airpcap_if_cb, NULL);
1376     g_list_free(if_list);
1377     if_list = NULL;
1378 }
1379
1380 /*
1381  * This function will use the airpcap.dll to find all the airpcap devices.
1382  * Will return null if no device is found.
1383  */
1384 GList*
1385 get_airpcap_interface_list(int *err, char **err_str)
1386 {
1387     GList  *il = NULL;
1388     airpcap_if_info_t *if_info;
1389     int n_adapts;
1390     AirpcapDeviceDescription *devsList, *adListEntry;
1391     char errbuf[PCAP_ERRBUF_SIZE];
1392
1393     *err = 0;
1394
1395     if (!AirpcapLoaded)
1396     {
1397                 *err = AIRPCAP_NOT_LOADED;
1398                 return il;
1399     }
1400
1401     if (!g_PAirpcapGetDeviceList(&devsList, errbuf))
1402     {
1403                 /* No interfaces, return il = NULL; */
1404                 *err = CANT_GET_AIRPCAP_INTERFACE_LIST;
1405                 if (err_str != NULL)
1406                         *err_str = cant_get_airpcap_if_list_error_message(errbuf);
1407                 return il;
1408     }
1409
1410     /*
1411      * Count the adapters
1412      */
1413     adListEntry = devsList;
1414     n_adapts = 0;
1415     while(adListEntry)
1416     {
1417         n_adapts++;
1418         adListEntry = adListEntry->next;
1419     }
1420
1421     if(n_adapts == 0)
1422     {
1423                 /* No interfaces, return il= NULL */
1424                 g_PAirpcapFreeDeviceList(devsList);
1425                 *err = NO_AIRPCAP_INTERFACES_FOUND;
1426                 if (err_str != NULL)
1427                         *err_str = NULL;
1428                 return il;
1429     }
1430
1431     /*
1432      * Insert the adapters in our list
1433      */
1434     adListEntry = devsList;
1435     while(adListEntry)
1436     {
1437                 if_info = airpcap_if_info_new(adListEntry->Name, adListEntry->Description);
1438                 if (if_info != NULL){
1439                         il = g_list_append(il, if_info);
1440                 }
1441
1442                 adListEntry = adListEntry->next;
1443     }
1444
1445     g_PAirpcapFreeDeviceList(devsList);
1446
1447     return il;
1448 }
1449
1450 /*
1451  * Used to retrieve the interface given the name
1452  * (the name is used in AirpcapOpen)
1453  */
1454 airpcap_if_info_t* get_airpcap_if_from_name(GList* if_list, const gchar* name)
1455 {
1456     unsigned int ifn;
1457     GList* curr;
1458     airpcap_if_info_t* if_info;
1459
1460     ifn = 0;
1461     if(if_list != NULL)
1462     {
1463         while( ifn < g_list_length(if_list) )
1464         {
1465             curr = g_list_nth(if_list, ifn);
1466
1467             if_info = NULL;
1468             if(curr != NULL)
1469                     if_info = curr->data;
1470             if(if_info != NULL)
1471             {
1472                 if ( g_ascii_strcasecmp(if_info->name,name) == 0
1473 #ifdef HAVE_PCAP_REMOTE /* The interface will be prepended with "rpcap://" */
1474                         || g_str_has_suffix(name, if_info->name)
1475 #endif
1476                         )
1477                 {
1478                     return if_info;
1479                 }
1480             }
1481             ifn++;
1482         }
1483     }
1484     return NULL;
1485 }
1486
1487 /*
1488  * Returns the ASCII string of a key given the key bytes
1489  */
1490 gchar*
1491 airpcap_get_key_string(AirpcapKey key)
1492 {
1493     unsigned int j = 0;
1494     gchar *dst,*src;
1495
1496     dst = NULL;
1497     src = NULL;
1498
1499     if(key.KeyType == AIRPDCAP_KEY_TYPE_WEP)
1500     {
1501         if(key.KeyLen != 0)
1502         {
1503             /* Allocate the string used to store the ASCII representation of the WEP key */
1504             dst = (gchar*)g_malloc(sizeof(gchar)*WEP_KEY_MAX_CHAR_SIZE + 1);
1505             /* Make sure that the first char is '\0' in order to make g_strlcat() work */
1506             dst[0]='\0';
1507
1508             for(j = 0; j < key.KeyLen; j++)
1509             {
1510                 src = g_strdup_printf("%.2x", key.KeyData[j]);
1511                 /*
1512                  * XXX - use g_strconcat() or GStrings instead ???
1513                  */
1514                 g_strlcat(dst, src, WEP_KEY_MAX_CHAR_SIZE+1);
1515             }
1516             g_free(src);
1517         }
1518     }
1519     else if(key.KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD)
1520     {
1521         /* XXX - Add code here */
1522     }
1523     else if(key.KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK)
1524     {
1525         /* XXX - Add code here */
1526     }
1527     else
1528     {
1529         /* XXX - Add code here */
1530     }
1531
1532     return dst;
1533 }
1534
1535 /*
1536  * Clear keys and decryption status for the specified interface
1537  */
1538 void
1539 airpcap_if_clear_decryption_settings(airpcap_if_info_t* info_if)
1540 {
1541     if(info_if != NULL)
1542     {
1543         if(info_if->keysCollection != NULL)
1544         {
1545             g_free(info_if->keysCollection);
1546             info_if->keysCollection = NULL;
1547         }
1548
1549         info_if->keysCollectionSize = 0;
1550
1551         info_if->DecryptionOn = FALSE;
1552         info_if->saved = FALSE;
1553     }
1554 }
1555
1556 /*
1557  * Used to retrieve the two chars string from interface
1558  */
1559 gchar*
1560 airpcap_get_if_string_number(airpcap_if_info_t* if_info)
1561 {
1562     gchar* number;
1563     guint n;
1564     int a;
1565
1566     a = sscanf(if_info->name,AIRPCAP_DEVICE_NUMBER_EXTRACT_STRING,&n);
1567
1568     /* If sscanf() returned 1, it means that has read a number, so interface is not "Any"
1569      * Otherwise, check if it is the "Any" adapter...
1570      */
1571     if(a == 0)
1572     {
1573         if(g_ascii_strcasecmp(if_info->name,AIRPCAP_DEVICE_ANY_EXTRACT_STRING)!=0)
1574             number = g_strdup_printf("??");
1575         else
1576             number = g_strdup_printf(AIRPCAP_CHANNEL_ANY_NAME);
1577     }
1578     else
1579     {
1580         number = g_strdup_printf("%.2u",n);
1581     }
1582
1583     return number;
1584 }
1585
1586 /*
1587  * Used to retrieve the two chars string from interface
1588  */
1589 gchar*
1590 airpcap_get_if_string_number_from_description(gchar* description)
1591 {
1592     gchar* number;
1593     gchar* pointer;
1594
1595     number = (gchar*)g_malloc(sizeof(gchar)*3);
1596
1597     pointer = g_strrstr(description,"#\0");
1598
1599     number[0] = *(pointer+1);
1600     number[1] = *(pointer+2);
1601     number[2] = '\0';
1602
1603     return number;
1604 }
1605
1606 /*
1607  * Returns the default airpcap interface of a list, NULL if list is empty
1608  */
1609 airpcap_if_info_t*
1610 airpcap_get_default_if(GList* airpcap_if_list)
1611 {
1612     gchar* s;
1613     airpcap_if_info_t* if_info = NULL;
1614
1615     if(prefs.capture_device != NULL)
1616     {
1617         s = g_strdup(get_if_name(prefs.capture_device));
1618         if_info = get_airpcap_if_from_name(airpcap_if_list,g_strdup(get_if_name(prefs.capture_device)));
1619         g_free(s);
1620     }
1621     return if_info;
1622 }
1623
1624 /*
1625  * Load the configuration for the specified interface
1626  */
1627 void
1628 airpcap_load_selected_if_configuration(airpcap_if_info_t* if_info)
1629 {
1630     gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1631     PAirpcapHandle ad;
1632
1633     if(if_info != NULL)
1634     {
1635         ad = airpcap_if_open(if_info->name, ebuf);
1636
1637         if(ad)
1638         {
1639             /* Stop blinking (if it was blinking!)*/
1640             if(if_info->blinking)
1641             {
1642                 /* Turn on the light (if it was off) */
1643                 if(!(if_info->led)) airpcap_if_turn_led_on(ad, 0);
1644             }
1645
1646             /* Apply settings... */
1647             airpcap_if_get_device_channel_ex(ad,&(if_info->channelInfo));
1648             airpcap_if_get_fcs_validation(ad,&(if_info->CrcValidationOn));
1649             airpcap_if_get_fcs_presence(ad,&(if_info->IsFcsPresent));
1650             airpcap_if_get_link_type(ad,&(if_info->linkType));
1651             airpcap_if_get_decryption_state(ad, &(if_info->DecryptionOn));
1652             /* get the keys, if everything is ok, close the adapter */
1653             if(airpcap_if_load_keys(ad,if_info))
1654                 airpcap_if_close(ad);
1655
1656             if_info->saved = TRUE;
1657         }
1658         else
1659         {
1660             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",if_info->description);
1661         }
1662     }
1663 }
1664
1665 /*
1666  * Save the configuration for the specified interface
1667  */
1668 void
1669 airpcap_save_selected_if_configuration(airpcap_if_info_t* if_info)
1670 {
1671     gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1672     PAirpcapHandle ad;
1673
1674     if(if_info != NULL)
1675     {
1676         ad = airpcap_if_open(if_info->name, ebuf);
1677
1678         if(ad)
1679         {
1680             /* Stop blinking (if it was blinking!)*/
1681             if(if_info->blinking)
1682             {
1683                 /* Turn on the light (if it was off) */
1684                 if(!(if_info->led)) airpcap_if_turn_led_on(ad, 0);
1685             }
1686
1687             /* Apply settings... */
1688             airpcap_if_set_device_channel_ex(ad,if_info->channelInfo);
1689             airpcap_if_set_fcs_validation(ad,if_info->CrcValidationOn);
1690             airpcap_if_set_fcs_presence(ad,if_info->IsFcsPresent);
1691             airpcap_if_set_link_type(ad,if_info->linkType);
1692             airpcap_if_set_decryption_state(ad, if_info->DecryptionOn);
1693             airpcap_if_save_keys(ad,if_info);
1694
1695             /* ... and save them */
1696             if(!airpcap_if_store_cur_config_as_adapter_default(ad))
1697             {
1698                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save Wireless configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
1699                 if_info->saved = FALSE;
1700                 airpcap_if_close(ad);
1701                 return;
1702             }
1703
1704             if_info->saved = TRUE;
1705             airpcap_if_close(ad);
1706         }
1707         else
1708         {
1709             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",if_info->description);
1710         }
1711     }
1712 }
1713
1714 /*
1715  * Save the configuration for the specified interface
1716  */
1717 void
1718 airpcap_save_driver_if_configuration(airpcap_if_info_t* fake_if_info)
1719 {
1720     gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1721     PAirpcapHandle ad;
1722
1723     if(fake_if_info != NULL)
1724     {
1725         ad = airpcap_if_open(fake_if_info->name, ebuf);
1726
1727         if(ad)
1728         {
1729             /* Apply decryption settings... */
1730             airpcap_if_set_driver_decryption_state(ad, fake_if_info->DecryptionOn);
1731             airpcap_if_save_driver_keys(ad,fake_if_info);
1732             airpcap_if_close(ad);
1733         }
1734         else
1735         {
1736             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",fake_if_info->description);
1737         }
1738     }
1739
1740     return;
1741 }
1742
1743 /*
1744  * DECRYPTION KEYS FUNCTIONS
1745  */
1746 /*
1747  * This function is used for DEBUG POURPOSES ONLY!!!
1748  */
1749 void
1750 print_key_list(GList* key_list)
1751 {
1752     gint n,i;
1753     decryption_key_t* tmp;
1754
1755     if(key_list == NULL)
1756     {
1757         g_print("\n\n******* KEY LIST NULL *******\n\n");
1758         return;
1759     }
1760
1761     n = g_list_length(key_list);
1762
1763     g_print("\n\n********* KEY LIST **********\n\n");
1764
1765     g_print("NUMBER OF KEYS IN LIST : %d\n\n",n);
1766
1767     for(i =0; i < n; i++)
1768     {
1769         g_print("[%d] :\n",i+1);
1770         tmp = (decryption_key_t*)(g_list_nth_data(key_list,i));
1771         g_print("KEY : %s\n",tmp->key->str);
1772
1773         g_print("BITS: %d\n",tmp->bits);
1774
1775         if(tmp->type == AIRPDCAP_KEY_TYPE_WEP)
1776             g_print("TYPE: %s\n",AIRPCAP_WEP_KEY_STRING);
1777         else if(tmp->type == AIRPDCAP_KEY_TYPE_WPA_PWD)
1778             g_print("TYPE: %s\n",AIRPCAP_WPA_PWD_KEY_STRING);
1779         else if(tmp->type == AIRPDCAP_KEY_TYPE_WPA_PMK)
1780             g_print("TYPE: %s\n",AIRPCAP_WPA_BIN_KEY_STRING);
1781         else
1782             g_print("TYPE: %s\n","???");
1783
1784         g_print("SSID: %s\n",(tmp->ssid != NULL) ?
1785                 format_text((guchar *)tmp->ssid->data, tmp->ssid->len) : "---");
1786         g_print("\n");
1787     }
1788
1789     g_print("\n*****************************\n\n");
1790 }
1791
1792 /*
1793  * Retrieves a GList of decryption_key_t structures containing infos about the
1794  * keys for the given adapter... returns NULL if no keys are found.
1795  */
1796 GList*
1797 get_airpcap_device_keys(airpcap_if_info_t* info_if)
1798 {
1799     /* tmp vars */
1800     char* tmp_key = NULL;
1801     guint i,keys_in_list = 0;
1802
1803     /* real vars*/
1804     decryption_key_t *new_key  = NULL;
1805     GList            *key_list = NULL;
1806
1807     /* Number of keys in key list */
1808     if(info_if->keysCollectionSize != 0)
1809         keys_in_list = (guint)(info_if->keysCollectionSize -  sizeof(AirpcapKeysCollection))/sizeof(AirpcapKey);
1810     else
1811         keys_in_list = 0;
1812
1813     for(i=0; i<keys_in_list; i++)
1814     {
1815         /* Different things to do depending on the key type  */
1816         if(info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP)
1817         {
1818             /* allocate memory for the new key item */
1819             new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1820
1821             /* fill the fields */
1822             /* KEY */
1823             tmp_key = airpcap_get_key_string(info_if->keysCollection->Keys[i]);
1824             new_key->key = g_string_new(tmp_key);
1825             g_free(tmp_key);
1826
1827             /* BITS */
1828             new_key->bits = (guint) new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an hexadecimal number) */
1829
1830             /* SSID not used in WEP keys */
1831             new_key->ssid = NULL;
1832
1833             /* TYPE (WEP in this case) */
1834             new_key->type = info_if->keysCollection->Keys[i].KeyType;
1835
1836             /* Append the new element in the list */
1837             key_list = g_list_append(key_list,(gpointer)new_key);
1838         }
1839         else if(info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD)
1840         {
1841             /* XXX - Not supported yet */
1842         }
1843         else if(info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK)
1844         {
1845             /* XXX - Not supported yet */
1846         }
1847     }
1848
1849     return key_list;
1850 }
1851
1852 /*
1853  * Retrieves a GList of decryption_key_t structures containing infos about the
1854  * keys for the global AirPcap driver... returns NULL if no keys are found.
1855  */
1856 GList*
1857 get_airpcap_driver_keys(void)
1858 {
1859     /* tmp vars */
1860     char* tmp_key = NULL;
1861     guint i,keys_in_list = 0;
1862
1863     /* real vars*/
1864     decryption_key_t *new_key  = NULL;
1865     GList            *key_list = NULL;
1866
1867     /*
1868      * To read the drivers general settings we need to create and use one airpcap adapter...
1869      * The only way to do that is to instantiate a fake adapter, and then close it and delete it.
1870      */
1871     airpcap_if_info_t* fake_info_if = NULL;
1872
1873     /* Create the fake_info_if from the first adapter of the list */
1874     fake_info_if = airpcap_driver_fake_if_info_new();
1875
1876     if(fake_info_if == NULL)
1877         return NULL;
1878
1879     /* Number of keys in key list */
1880     if(fake_info_if->keysCollectionSize != 0)
1881         keys_in_list = (guint)(fake_info_if->keysCollectionSize -  sizeof(AirpcapKeysCollection))/sizeof(AirpcapKey);
1882     else
1883         keys_in_list = 0;
1884
1885     for(i=0; i<keys_in_list; i++)
1886     {
1887         /* Different things to do depending on the key type  */
1888         if(fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP)
1889         {
1890             /* allocate memory for the new key item */
1891             new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1892
1893             /* fill the fields */
1894             /* KEY */
1895             tmp_key = airpcap_get_key_string(fake_info_if->keysCollection->Keys[i]);
1896             new_key->key = g_string_new(tmp_key);
1897             if(tmp_key != NULL) g_free(tmp_key);
1898
1899             /* BITS */
1900             new_key->bits = (guint) new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an hexadecimal number) */
1901
1902             /* SSID not used in WEP keys */
1903             new_key->ssid = NULL;
1904
1905             /* TYPE (WEP in this case) */
1906             new_key->type = fake_info_if->keysCollection->Keys[i].KeyType;
1907
1908             /* Append the new element in the list */
1909             key_list = g_list_append(key_list,(gpointer)new_key);
1910         }
1911         else if(fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD)
1912         {
1913             /* XXX - Not supported yet */
1914         }
1915         else if(fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK)
1916         {
1917             /* XXX - Not supported yet */
1918         }
1919     }
1920
1921     airpcap_if_info_free(fake_info_if);
1922
1923     return key_list;
1924 }
1925
1926 /*
1927  * Returns the list of the decryption keys specified for wireshark, NULL if
1928  * no key is found
1929  */
1930 GList*
1931 get_wireshark_keys(void)
1932 {
1933     keys_cb_data_t* wep_user_data = NULL;
1934
1935     GList* final_list = NULL;
1936     GList* wep_final_list = NULL;
1937
1938     /* Retrieve the wlan preferences */
1939     wlan_prefs = prefs_find_module("wlan");
1940
1941     /* Allocate a structure used to keep infos  between the callbacks */
1942     wep_user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
1943
1944     /* Fill the structure */
1945     wep_user_data->list = NULL;
1946     wep_user_data->current_index = 0;
1947     wep_user_data->number_of_keys= 0; /* Still unknown */
1948
1949     /* Run the callback on each 802.11 preference */
1950     /* XXX - Right now, only WEP keys will be loaded */
1951     prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)wep_user_data);
1952
1953     /* Copy the list field in the user data structure pointer into the final_list */
1954     if(wep_user_data != NULL)  wep_final_list  = wep_user_data->list;
1955
1956     /* XXX - Merge the three lists!!!!! */
1957     final_list = wep_final_list;
1958
1959     /* free the wep_user_data structure */
1960     g_free(wep_user_data);
1961
1962     return final_list;
1963 }
1964
1965 /*
1966  * Merges two lists of keys and return a newly created GList. If a key is
1967  * found multiple times, it will just appear once!
1968  * list1 and list 2 pointer will have to be freed manually if needed!!!
1969  * If the total number of keys exceeeds the maximum number allowed,
1970  * exceeding keys will be discarded...
1971  */
1972 GList*
1973 merge_key_list(GList* list1, GList* list2)
1974 {
1975     guint n1=0,n2=0;
1976     guint i;
1977     decryption_key_t *dk1=NULL,
1978                       *dk2=NULL,
1979                       *new_dk=NULL;
1980
1981     GList* merged_list = NULL;
1982
1983     if( (list1 == NULL) && (list2 == NULL) )
1984         return NULL;
1985
1986     if(list1 == NULL)
1987     {
1988         n1 = 0;
1989         n2 = g_list_length(list2);
1990
1991         for(i=0;i<n2;i++)
1992         {
1993             new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1994             dk2 = (decryption_key_t *)g_list_nth_data(list2,i);
1995
1996             new_dk->bits = dk2->bits;
1997             new_dk->type = dk2->type;
1998             new_dk->key  = g_string_new(dk2->key->str);
1999             new_dk->ssid = byte_array_dup(dk2->ssid);
2000
2001             /* Check the total length of the merged list */
2002             if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)
2003                 merged_list = g_list_append(merged_list,(gpointer)new_dk);
2004         }
2005     }
2006     else if(list2 == NULL)
2007     {
2008         n1 = g_list_length(list1);
2009         n2 = 0;
2010
2011         for(i=0;i<n1;i++)
2012         {
2013             new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
2014             dk1 = (decryption_key_t*)g_list_nth_data(list1,i);
2015
2016             new_dk->bits = dk1->bits;
2017             new_dk->type = dk1->type;
2018             new_dk->key  = g_string_new(dk1->key->str);
2019             new_dk->ssid = byte_array_dup(dk1->ssid);
2020
2021             /* Check the total length of the merged list */
2022             if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)
2023                 merged_list = g_list_append(merged_list,(gpointer)new_dk);
2024         }
2025     }
2026     else
2027     {
2028         n1 = g_list_length(list1);
2029         n2 = g_list_length(list2);
2030
2031         /* Copy the whole list1 into merged_list */
2032         for(i=0;i<n1;i++)
2033         {
2034             new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
2035             dk1 = (decryption_key_t *)g_list_nth_data(list1,i);
2036
2037             new_dk->bits = dk1->bits;
2038             new_dk->type = dk1->type;
2039             new_dk->key  = g_string_new(dk1->key->str);
2040             new_dk->ssid = byte_array_dup(dk1->ssid);
2041
2042             /* Check the total length of the merged list */
2043             if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)
2044                 merged_list = g_list_append(merged_list,(gpointer)new_dk);
2045         }
2046
2047         /* Look for keys that are present in list2 but aren't in list1 yet...
2048          * Add them to merged_list
2049          */
2050         for(i=0;i<n2;i++)
2051         {
2052             dk2 = (decryption_key_t *)g_list_nth_data(list2,i);
2053
2054             if(!key_is_in_list(dk2,merged_list))
2055             {
2056                 new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
2057
2058                 new_dk->bits = dk2->bits;
2059                 new_dk->type = dk2->type;
2060                 new_dk->key  = g_string_new(dk2->key->str);
2061                 new_dk->ssid = byte_array_dup(dk2->ssid);
2062
2063                 /* Check the total length of the merged list */
2064                 if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)
2065                     merged_list = g_list_append(merged_list,(gpointer)new_dk);
2066             }
2067         }
2068     }
2069
2070     return merged_list;
2071 }
2072
2073 /*
2074  * Use this function to free a key list.
2075  */
2076 void
2077 free_key_list(GList *list)
2078 {
2079     guint i,n;
2080     decryption_key_t *curr_key;
2081
2082     if(list == NULL)
2083         return;
2084
2085     n = g_list_length(list);
2086
2087     for(i = 0; i < n; i++)
2088     {
2089         curr_key = (decryption_key_t*)g_list_nth_data(list,i);
2090
2091         /* Free all the strings */
2092         if(curr_key->key != NULL)
2093             g_string_free(curr_key->key, TRUE);
2094
2095         if(curr_key->ssid != NULL)
2096         g_byte_array_free(curr_key->ssid, TRUE);
2097
2098         /* free the decryption_key_t structure*/
2099         g_free(curr_key);
2100         curr_key = NULL;
2101     }
2102
2103     /* Free the list */
2104     g_list_free(list);
2105
2106     return;
2107 }
2108
2109
2110 /*
2111  * If the given key is contained in the list, returns TRUE.
2112  * Returns FALSE otherwise.
2113  */
2114 gboolean
2115 key_is_in_list(decryption_key_t *dk,GList *list)
2116 {
2117     guint i,n;
2118     decryption_key_t* curr_key = NULL;
2119     gboolean found = FALSE;
2120
2121     if( (list == NULL) || (dk == NULL) )
2122         return FALSE;
2123
2124     n = g_list_length(list);
2125
2126     if(n < 1)
2127         return FALSE;
2128
2129     for(i = 0; i < n; i++)
2130     {
2131         curr_key = (decryption_key_t*)g_list_nth_data(list,i);
2132         if(keys_are_equals(dk,curr_key))
2133             found = TRUE;
2134     }
2135
2136     return found;
2137 }
2138
2139 /*
2140  * Returns TRUE if keys are equals, FALSE otherwise
2141  */
2142 gboolean
2143 keys_are_equals(decryption_key_t *k1,decryption_key_t *k2)
2144 {
2145
2146     if((k1==NULL) || (k2==NULL))
2147         return FALSE;
2148
2149     /* XXX - Remove this check when we will have the WPA/WPA2 decryption in the Driver! */
2150     /** if( (k1->type == AIRPDCAP_KEY_TYPE_WPA_PWD) || (k2->type == AIRPDCAP_KEY_TYPE_WPA_PWD) || (k1->type == AIRPDCAP_KEY_TYPE_WPA_PMK) || (k2->type == AIRPDCAP_KEY_TYPE_WPA_PMK) ) **/
2151     /**         return TRUE;  **/
2152
2153     if( g_string_equal(k1->key,k2->key) &&
2154         (k1->bits == k2->bits) && /* If the previous is TRUE, this must be TRUE as well */
2155         k1->type == k2->type)
2156     {
2157         /* Check the ssid... if the key type is WEP, the two fields should be NULL */
2158         if((k1->ssid == NULL) && (k2->ssid == NULL))
2159             return TRUE;
2160
2161         /* If they are not null, they must share the same ssid */
2162         return byte_array_equal(k1->ssid,k2->ssid);
2163     }
2164
2165     /* Some field is not equal ... */
2166     return FALSE;
2167 }
2168
2169 /*
2170  * Tests if two collection of keys are equal or not, to be considered equals, they have to
2171  * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will
2172  * return TRUE)
2173  */
2174 gboolean
2175 key_lists_are_equal(GList* list1, GList* list2)
2176 {
2177     guint n1=0,n2=0;
2178     /* XXX - Remove */
2179     guint wep_n1=0,wep_n2=0;
2180     GList *wep_list1=NULL;
2181     GList *wep_list2=NULL;
2182     /* XXX - END*/
2183     guint i/*,j*/;
2184     decryption_key_t *dk1=NULL,*dk2=NULL;
2185
2186     n1 = g_list_length(list1);
2187     n2 = g_list_length(list2);
2188
2189     /*
2190      * XXX - START : Retrieve the aublists of WEP keys!!! This is needed only 'till Driver WPA decryption
2191      * is implemented.
2192      */
2193     for(i=0;i<n1;i++)
2194     {
2195         dk1=(decryption_key_t*)g_list_nth_data(list1,i);
2196         if(dk1->type == AIRPDCAP_KEY_TYPE_WEP)
2197         {
2198             wep_list1 = g_list_append(wep_list1,(gpointer)dk1);
2199             wep_n1++;
2200         }
2201     }
2202     for(i=0;i<n2;i++)
2203     {
2204         dk2=(decryption_key_t*)g_list_nth_data(list2,i);
2205         if(dk2->type == AIRPDCAP_KEY_TYPE_WEP)
2206         {
2207             wep_list2 = g_list_append(wep_list2,(gpointer)dk2);
2208             wep_n2++;
2209         }
2210     }
2211
2212     /*
2213      * XXX - END : Remove from START to END when the WPA/WPA2 decryption will be implemented in
2214      * the Driver
2215      */
2216
2217     /*
2218      * Commented, because in the new AirPcap version all the keys will be saved
2219      * into the driver, and all the keys for every specific adapter will be
2220      * removed. This means that this check will always fail... and the user will
2221      * always be asked what to do... and it doesn't make much sense.
2222      */
2223     /* if(n1 != n2) return FALSE; */
2224     if(wep_n1 != wep_n2) return FALSE;
2225
2226     n1 = wep_n1;
2227     n2 = wep_n2;
2228
2229     /*for(i=0;i<n1;i++)
2230     {
2231     dk1=(decryption_key_t*)g_list_nth_data(list1,i);
2232     dk2=(decryption_key_t*)g_list_nth_data(list2,i);
2233
2234     if(!g_string_equal(dk1->key,dk2->key)) return FALSE;
2235     }*/
2236     for(i=0;i<n2;i++)
2237     {
2238         dk2=(decryption_key_t*)g_list_nth_data(wep_list2,i);
2239         if(!key_is_in_list(dk2,wep_list1)) return FALSE;
2240     }
2241
2242     return TRUE;
2243 }
2244
2245 static guint
2246 test_if_on(pref_t *pref, gpointer ud)
2247 {
2248     gboolean *is_on;
2249     gboolean number;
2250
2251     /* Retrieve user data info */
2252     is_on = (gboolean*)ud;
2253
2254
2255     if (g_ascii_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL)
2256     {
2257         number = *pref->varp.boolp;
2258
2259         if(number) *is_on = TRUE;
2260         else *is_on = FALSE;
2261
2262         return 1;
2263     }
2264     return 0;
2265 }
2266
2267 /*
2268  * Returns TRUE if the Wireshark decryption is active, false otherwise
2269  * XXX - Should we just add a routine to packet-ieee80211.c to grab this directly?
2270  */
2271 gboolean
2272 wireshark_decryption_on(void)
2273 {
2274     gboolean is_on;
2275
2276     /* Retrieve the wlan preferences */
2277     wlan_prefs = prefs_find_module("wlan");
2278
2279     /* Run the callback on each 802.11 preference */
2280     prefs_pref_foreach(wlan_prefs, test_if_on, (gpointer)&is_on);
2281
2282     return is_on;
2283 }
2284
2285 /*
2286  * Returns TRUE if the AirPcap decryption for the current adapter is active, false otherwise
2287  */
2288 gboolean
2289 airpcap_decryption_on(void)
2290 {
2291     gboolean is_on = FALSE;
2292
2293     airpcap_if_info_t* fake_if_info = NULL;
2294
2295     fake_if_info = airpcap_driver_fake_if_info_new();
2296
2297     if(fake_if_info != NULL)
2298     {
2299         if(fake_if_info->DecryptionOn == AIRPCAP_DECRYPTION_ON)
2300             is_on = TRUE;
2301         else if(fake_if_info->DecryptionOn == AIRPCAP_DECRYPTION_OFF)
2302             is_on = FALSE;
2303     }
2304
2305     airpcap_if_info_free(fake_if_info);
2306
2307     return is_on;
2308 }
2309
2310 /*
2311  * Free an instance of airpcap_if_info_t
2312  */
2313 void
2314 airpcap_if_info_free(airpcap_if_info_t *if_info)
2315 {
2316     if(if_info != NULL)
2317     {
2318         if (if_info->name != NULL)
2319             g_free(if_info->name);
2320
2321         if (if_info->description != NULL)
2322             g_free(if_info->description);
2323
2324         if(if_info->keysCollection != NULL)
2325         {
2326             g_free(if_info->keysCollection);
2327             if_info->keysCollection = NULL;
2328         }
2329
2330         if(if_info->ip_addr != NULL)
2331         {
2332             g_slist_free(if_info->ip_addr);
2333             if_info->ip_addr = NULL;
2334         }
2335
2336         if(if_info != NULL)
2337         {
2338             g_free(if_info);
2339             if_info = NULL;
2340         }
2341     }
2342 }
2343
2344 static guint
2345 set_on_off(pref_t *pref, gpointer ud)
2346 {
2347     gboolean *is_on;
2348     gboolean number;
2349
2350     /* Retrieve user data info */
2351     is_on = (gboolean*)ud;
2352
2353     if (g_ascii_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL)
2354     {
2355         number = *pref->varp.boolp;
2356
2357         if(*is_on)
2358             *pref->varp.boolp = TRUE;
2359         else
2360             *pref->varp.boolp = FALSE;
2361
2362         return 1;
2363     }
2364     return 0;
2365 }
2366
2367 /*
2368  * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise.
2369  */
2370 void
2371 set_wireshark_decryption(gboolean on_off)
2372 {
2373     gboolean is_on;
2374
2375     is_on = on_off;
2376
2377     /* Retrieve the wlan preferences */
2378     wlan_prefs = prefs_find_module("wlan");
2379
2380     /* Run the callback on each 802.11 preference */
2381     prefs_pref_foreach(wlan_prefs, set_on_off, (gpointer)&is_on);
2382
2383     /*
2384      * Signal that we've changed things, and run the 802.11 dissector's
2385      * callback
2386      */
2387     wlan_prefs->prefs_changed = TRUE;
2388
2389     prefs_apply(wlan_prefs);
2390 }
2391
2392 /*
2393  * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise.
2394  */
2395 gboolean
2396 set_airpcap_decryption(gboolean on_off)
2397 {
2398     /* We need to directly access the .dll functions here... */
2399     gchar ebuf[AIRPCAP_ERRBUF_SIZE];
2400     PAirpcapHandle ad,ad_driver;
2401
2402     gboolean success = TRUE;
2403
2404     gint n = 0;
2405     gint i = 0;
2406     airpcap_if_info_t* curr_if = NULL;
2407     airpcap_if_info_t* fake_if_info = NULL;
2408
2409     fake_if_info = airpcap_driver_fake_if_info_new();
2410
2411     if(fake_if_info == NULL)
2412         /* We apparently don't have any adapters installed.
2413          * This isn't a failure, so return TRUE
2414          */
2415         return TRUE;
2416
2417         /* Set the driver decryption */
2418         ad_driver = airpcap_if_open(fake_if_info->name, ebuf);
2419         if(ad_driver)
2420         {
2421             if(on_off)
2422                 airpcap_if_set_driver_decryption_state(ad_driver,AIRPCAP_DECRYPTION_ON);
2423             else
2424                 airpcap_if_set_driver_decryption_state(ad_driver,AIRPCAP_DECRYPTION_OFF);
2425
2426             airpcap_if_close(ad_driver);
2427         }
2428
2429         airpcap_if_info_free(fake_if_info);
2430
2431         n = g_list_length(airpcap_if_list);
2432
2433         /* Set to FALSE the decryption for all the adapters */
2434         /* Apply this change to all the adapters !!! */
2435         for(i = 0; i < n; i++)
2436         {
2437             curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
2438
2439             if( curr_if != NULL )
2440             {
2441                 ad = airpcap_if_open(curr_if->name, ebuf);
2442                 if(ad)
2443                 {
2444                     curr_if->DecryptionOn = (gboolean)AIRPCAP_DECRYPTION_OFF;
2445                     airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
2446                     /* Save configuration for the curr_if */
2447                     if(!airpcap_if_store_cur_config_as_adapter_default(ad))
2448                     {
2449                         success = FALSE;
2450                     }
2451                     airpcap_if_close(ad);
2452                 }
2453             }
2454         }
2455
2456         return success;
2457 }
2458
2459
2460 /* DYNAMIC LIBRARY LOADER */
2461 /*
2462  *  Used to dynamically load the airpcap library in order link it only when
2463  *  it's present on the system
2464  */
2465 int load_airpcap(void)
2466 {
2467 #ifdef _WIN32
2468     gboolean base_functions = TRUE;
2469     gboolean eleven_n_functions = TRUE;
2470
2471     if((AirpcapLib = ws_load_library("airpcap.dll")) == NULL)
2472     {
2473                 /* Report the error but go on */
2474                 AirpcapVersion = AIRPCAP_DLL_NOT_FOUND;
2475                 return AirpcapVersion;
2476     }
2477     else
2478     {
2479                 if((g_PAirpcapGetLastError = (AirpcapGetLastErrorHandler) GetProcAddress(AirpcapLib, "AirpcapGetLastError")) == NULL) base_functions = FALSE;
2480                 if((g_PAirpcapGetDeviceList = (AirpcapGetDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceList")) == NULL) base_functions = FALSE;
2481                 if((g_PAirpcapFreeDeviceList = (AirpcapFreeDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapFreeDeviceList")) == NULL) base_functions = FALSE;
2482                 if((g_PAirpcapOpen = (AirpcapOpenHandler) GetProcAddress(AirpcapLib, "AirpcapOpen")) == NULL) base_functions = FALSE;
2483                 if((g_PAirpcapClose = (AirpcapCloseHandler) GetProcAddress(AirpcapLib, "AirpcapClose")) == NULL) base_functions = FALSE;
2484                 if((g_PAirpcapGetLinkType = (AirpcapGetLinkTypeHandler) GetProcAddress(AirpcapLib, "AirpcapGetLinkType")) == NULL) base_functions = FALSE;
2485                 if((g_PAirpcapSetLinkType = (AirpcapSetLinkTypeHandler) GetProcAddress(AirpcapLib, "AirpcapSetLinkType")) == NULL) base_functions = FALSE;
2486                 if((g_PAirpcapSetKernelBuffer = (AirpcapSetKernelBufferHandler) GetProcAddress(AirpcapLib, "AirpcapSetKernelBuffer")) == NULL) base_functions = FALSE;
2487                 if((g_PAirpcapSetFilter = (AirpcapSetFilterHandler) GetProcAddress(AirpcapLib, "AirpcapSetFilter")) == NULL) base_functions = FALSE;
2488                 if((g_PAirpcapGetMacAddress = (AirpcapGetMacAddressHandler) GetProcAddress(AirpcapLib, "AirpcapGetMacAddress")) == NULL) base_functions = FALSE;
2489                 if((g_PAirpcapSetMinToCopy = (AirpcapSetMinToCopyHandler) GetProcAddress(AirpcapLib, "AirpcapSetMinToCopy")) == NULL) base_functions = FALSE;
2490                 if((g_PAirpcapGetReadEvent = (AirpcapGetReadEventHandler) GetProcAddress(AirpcapLib, "AirpcapGetReadEvent")) == NULL) base_functions = FALSE;
2491                 if((g_PAirpcapRead = (AirpcapReadHandler) GetProcAddress(AirpcapLib, "AirpcapRead")) == NULL) base_functions = FALSE;
2492                 if((g_PAirpcapGetStats = (AirpcapGetStatsHandler) GetProcAddress(AirpcapLib, "AirpcapGetStats")) == NULL) base_functions = FALSE;
2493                 if((g_PAirpcapTurnLedOn = (AirpcapTurnLedOnHandler) GetProcAddress(AirpcapLib, "AirpcapTurnLedOn")) == NULL) base_functions = FALSE;
2494                 if((g_PAirpcapTurnLedOff = (AirpcapTurnLedOffHandler) GetProcAddress(AirpcapLib, "AirpcapTurnLedOff")) == NULL) base_functions = FALSE;
2495                 if((g_PAirpcapGetDeviceChannel = (AirpcapGetDeviceChannelHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceChannel")) == NULL) base_functions = FALSE;
2496                 if((g_PAirpcapSetDeviceChannel = (AirpcapSetDeviceChannelHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceChannel")) == NULL) base_functions = FALSE;
2497                 if((g_PAirpcapGetFcsPresence = (AirpcapGetFcsPresenceHandler) GetProcAddress(AirpcapLib, "AirpcapGetFcsPresence")) == NULL) base_functions = FALSE;
2498                 if((g_PAirpcapSetFcsPresence = (AirpcapSetFcsPresenceHandler) GetProcAddress(AirpcapLib, "AirpcapSetFcsPresence")) == NULL) base_functions = FALSE;
2499                 if((g_PAirpcapGetFcsValidation = (AirpcapGetFcsValidationHandler) GetProcAddress(AirpcapLib, "AirpcapGetFcsValidation")) == NULL) base_functions = FALSE;
2500                 if((g_PAirpcapSetFcsValidation = (AirpcapSetFcsValidationHandler) GetProcAddress(AirpcapLib, "AirpcapSetFcsValidation")) == NULL) base_functions = FALSE;
2501                 if((g_PAirpcapGetDeviceKeys = (AirpcapGetDeviceKeysHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceKeys")) == NULL) base_functions = FALSE;
2502                 if((g_PAirpcapSetDeviceKeys = (AirpcapSetDeviceKeysHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceKeys")) == NULL) base_functions = FALSE;
2503                 if((g_PAirpcapGetDecryptionState = (AirpcapGetDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapGetDecryptionState")) == NULL) base_functions = FALSE;
2504                 if((g_PAirpcapSetDecryptionState = (AirpcapSetDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapSetDecryptionState")) == NULL) base_functions = FALSE;
2505                 if((g_PAirpcapStoreCurConfigAsAdapterDefault = (AirpcapStoreCurConfigAsAdapterDefaultHandler) GetProcAddress(AirpcapLib, "AirpcapStoreCurConfigAsAdapterDefault")) == NULL) base_functions = FALSE;
2506                 if((g_PAirpcapGetVersion = (AirpcapGetVersionHandler) GetProcAddress(AirpcapLib, "AirpcapGetVersion")) == NULL) base_functions = FALSE;
2507                 if((g_PAirpcapGetDriverDecryptionState = (AirpcapGetDriverDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapGetDriverDecryptionState")) == NULL) base_functions = FALSE;
2508                 if((g_PAirpcapSetDriverDecryptionState = (AirpcapSetDriverDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapSetDriverDecryptionState")) == NULL) base_functions = FALSE;
2509                 if((g_PAirpcapGetDriverKeys = (AirpcapGetDriverKeysHandler) GetProcAddress(AirpcapLib, "AirpcapGetDriverKeys")) == NULL) base_functions = FALSE;
2510                 if((g_PAirpcapSetDriverKeys = (AirpcapSetDriverKeysHandler) GetProcAddress(AirpcapLib, "AirpcapSetDriverKeys")) == NULL) base_functions = FALSE;
2511
2512                 /* TEST IF AIRPCAP SUPPORTS 11N */
2513                 if((g_PAirpcapSetDeviceChannelEx = (AirpcapSetDeviceChannelExHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceChannelEx")) == NULL) eleven_n_functions = FALSE;
2514                 if((g_PAirpcapGetDeviceChannelEx = (AirpcapGetDeviceChannelExHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceChannelEx")) == NULL) eleven_n_functions = FALSE;
2515                 if((g_PAirpcapGetDeviceSupportedChannels = (AirpcapGetDeviceSupportedChannelsHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceSupportedChannels")) == NULL) eleven_n_functions = FALSE;
2516
2517                 if(base_functions && eleven_n_functions){
2518                         AirpcapLoaded = TRUE;
2519                         AirpcapVersion = AIRPCAP_DLL_OK;
2520                 }else if(base_functions){
2521                         AirpcapLoaded = TRUE;
2522                         AirpcapVersion = AIRPCAP_DLL_OLD;
2523                         return AIRPCAP_DLL_OK;
2524                 }else{
2525                         AirpcapLoaded = FALSE;
2526                         AirpcapVersion = AIRPCAP_DLL_ERROR;
2527                 }
2528     }
2529     return AirpcapVersion;
2530 #else /* _WIN32 */
2531     return AIRPCAP_DLL_NOT_FOUND;
2532 #endif /* _WIN32 */
2533 }
2534
2535 /*
2536  * Append the version of AirPcap with which we were compiled to a GString.
2537  */
2538 void
2539 get_compiled_airpcap_version(GString *str)
2540 {
2541     g_string_append(str, "with AirPcap");
2542 }
2543
2544 /*
2545  * Append the version of AirPcap with which we we're running to a GString.
2546  */
2547 void
2548 get_runtime_airpcap_version(GString *str)
2549 {
2550     guint vmaj, vmin, vrev, build;
2551
2552     /* See if the DLL has been loaded successfully.  Bail if it hasn't */
2553     if (AirpcapLoaded == FALSE) {
2554         g_string_append(str, "without AirPcap");
2555         return;
2556     }
2557
2558     g_PAirpcapGetVersion(&vmaj, &vmin, &vrev, &build);
2559     g_string_append_printf(str, "with AirPcap %d.%d.%d build %d", vmaj, vmin,
2560         vrev, build);
2561 }
2562 #endif /* HAVE_AIRPCAP */