From Stephen Fisher
[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 _WIN32
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
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 "capture_ui_utils.h"
46
47 #include "simple_dialog.h"
48
49 #include <airpcap.h>
50 #include "airpcap_loader.h"
51
52 /*
53  * We load dinamically the dag library in order link it only when
54  * it's present on the system
55  */
56 static HMODULE AirpcapLib = NULL;
57
58 static AirpcapGetLastErrorHandler g_PAirpcapGetLastError;
59 static AirpcapGetDeviceListHandler g_PAirpcapGetDeviceList;
60 static AirpcapFreeDeviceListHandler g_PAirpcapFreeDeviceList;
61 static AirpcapOpenHandler g_PAirpcapOpen;
62 static AirpcapCloseHandler g_PAirpcapClose;
63 static AirpcapGetLinkTypeHandler g_PAirpcapGetLinkType;
64 static AirpcapSetLinkTypeHandler g_PAirpcapSetLinkType;
65 static AirpcapSetKernelBufferHandler g_PAirpcapSetKernelBuffer;
66 static AirpcapSetFilterHandler g_PAirpcapSetFilter;
67 static AirpcapGetMacAddressHandler g_PAirpcapGetMacAddress;
68 static AirpcapSetMinToCopyHandler g_PAirpcapSetMinToCopy;
69 static AirpcapGetReadEventHandler g_PAirpcapGetReadEvent;
70 static AirpcapReadHandler g_PAirpcapRead;
71 static AirpcapGetStatsHandler g_PAirpcapGetStats;
72 static AirpcapTurnLedOnHandler g_PAirpcapTurnLedOn;
73 static AirpcapTurnLedOffHandler g_PAirpcapTurnLedOff;
74 static AirpcapGetDeviceChannelHandler g_PAirpcapGetDeviceChannel;
75 static AirpcapSetDeviceChannelHandler g_PAirpcapSetDeviceChannel;
76 static AirpcapGetFcsPresenceHandler g_PAirpcapGetFcsPresence;
77 static AirpcapSetFcsPresenceHandler g_PAirpcapSetFcsPresence;
78 static AirpcapGetFcsValidationHandler g_PAirpcapGetFcsValidation;
79 static AirpcapSetFcsValidationHandler g_PAirpcapSetFcsValidation;
80 static AirpcapGetDeviceKeysHandler g_PAirpcapGetDeviceKeys;
81 static AirpcapSetDeviceKeysHandler g_PAirpcapSetDeviceKeys;
82 static AirpcapGetDecryptionStateHandler g_PAirpcapGetDecryptionState;
83 static AirpcapSetDecryptionStateHandler g_PAirpcapSetDecryptionState;
84 static AirpcapStoreCurConfigAsAdapterDefaultHandler g_PAirpcapStoreCurConfigAsAdapterDefault;
85 static AirpcapGetVersionHandler g_PAirpcapGetVersion;
86
87 /* Airpcap interface list */
88 GList *airpcap_if_list = NULL;
89
90 /* Airpcap current selected interface */
91 airpcap_if_info_t *airpcap_if_selected = NULL;
92
93 /* Airpcap current active interface */
94 airpcap_if_info_t *airpcap_if_active = NULL;
95
96 /* WLAN preferences pointer */
97 module_t *wlan_prefs = NULL;
98
99 /* Callback used by the load_wlan_keys() routine in order to read a WEP decryption key */
100 static guint
101 get_wep_key(pref_t *pref, gpointer ud _U_)
102 {
103 gchar *my_string = NULL;
104 keys_cb_data_t* user_data;
105
106 decryption_key_t* new_key;
107
108 /* Retrieve user data info */
109 user_data = (keys_cb_data_t*)ud; 
110
111 if (g_strncasecmp(pref->name, "wep_key", 7) == 0 && pref->type == PREF_STRING)
112     {
113     my_string = g_strdup(*pref->varp.string);
114     
115     if( my_string != NULL)
116         {
117         /* Key is added only if not null ... */
118         if( (g_strcasecmp(my_string,"") != 0) && (wep_key_is_valid(my_string)))
119             {
120             new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
121             
122             new_key->key = g_string_new(my_string);
123             g_free(my_string);
124             
125             new_key->bits = new_key->key->len * 4;
126             
127             new_key->type = AIRPCAP_KEYTYPE_WEP;
128             
129             new_key->ssid = NULL;
130             
131             user_data->list = g_list_append(user_data->list,new_key);
132             user_data->number_of_keys++;
133             user_data->current_index++;
134             }
135         }
136     }
137 return 0;
138 }
139
140 /* Callback used by the load_wlan_keys() routine in order to read a WPA decryption key */
141 static guint
142 get_wpa_key(pref_t *pref, gpointer ud _U_)
143 {
144 return 1;
145 }
146
147 /* Callback used by the load_wlan_keys() routine in order to read a WPA2 decryption key */
148 static guint
149 get_wpa2_key(pref_t *pref, gpointer ud _U_)
150 {
151 return 1;
152 }
153
154 /* Returs TRUE if the WEP key is valid, false otherwise */
155 gboolean
156 wep_key_is_valid(char* key)
157 {
158 GString *new_key_string;
159 gint i=0;
160
161 if(key == NULL)
162         return FALSE;
163
164 new_key_string = g_string_new(key);
165
166 if( ((new_key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((new_key_string->len) < 2))
167         {
168         g_string_free(new_key_string,FALSE);
169         return FALSE;
170         }
171 if((new_key_string->len % 2) != 0)
172         {
173         g_string_free(new_key_string,FALSE);
174         return FALSE;
175         }
176 for(i = 0; i < new_key_string->len; i++)
177         {
178         if(!g_ascii_isxdigit(new_key_string->str[i]))
179                 {
180                 g_string_free(new_key_string,FALSE);
181                 return FALSE;
182                 }
183         }
184
185 g_string_free(new_key_string,FALSE);
186 return TRUE;
187 }
188
189 /* Callback used by the save_wlan_keys() routine in order to write a decryption key */
190 static guint
191 set_wep_key(pref_t *pref, gpointer ud _U_)
192 {
193 gchar *my_string = NULL;
194 keys_cb_data_t* user_data;
195 gint wep_key_number = 0;
196
197 /* Retrieve user data info */
198 user_data = (keys_cb_data_t*)ud; 
199
200 if (g_strncasecmp(pref->name, "wep_key", 7) == 0 && pref->type == PREF_STRING)
201     {
202     /* Ok, the pref we're gonna set is a wep_key ... but what number? */
203     sscanf(pref->name,"wep_key%d",&wep_key_number);
204     
205     if(user_data->current_index < user_data->number_of_keys)
206         {
207         if(wep_key_number == (user_data->current_index+1))
208             {
209             my_string = g_strdup((char*)g_list_nth_data(user_data->list,user_data->current_index));
210             
211                         g_free((void *)*pref->varp.string);
212                         *pref->varp.string = (void *)g_strdup(my_string);  
213                           
214             g_free(my_string);
215             }
216         }
217     else /* If the number of keys has been reduced somehow, we need to delete all the other keys 
218           * (remember that the new ones have been probably overwritten)
219           */
220         {
221         g_free((void *)*pref->varp.string);
222         *pref->varp.string = (void *)g_strdup("");  /* Do not just free memory!!! Put an 'empty' string! */
223         }
224     user_data->current_index++;
225     }
226
227 return 0;
228 }
229
230 /*
231  * Function used to read the Decryption Keys from the preferences and store them
232  * properly into the airpcap adapter.
233  */
234 BOOL
235 load_wlan_wep_keys(airpcap_if_info_t* info_if)
236 {
237 keys_cb_data_t* user_data;
238 guint i;
239 gchar *tmp = NULL;
240                                       
241 if(info_if == NULL) return FALSE;
242
243 /* Retrieve the wlan preferences */
244 wlan_prefs = prefs_find_module("wlan");
245
246 /* Allocate a structure used to keep infos  between the callbacks */
247 user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
248
249 /* Fill the structure */
250 user_data->list = NULL;
251 user_data->current_index = 0;
252 user_data->number_of_keys= 0; /* Still unknown */
253
254 /* Run the callback on each 802.11 preference */
255 prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)user_data);
256
257 /* Now the key list should be filled */
258
259 /* 
260  * Signal that we've changed things, and run the 802.11 dissector's
261  * callback 
262  */
263 wlan_prefs->prefs_changed = TRUE;
264
265 prefs_apply(wlan_prefs);
266
267 write_wlan_wep_keys_to_regitry(info_if,user_data->list);
268
269 /* FREE MEMORY */
270 /* free the WEP key string */
271 for(i=0;i<g_list_length(user_data->list);i++)
272     {
273     g_free(g_list_nth(user_data->list,i)->data);
274     }
275
276 /* free the (empty) list */
277 g_list_free(user_data->list);
278
279 /* free the user_data structure */
280 g_free(user_data);
281
282 return TRUE;
283 }
284
285 /*
286  * This function will tell the airpcap driver the key list to use
287  * This will be stored into the registry...
288  */
289 BOOL
290 write_wlan_wep_keys_to_regitry(airpcap_if_info_t* info_if, GList* key_list)
291 {
292 UINT i,j;
293 GString *new_key;
294 gchar s[3];
295 PAirpcapKeysCollection KeysCollection;
296 ULONG KeysCollectionSize;
297 UCHAR KeyByte; 
298 UINT keys_in_list = 0;
299 decryption_key_t* key_item = NULL;
300
301 keys_in_list = g_list_length(key_list);
302
303 /*
304  * Save the encryption keys, if we have any of them
305  */
306 KeysCollectionSize = 0;
307
308 /*
309  * Calculate the size of the keys collection
310  */
311 KeysCollectionSize = sizeof(AirpcapKeysCollection) + keys_in_list * sizeof(AirpcapKey);
312
313 /*
314  * Allocate the collection
315  */
316 KeysCollection = (PAirpcapKeysCollection)malloc(KeysCollectionSize);
317 if(!KeysCollection)
318 {
319         return FALSE;
320 }
321
322 /*
323  * Populate the key collection
324  */
325 KeysCollection->nKeys = keys_in_list;
326
327 for(i = 0; i < keys_in_list; i++)
328 {
329     KeysCollection->Keys[i].KeyType = AIRPCAP_KEYTYPE_WEP;
330
331         /* Retrieve the Item corresponding to the i-th key */
332         key_item = (decryption_key_t*)g_list_nth_data(key_list,i);
333         new_key = g_string_new(key_item->key->str);
334         
335         KeysCollection->Keys[i].KeyLen = new_key->len / 2;
336         memset(&KeysCollection->Keys[i].KeyData, 0, sizeof(KeysCollection->Keys[i].KeyData));
337
338         for(j = 0 ; j < new_key->len; j += 2)
339         {
340                 s[0] = new_key->str[j];
341                 s[1] = new_key->str[j+1];
342                 s[2] = '\0';
343                 KeyByte = (UCHAR)strtol(s, NULL, 16);
344                 KeysCollection->Keys[i].KeyData[j / 2] = KeyByte;
345         }
346         
347         g_string_free(new_key,TRUE);    
348 }
349
350 /*
351  * Free the old adapter key collection!
352  */
353 if(info_if->keysCollection != NULL)
354         g_free(info_if->keysCollection);
355
356 /*
357  * Set this collection ad the new one
358  */
359 info_if->keysCollection = KeysCollection;
360 info_if->keysCollectionSize = KeysCollectionSize;
361
362 /*
363  * Configuration must be saved
364  */
365 info_if->saved = FALSE;
366
367 /*
368  * Write down the changes to the registry
369  */
370 airpcap_save_selected_if_configuration(info_if);
371
372 return TRUE;
373 }
374
375 /* 
376  *  Function used to save to the preference file the Decryption Keys.
377  */
378 gboolean
379 save_wlan_wep_keys(airpcap_if_info_t* info_if)
380 {
381 GList* key_list = NULL;
382 char* tmp_key = NULL;
383 guint keys_in_list,i;
384 keys_cb_data_t* user_data;
385                                       
386 if(info_if == NULL) return FALSE;
387
388 /* Retrieve the wlan preferences */
389 wlan_prefs = prefs_find_module("wlan");
390
391 /* Allocate a structure used to keep infos  between the callbacks */
392 user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
393
394 /* Number of keys in key list */
395 keys_in_list = (info_if->keysCollectionSize -  sizeof(AirpcapKeysCollection))/sizeof(AirpcapKey);
396
397 for(i=0; i<keys_in_list; i++)
398 {
399 /* Only if it is a WEP key... */
400 if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_WEP)
401     {
402     tmp_key = airpcap_get_key_string(info_if->keysCollection->Keys[i]);   
403     key_list = g_list_append(key_list,g_strdup(tmp_key));    
404     g_free(tmp_key);
405     }
406 }
407
408 /* Now we know the exact number of WEP keys in the list, so store it ... */
409 keys_in_list = g_list_length(key_list);
410
411 /* Fill the structure */
412 user_data->list = key_list;
413 user_data->current_index = 0;
414 user_data->number_of_keys= keys_in_list; 
415
416 /* Retrieve the wlan preferences */
417 wlan_prefs = prefs_find_module("wlan");
418
419 /* Run the callback on each 802.11 preference */
420 prefs_pref_foreach(wlan_prefs, set_wep_key,  (gpointer)user_data);
421
422 /* Signal that we've changed things, and run the 802.11 dissector's
423  * callback */
424 wlan_prefs->prefs_changed = TRUE;
425
426 /* Apply changes for the specified preference */
427 prefs_apply(wlan_prefs);
428
429 /* FREE MEMORY */
430 /* free the WEP key string */
431 for(i=0;i<g_list_length(user_data->list);i++)
432     {
433     g_free(g_list_nth(user_data->list,i)->data);
434     }
435
436 /* free the (empty) list */
437 g_list_free(user_data->list);
438
439 /* free the user_data structure */
440 g_free(user_data);
441
442 return TRUE;
443 }
444
445 /*
446  * Get an error message string for a CANT_GET_INTERFACE_LIST error from
447  * "get_airpcap_interface_list()".
448  */
449 gchar *
450 cant_get_airpcap_if_list_error_message(const char *err_str)
451 {
452         return g_strdup_printf("Can't get list of Wireless interfaces: %s", err_str);
453 }
454
455 /*
456  * Airpcap wrapper, used to store the current settings for the selected adapter
457  */
458 BOOL
459 airpcap_if_store_cur_config_as_adapter_default(PAirpcapHandle ah)
460 {
461         return g_PAirpcapStoreCurConfigAsAdapterDefault(ah);
462 }
463
464 /*
465  * Airpcap wrapper, used to open an airpcap adapter
466  */
467 PAirpcapHandle
468 airpcap_if_open(PCHAR name, PCHAR err)
469 {
470         return g_PAirpcapOpen(name,err);
471 }
472
473 /*
474  * Airpcap wrapper, used to close an airpcap adapter
475  */
476 VOID
477 airpcap_if_close(PAirpcapHandle handle)
478 {
479 g_PAirpcapClose(handle);
480
481 }
482
483 /*
484  * Airpcap wrapper, used to turn on the led of an airpcap adapter
485  */
486 BOOL
487 airpcap_if_turn_led_on(PAirpcapHandle AdapterHandle, UINT LedNumber)
488 {
489         return g_PAirpcapTurnLedOn(AdapterHandle,LedNumber);
490 }
491
492 /*
493  * Airpcap wrapper, used to turn off the led of an airpcap adapter
494  */
495 BOOL
496 airpcap_if_turn_led_off(PAirpcapHandle AdapterHandle, UINT LedNumber)
497 {
498         return g_PAirpcapTurnLedOff(AdapterHandle,LedNumber);
499 }
500
501 /*
502  * Airpcap wrapper, used to get the channel of an airpcap adapter
503  */
504 BOOL
505 airpcap_if_get_device_channel(PAirpcapHandle ah, PUINT ch)
506 {
507         return g_PAirpcapGetDeviceChannel(ah,ch);
508 }
509
510 /*
511  * Airpcap wrapper, used to set the channel of an airpcap adapter
512  */
513 BOOL
514 airpcap_if_set_device_channel(PAirpcapHandle ah, UINT ch)
515 {
516         return g_PAirpcapSetDeviceChannel(ah,ch);
517 }
518
519 /*
520  * Airpcap wrapper, used to get the link type of an airpcap adapter
521  */
522 BOOL
523 airpcap_if_get_link_type(PAirpcapHandle ah, PAirpcapLinkType lt)
524 {
525         return g_PAirpcapGetLinkType(ah,lt);
526 }
527
528 /*
529  * Airpcap wrapper, used to set the link type of an airpcap adapter
530  */
531 BOOL
532 airpcap_if_set_link_type(PAirpcapHandle ah, AirpcapLinkType lt)
533 {
534         return g_PAirpcapSetLinkType(ah,lt);
535 }
536
537 /*
538  * Airpcap wrapper, used to get the fcs presence of an airpcap adapter
539  */
540 BOOL
541 airpcap_if_get_fcs_presence(PAirpcapHandle ah, PBOOL fcs)
542 {
543         return g_PAirpcapGetFcsPresence(ah,fcs);
544 }
545
546 /*
547  * Airpcap wrapper, used to set the fcs presence of an airpcap adapter
548  */
549 BOOL
550 airpcap_if_set_fcs_presence(PAirpcapHandle ah, BOOL fcs)
551 {
552         return g_PAirpcapSetFcsPresence(ah,fcs);
553 }
554
555 /*
556  * Airpcap wrapper, used to get the decryption enabling of an airpcap adapter
557  */
558 BOOL
559 airpcap_if_get_decryption_state(PAirpcapHandle ah, PAirpcapDecryptionState PEnable)
560 {
561         return g_PAirpcapGetDecryptionState(ah,PEnable);
562 }
563
564 /*
565  * Airpcap wrapper, used to set the decryption enabling of an airpcap adapter
566  */
567 BOOL
568 airpcap_if_set_decryption_state(PAirpcapHandle ah, AirpcapDecryptionState Enable)
569 {
570         return g_PAirpcapSetDecryptionState(ah,Enable);
571 }
572
573 /*
574  * Airpcap wrapper, used to get the fcs validation of an airpcap adapter
575  */
576 BOOL
577 airpcap_if_get_fcs_validation(PAirpcapHandle ah, PAirpcapValidationType val)
578 {
579         return g_PAirpcapGetFcsValidation(ah,val);
580 }
581
582 /*
583  * Airpcap wrapper, used to set the fcs validation of an airpcap adapter
584  */
585 BOOL
586 airpcap_if_set_fcs_validation(PAirpcapHandle ah, AirpcapValidationType val)
587 {
588         return g_PAirpcapSetFcsValidation(ah,val);
589 }
590
591 /*
592  * Airpcap wrapper, used to save the settings for the selected_if
593  */
594 BOOL
595 airpcap_if_set_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection)
596 {
597         return g_PAirpcapSetDeviceKeys(AdapterHandle,KeysCollection);
598 }
599
600 /*
601  * Airpcap wrapper, used to save the settings for the selected_if
602  */
603 BOOL
604 airpcap_if_get_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, PUINT PKeysCollectionSize)
605 {   
606         return g_PAirpcapGetDeviceKeys(AdapterHandle,KeysCollection,PKeysCollectionSize);
607 }
608
609 /*
610  * This function will create a new airpcap_if_info_t using a name and a description
611  */
612 airpcap_if_info_t *
613 airpcap_if_info_new(char *name, char *description)
614 {
615 PAirpcapHandle ad;
616 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
617
618         airpcap_if_info_t *if_info;
619
620         if_info = g_malloc(sizeof (airpcap_if_info_t));
621         if_info->name = g_strdup(name);
622         if (description == NULL)
623                 if_info->description = NULL;
624         else
625                 if_info->description = g_strdup(description);
626         if_info->ip_addr = NULL;
627         if_info->loopback = FALSE;
628         
629         /* Probably I have to switch on the leds!!! */
630         ad = airpcap_if_open(if_info->name, ebuf);
631         if(ad)
632                 {
633                 airpcap_if_get_fcs_validation(ad,&(if_info->CrcValidationOn));
634                 airpcap_if_get_fcs_presence(ad,&(if_info->IsFcsPresent));
635                 airpcap_if_get_link_type(ad,&(if_info->linkType));
636                 airpcap_if_get_device_channel(ad,&(if_info->channel));
637                 airpcap_if_turn_led_on(ad, 0);
638                 airpcap_if_get_decryption_state(ad, &(if_info->DecryptionOn));
639                 if_info->led = TRUE;
640                 if_info->blinking = FALSE;
641                 if_info->saved = TRUE; /* NO NEED TO BE SAVED */
642
643                 /* get the keys, if everything is ok, close the adapter */
644                 if(airpcap_if_load_keys(ad,if_info))
645                         airpcap_if_close(ad);
646                 }
647         return if_info;
648 }
649
650 /*
651  * Function used to load the WEP keys for a selected interface
652  */
653 BOOL
654 airpcap_if_load_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info)
655 {
656 if_info->keysCollectionSize = 0;
657 if_info->keysCollection = NULL;
658
659 if(!airpcap_if_get_device_keys(ad, NULL, &(if_info->keysCollectionSize)))
660         {
661         if(if_info->keysCollectionSize == 0)
662                 {
663                 if_info->keysCollection = NULL;
664                 airpcap_if_close(ad);
665                 return FALSE;
666                 }
667
668         if_info->keysCollection = (PAirpcapKeysCollection)malloc(if_info->keysCollectionSize);
669         if(!if_info->keysCollection)
670                 {
671                 if_info->keysCollectionSize = 0;
672                 if_info->keysCollection = NULL;
673                 airpcap_if_close(ad);
674                 return FALSE;
675                 }
676
677         airpcap_if_get_device_keys(ad, if_info->keysCollection, &(if_info->keysCollectionSize));
678         return TRUE;
679         }
680 airpcap_if_close(ad);
681 return FALSE;
682 }
683
684 /*
685  * Function used to save the WEP keys for a selected interface
686  */
687 void
688 airpcap_if_save_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info)
689 {
690         if(if_info->keysCollection != NULL)
691                 g_PAirpcapSetDeviceKeys(ad,if_info->keysCollection);
692 }
693
694 /*
695  * Callback used to free an instance of airpcap_if_info_t
696  */
697 static void
698 free_airpcap_if_cb(gpointer data, gpointer user_data _U_)
699 {
700         airpcap_if_info_t *if_info = data;
701
702         if (if_info->name != NULL)
703                 g_free(if_info->name);
704
705         if (if_info->description != NULL)
706                 g_free(if_info->description);
707
708         /* XXX - FREE THE WEP KEY LIST HERE!!!*/
709         if(if_info->keysCollection != NULL)
710                 g_free(if_info->keysCollection);
711
712         if(if_info->ip_addr != NULL)
713                 g_slist_free(if_info->ip_addr);
714
715         if(if_info != NULL)
716                 g_free(if_info);
717 }
718
719 /*
720  * Function used to free the airpcap interface list
721  */
722 void
723 free_airpcap_interface_list(GList *if_list)
724 {
725         g_list_foreach(if_list, free_airpcap_if_cb, NULL);
726         g_list_free(if_list);
727         if_list = NULL;
728 }
729
730 /*
731  * This function will use the airpcap.dll to find all the airpcap devices.
732  * Will return null if no device is found.
733  */
734 GList*
735 get_airpcap_interface_list(int *err, char *err_str)
736 {
737         GList  *il = NULL;
738         airpcap_if_info_t *if_info;
739         int i, n_adapts;
740     AirpcapDeviceDescription *devsList, *adListEntry;
741
742         if(!g_PAirpcapGetDeviceList(&devsList, err_str))
743         {
744                 /* No interfaces, return il = NULL; */
745                 *err = NO_AIRPCAP_INTERFACES_FOUND;
746                 return il;
747         }
748
749         /*
750          * Count the adapters
751          */
752         adListEntry = devsList;
753         n_adapts = 0;
754         while(adListEntry)
755         {
756                 n_adapts++;
757                 adListEntry = adListEntry->next;
758         }
759
760         if(n_adapts == 0)
761         {
762                 /* No interfaces, return il= NULL */
763                 g_PAirpcapFreeDeviceList(devsList);
764                 *err = NO_AIRPCAP_INTERFACES_FOUND;
765                 return il;
766         }
767
768         /*
769          * Insert the adapters in our list
770          */
771         adListEntry = devsList;
772         for(i = 0; i < n_adapts; i++)
773         {
774                 if_info = airpcap_if_info_new(adListEntry->Name, adListEntry->Description);
775         il = g_list_append(il, if_info);
776
777                 adListEntry = adListEntry->next;
778         }
779
780         g_PAirpcapFreeDeviceList(devsList);
781
782         return il;
783 }
784
785 /*
786  * Used to retrieve the name of the interface given the description
787  * (the name is used in AirpcapOpen, the description is put in the combo box)
788  */
789 gchar* get_airpcap_name_from_description(GList* if_list, gchar* description)
790 {
791 unsigned int ifn;
792 GList* curr;
793 airpcap_if_info_t* if_info;
794
795 ifn = 0;
796 if(if_list != NULL)
797         {
798         while( ifn < g_list_length(if_list) )
799                 {
800                 curr = g_list_nth(if_list, ifn);
801
802                 if_info = NULL;
803                 if(curr != NULL)
804                         if_info = curr->data;
805                 if(if_info != NULL)
806                         if ( g_ascii_strcasecmp(if_info->description,description) == 0)
807                                 {
808                                 return if_info->name;
809                                 }
810                 ifn++;
811                 }
812         }
813 return NULL;
814 }
815
816 /*
817  * Used to retrieve the interface given the name
818  * (the name is used in AirpcapOpen)
819  */
820 airpcap_if_info_t* get_airpcap_if_by_name(GList* if_list, const gchar* name)
821 {
822 unsigned int ifn;
823 GList* curr;
824 airpcap_if_info_t* if_info;
825
826 ifn = 0;
827 if(if_list != NULL)
828         {
829         while( ifn < g_list_length(if_list) )
830                 {
831                 curr = g_list_nth(if_list, ifn);
832
833                 if_info = NULL;
834                 if(curr != NULL)
835                         if_info = curr->data;
836                 if(if_info != NULL)
837                         if ( g_ascii_strcasecmp(if_info->name,name) == 0)
838                                 {
839                                 return if_info;
840                                 }
841                 ifn++;
842                 }
843         }
844 return NULL;
845 }
846
847 /*
848  * Returns the ASCII string of a key given the key bytes
849  */
850 gchar*
851 airpcap_get_key_string(AirpcapKey key)
852 {
853 unsigned int j = 0;
854 unsigned int l = 0;
855 gchar *dst,*src;
856
857 src = NULL;
858
859 if(key.KeyType == AIRPCAP_KEYTYPE_WEP)
860         {
861         if(key.KeyLen != 0)
862             {
863         /* Allocate the string used to store the ASCII representation of the WEP key */
864         dst = (gchar*)g_malloc(sizeof(gchar)*WEP_KEY_MAX_CHAR_SIZE + 1);
865         /* Make sure that the first char is '\0' in order to make g_strlcat() work */
866         dst[0]='\0';
867         
868             for(j = 0; j < key.KeyLen; j++)
869                     {
870                     src = g_strdup_printf("%.2x\0", key.KeyData[j]);
871                     /*
872              * XXX - use g_strconcat() instead ??? 
873              */         
874                 l = g_strlcat(dst,src,WEP_KEY_MAX_CHAR_SIZE+1);
875                 }
876         g_free(src);
877         }
878         }
879 else if(key.KeyType == AIRPCAP_KEYTYPE_TKIP)
880     {
881     /* XXX - Add code here */
882     }
883 else if(key.KeyType == AIRPCAP_KEYTYPE_CCMP)
884     {
885     /* XXX - Add code here */
886     }
887 else
888     {
889     /* XXX - Add code here */
890     }
891
892 return dst;
893 }
894
895 /*
896  * Used to retrieve the airpcap_if_info_t of the selected interface given the
897  * description (that is the entry of the combo box).
898  */
899 gpointer get_airpcap_if_from_description(GList* if_list, const gchar* description)
900 {
901 unsigned int ifn;
902 GList* curr;
903 airpcap_if_info_t* if_info;
904
905 ifn = 0;
906 if(if_list != NULL)
907         {
908         while( ifn < g_list_length(if_list) )
909                 {
910                 curr = g_list_nth(if_list, ifn);
911
912                 if_info = NULL;
913                 if(curr != NULL)
914                         if_info = curr->data;
915                 if(if_info != NULL)
916                         if ( g_ascii_strcasecmp(if_info->description,description) == 0)
917                                 {
918                                 return if_info;
919                                 }
920                 ifn++;
921                 }
922         }
923 return NULL;
924 }
925
926 /*
927  * Used to retrieve the two chars string from interface
928  */
929 gchar*
930 airpcap_get_if_string_number(airpcap_if_info_t* if_info)
931 {
932         gchar* number;
933         guint n;
934         int a;
935
936         a = sscanf(if_info->name,AIRPCAP_DEVICE_NUMBER_EXTRACT_STRING,&n);
937     
938     /* If sscanf() returned 1, it means that has read a number, so interface is not "Any"
939      * Otherwise, check if it is the "Any" adapter...
940      */
941      if(a == 0)
942           {
943           if(g_strcasecmp(if_info->name,AIRPCAP_DEVICE_ANY_EXTRACT_STRING)!=0)
944                number = g_strdup_printf("??");
945           else
946                number = g_strdup_printf(AIRPCAP_CHANNEL_ANY_NAME);
947           }
948      else
949           {
950           number = g_strdup_printf("%.2u\0",n);
951           }
952
953         return number;
954 }
955
956 /*
957  * Used to retrieve the two chars string from interface
958  */
959 gchar*
960 airpcap_get_if_string_number_from_description(gchar* description)
961 {
962         gchar* number;
963         gchar* pointer;
964
965         number = (gchar*)g_malloc(sizeof(gchar)*3);
966
967         pointer = g_strrstr(description,"#\0");
968
969         number[0] = *(pointer+1);
970         number[1] = *(pointer+2);
971         number[2] = '\0';
972
973         return number;
974 }
975
976 /*
977  * Returns the default airpcap interface of a list, NULL if list is empty
978  */
979 airpcap_if_info_t*
980 airpcap_get_default_if(GList* airpcap_if_list)
981 {
982 int ifn = 0;
983 GList* popdown_if_list = NULL;
984 GList* curr = NULL;
985
986         gchar* s;
987         airpcap_if_info_t* if_info = NULL;
988
989     if(prefs.capture_device != NULL)
990     {
991         s = g_strdup(get_if_name(prefs.capture_device));
992         if_info = get_airpcap_if_by_name(airpcap_if_list,g_strdup(get_if_name(prefs.capture_device)));
993         g_free(s);
994     }
995         return if_info;
996 }
997
998 /*
999  * Load the configuration for the specified interface
1000  */
1001 void
1002 airpcap_load_selected_if_configuration(airpcap_if_info_t* if_info)
1003 {
1004 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1005 PAirpcapHandle ad;
1006
1007 if(if_info != NULL)
1008         {
1009         ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list, if_info->description), ebuf);
1010
1011         if(ad)
1012                 {
1013                 /* Stop blinking (if it was blinkig!)*/
1014                 if(if_info->blinking)
1015                         {
1016                         /* Turn on the light (if it was off) */
1017                         if(!(if_info->led)) airpcap_if_turn_led_on(ad, 0);
1018                         }
1019
1020                 /* Apply settings... */
1021                 airpcap_if_get_device_channel(ad,&(if_info->channel));
1022                 airpcap_if_get_fcs_validation(ad,&(if_info->CrcValidationOn));
1023                 airpcap_if_get_fcs_presence(ad,&(if_info->IsFcsPresent));
1024                 airpcap_if_get_link_type(ad,&(if_info->linkType));
1025                 airpcap_if_get_decryption_state(ad, &(if_info->DecryptionOn));
1026                 /* get the keys, if everything is ok, close the adapter */
1027                 if(airpcap_if_load_keys(ad,if_info))
1028                         airpcap_if_close(ad);
1029
1030                 if_info->saved = TRUE;
1031                 }
1032         else
1033                 {
1034                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",if_info->description);
1035                 }
1036         }
1037 }
1038
1039 /*
1040  * Save the configuration for the specified interface
1041  */
1042 void
1043 airpcap_save_selected_if_configuration(airpcap_if_info_t* if_info)
1044 {
1045 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1046 PAirpcapHandle ad;
1047
1048 if(if_info != NULL)
1049         {
1050         ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list, if_info->description), ebuf);
1051
1052         if(ad)
1053                 {
1054                 /* Stop blinking (if it was blinkig!)*/
1055                 if(if_info->blinking)
1056                         {
1057                         /* Turn on the light (if it was off) */
1058                         if(!(if_info->led)) airpcap_if_turn_led_on(ad, 0);
1059                         }
1060
1061                 /* Apply settings... */
1062                 airpcap_if_set_device_channel(ad,if_info->channel);
1063                 airpcap_if_set_fcs_validation(ad,if_info->CrcValidationOn);
1064                 airpcap_if_set_fcs_presence(ad,if_info->IsFcsPresent);
1065                 airpcap_if_set_link_type(ad,if_info->linkType);
1066                 airpcap_if_set_decryption_state(ad, if_info->DecryptionOn);
1067                 airpcap_if_save_keys(ad,if_info);
1068
1069                 /* ... and save them */
1070                 if(!airpcap_if_store_cur_config_as_adapter_default(ad))
1071                         {
1072                         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.");
1073                         if_info->saved = FALSE;
1074                         airpcap_if_close(ad);
1075                         return;
1076                         }
1077
1078                 if_info->saved = TRUE;
1079                 airpcap_if_close(ad);
1080                 }
1081         else
1082                 {
1083                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",if_info->description);
1084                 }
1085         }
1086 }
1087
1088 /*
1089  * DECRYPTION KEYS FUNCTIONS
1090  */
1091 /*
1092  * This function is used for DEBUG POURPOSES ONLY!!!
1093  */
1094 void
1095 print_key_list(GList* key_list)
1096 {
1097 gint n,i;
1098 decryption_key_t* tmp;
1099                       
1100 n = g_list_length(key_list);
1101
1102 g_print("\n\n********* KEY LIST **********\n\n");
1103
1104 g_print("NUMBER OF KEYS IN LIST : %d\n\n",n);
1105
1106 for(i =0; i < n; i++)
1107 {
1108 g_print("[%d] :\n",i+1);
1109 tmp = (decryption_key_t*)(g_list_nth_data(key_list,i));
1110 g_print("KEY : %s\n",tmp->key->str);
1111
1112 g_print("BITS: %d\n",tmp->bits);
1113
1114 if(tmp->type == AIRPCAP_KEYTYPE_WEP)
1115     g_print("TYPE: %s\n",AIRPCAP_WEP_KEY_STRING);
1116 else if(tmp->type == AIRPCAP_KEYTYPE_TKIP)
1117     g_print("TYPE: %s\n",AIRPCAP_WPA_KEY_STRING);
1118 else if(tmp->type == AIRPCAP_KEYTYPE_CCMP)
1119     g_print("TYPE: %s\n",AIRPCAP_WPA2_KEY_STRING);
1120 else 
1121     g_print("TYPE: %s\n","???");
1122
1123 g_print("SSID: %s\n",(tmp->ssid != NULL) ? tmp->ssid->str : "---");
1124 g_print("\n");
1125 }
1126
1127 g_print("\n*****************************\n\n");
1128 }
1129
1130 /*
1131  * Retrieves a GList of decryption_key_t structures containing infos about the
1132  * keys for the given adapter... returns NULL if no keys are found.
1133  */
1134 GList*
1135 get_airpcap_device_keys(airpcap_if_info_t* info_if)
1136 {
1137 /* tmp vars */
1138 char* tmp_key = NULL;
1139 guint i,keys_in_list = 0;
1140
1141 /* real vars*/
1142 decryption_key_t *new_key  = NULL;
1143 GList            *key_list = NULL;
1144             
1145 /* Number of keys in key list */
1146 if(info_if->keysCollectionSize != 0)
1147     keys_in_list = (guint)(info_if->keysCollectionSize -  sizeof(AirpcapKeysCollection))/sizeof(AirpcapKey);
1148 else
1149     keys_in_list = 0;
1150     
1151 for(i=0; i<keys_in_list; i++)
1152 {
1153 /* Different things to do depending on the key type  */
1154 if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_WEP)
1155     {
1156     /* allocate memory for the new key item */
1157     new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1158     
1159     /* fill the fields */
1160     /* KEY */
1161     tmp_key = airpcap_get_key_string(info_if->keysCollection->Keys[i]);
1162     new_key->key = g_string_new(tmp_key);
1163     g_free(tmp_key);
1164     
1165     /* BITS */
1166     new_key->bits = new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an exadecimal number) */
1167     
1168     /* SSID not used in WEP keys */
1169     new_key->ssid = NULL;
1170     
1171     /* TYPE (WEP in this case) */
1172     new_key->type = info_if->keysCollection->Keys[i].KeyType;
1173     
1174     /* Append the new element in the list */
1175     key_list = g_list_append(key_list,(gpointer)new_key);    
1176     }
1177 else if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_TKIP)
1178     {
1179     /* XXX - Not supported yet */
1180     }
1181 else if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_CCMP)
1182     {
1183     /* XXX - Not supported yet */
1184     }
1185 }
1186
1187 return key_list;
1188 }
1189
1190 /*
1191  * Returns the list of the decryption keys specified for wireshark, NULL if
1192  * no key is found 
1193  */
1194 GList*
1195 get_wireshark_keys()
1196 {
1197 keys_cb_data_t* wep_user_data = NULL;
1198 keys_cb_data_t* wpa_user_data = NULL;
1199 keys_cb_data_t* wpa2_user_data= NULL;
1200
1201 gchar *tmp = NULL;
1202
1203 GList* final_list = NULL;
1204 GList* wep_final_list = NULL;
1205 GList* wpa_final_list = NULL;
1206 GList* wpa2_final_list = NULL;
1207                 
1208 /* Retrieve the wlan preferences */
1209 wlan_prefs = prefs_find_module("wlan");
1210
1211 /* Allocate a structure used to keep infos  between the callbacks */
1212 wep_user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
1213
1214 /* Fill the structure */
1215 wep_user_data->list = NULL;
1216 wep_user_data->current_index = 0;
1217 wep_user_data->number_of_keys= 0; /* Still unknown */
1218
1219 /* Run the callback on each 802.11 preference */
1220 /* XXX - Right now, only WEP keys will be loaded */
1221 prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)wep_user_data);
1222 prefs_pref_foreach(wlan_prefs, get_wpa_key, (gpointer)wpa_user_data);
1223 prefs_pref_foreach(wlan_prefs, get_wpa2_key, (gpointer)wpa2_user_data);
1224
1225 /* Copy the list field in the user data structure pointer into the final_list */
1226 if(wep_user_data != NULL)  wep_final_list  = wep_user_data->list;
1227 if(wpa_user_data != NULL)  wpa_final_list  = wpa_user_data->list;
1228 if(wpa2_user_data != NULL) wpa2_final_list = wpa2_user_data->list;
1229
1230 /* XXX - Merge the three lists!!!!! */
1231 final_list = wep_final_list;
1232
1233 /* free the wep_user_data structure */
1234 g_free(wep_user_data);
1235 /* free the wpa_user_data structure */
1236 g_free(wpa_user_data);
1237 /* free the wpa2_user_data structure */
1238 g_free(wpa2_user_data);
1239
1240 return final_list;
1241 }
1242
1243 /*
1244  * Merges two lists of keys and return a newly created GList. If a key is 
1245  * found multiple times, it will just appear once!
1246  * list1 and list 2 pointer will have to be freed manually if needed!!! 
1247  * If the total number of keys exceeeds the maximum number allowed, 
1248  * exceeding keys will be discarded...
1249  */
1250 GList*
1251 merge_key_list(GList* list1, GList* list2)
1252 {
1253 guint n1=0,n2=0;
1254 guint i;
1255 decryption_key_t *dk1=NULL,
1256                  *dk2=NULL, 
1257                  *new_dk=NULL;
1258
1259 GList* merged_list = NULL;
1260
1261 if( (list1 == NULL) && (list2 == NULL) )
1262     return NULL;
1263
1264 if(list1 == NULL)
1265     {
1266     n1 = 0;
1267     n2 = g_list_length(list2);
1268     
1269     for(i=0;i<n2;i++)
1270         {
1271         new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1272         dk2 = (decryption_key_t *)g_list_nth_data(list2,i);
1273         
1274         new_dk->bits = dk2->bits;
1275         new_dk->type = dk2->type;
1276         new_dk->key  = g_string_new(dk2->key->str);
1277         if(dk2->ssid != NULL)
1278             new_dk->ssid = g_string_new(dk2->ssid->str);
1279         else
1280             new_dk->ssid = NULL;
1281
1282                 /* Check the total length of the merged list */
1283                 if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)      
1284                         merged_list = g_list_append(merged_list,(gpointer)new_dk);
1285         }   
1286     }
1287 else if(list2 == NULL)
1288     {
1289     n1 = g_list_length(list1);
1290     n2 = 0;
1291     
1292     for(i=0;i<n1;i++)
1293         {
1294         new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1295         dk1 = (decryption_key_t*)g_list_nth_data(list1,i);
1296         
1297         new_dk->bits = dk1->bits;
1298         new_dk->type = dk1->type;
1299         new_dk->key  = g_string_new(dk1->key->str);
1300         if(dk1->ssid != NULL)
1301             new_dk->ssid = g_string_new(dk1->ssid->str);
1302         else
1303             new_dk->ssid = NULL;
1304         
1305                 /* Check the total length of the merged list */
1306                 if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)      
1307                         merged_list = g_list_append(merged_list,(gpointer)new_dk);
1308         }   
1309     }
1310 else
1311     {
1312     n1 = g_list_length(list1);
1313     n2 = g_list_length(list2);
1314     
1315     /* Copy the whole list1 into merged_list */
1316     for(i=0;i<n1;i++)
1317     {
1318     new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1319     dk1 = (decryption_key_t *)g_list_nth_data(list1,i);
1320     
1321     new_dk->bits = dk1->bits;
1322     new_dk->type = dk1->type;
1323     new_dk->key  = g_string_new(dk1->key->str);
1324     
1325     if(dk1->ssid != NULL)
1326         new_dk->ssid = g_string_new(dk1->ssid->str);
1327     else
1328         new_dk->ssid = NULL;
1329
1330         /* Check the total length of the merged list */
1331         if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)  
1332                 merged_list = g_list_append(merged_list,(gpointer)new_dk);
1333     }   
1334     
1335     /* Look for keys that are present in list2 but aren't in list1 yet...
1336      * Add them to merged_list
1337      */
1338     for(i=0;i<n2;i++)
1339         {
1340         dk2 = (decryption_key_t *)g_list_nth_data(list2,i);
1341         
1342         if(!key_is_in_list(dk2,merged_list))
1343             {
1344             new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1345             
1346             new_dk->bits = dk2->bits;
1347             new_dk->type = dk2->type;
1348             new_dk->key  = g_string_new(dk2->key->str);
1349             if(dk2->ssid != NULL)
1350                 new_dk->ssid = g_string_new(dk2->ssid->str);
1351             else
1352                 new_dk->ssid = NULL;
1353             
1354                         /* Check the total length of the merged list */
1355                         if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)
1356                                 merged_list = g_list_append(merged_list,(gpointer)new_dk);
1357             }        
1358         }
1359     }
1360
1361 return merged_list;
1362 }
1363
1364 /*
1365  * Use this function to free a key list. 
1366  */
1367 void
1368 free_key_list(GList *list)
1369 {
1370 guint i,n;
1371 decryption_key_t *curr_key;
1372
1373 if(list == NULL)
1374     return;
1375     
1376 n = g_list_length(list);
1377
1378 for(i = 0; i < n; i++)
1379 {
1380 curr_key = (decryption_key_t*)g_list_nth_data(list,i);
1381
1382 /* Free all the strings */
1383 if(curr_key->key != NULL)
1384     g_string_free(curr_key->key,TRUE);
1385     
1386 if(curr_key->ssid != NULL)
1387 g_string_free(curr_key->ssid,TRUE);
1388
1389 /* free the decryption_key_t structure*/
1390 g_free(curr_key);
1391 curr_key = NULL;
1392 }
1393
1394 /* Free the list */
1395 g_list_free(list);
1396
1397 return;
1398 }
1399
1400
1401 /*
1402  * If the given key is contained in the list, returns TRUE.
1403  * Returns FALSE otherwise. 
1404  */
1405 gboolean
1406 key_is_in_list(decryption_key_t *dk,GList *list)
1407 {
1408 guint i,n;
1409 decryption_key_t* curr_key = NULL;
1410 gboolean found = FALSE;
1411
1412 if( (list == NULL) || (dk == NULL) )
1413     return FALSE;
1414
1415 n = g_list_length(list);
1416
1417 if(n < 1)
1418     return FALSE;
1419
1420 for(i = 0; i < n; i++)
1421 {
1422 curr_key = (decryption_key_t*)g_list_nth_data(list,i); 
1423 if(keys_are_equals(dk,curr_key))
1424     found = TRUE;  
1425 }     
1426
1427 return found;
1428 }
1429
1430 /*
1431  * Returns TRUE if keys are equals, FALSE otherwise
1432  */
1433 gboolean
1434 keys_are_equals(decryption_key_t *k1,decryption_key_t *k2)
1435 {
1436
1437 if((k1==NULL) || (k2==NULL))
1438     return FALSE;
1439     
1440 if( g_string_equal(k1->key,k2->key) &&
1441     (k1->bits == k2->bits) && /* If the previous is TRUE, this must be TRUE as well */
1442     k1->type == k2->type)
1443     {
1444     /* Check the ssid... if the key type is WEP, the two fields should be NULL */
1445     if((k1->ssid == NULL) && (k2->ssid == NULL))
1446         return TRUE;
1447     
1448     /* Check if one of them is null and one is not... */
1449     if((k1->ssid == NULL) || (k2->ssid == NULL))
1450         return FALSE;
1451         
1452     /* If they are not null, they must share the same ssid */
1453     return g_string_equal(k1->ssid,k2->ssid);
1454     }
1455
1456 /* Some field is not equal ... */
1457 return FALSE;
1458 }
1459
1460 /*
1461  * Tests if two collection of keys are equal or not, to be considered equals, they have to
1462  * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will
1463  * return TRUE)
1464  */
1465 gboolean
1466 key_lists_are_equal(GList* list1, GList* list2)
1467 {
1468 guint n1=0,n2=0;
1469 guint i;
1470 decryption_key_t *dk1=NULL,*dk2=NULL;
1471
1472 n1 = g_list_length(list1);
1473 n2 = g_list_length(list2);
1474
1475 if(n1 != n2) return FALSE;
1476
1477 for(i=0;i<n1;i++)
1478 {
1479 dk1=(decryption_key_t*)g_list_nth_data(list1,i);
1480 dk2=(decryption_key_t*)g_list_nth_data(list2,i);
1481
1482 if(!g_string_equal(dk1->key,dk2->key)) return FALSE;
1483 }
1484
1485 return TRUE;
1486 }
1487
1488 static guint
1489 test_if_on(pref_t *pref, gpointer ud _U_)
1490 {
1491 gboolean *is_on;
1492 gboolean number;
1493
1494 /* Retrieve user data info */
1495 is_on = (gboolean*)ud; 
1496
1497
1498 if (g_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL)
1499     {
1500     number = *pref->varp.boolp;
1501     
1502     if(number) *is_on = TRUE;
1503     else *is_on = FALSE;
1504
1505     return 1;
1506     }
1507 return 0;
1508 }
1509
1510 /*
1511  * Returns TRUE if the Wireshark decryption is active, false otherwise
1512  */
1513 gboolean
1514 wireshark_decryption_on()
1515 {
1516 gboolean is_on;
1517
1518 /* Retrieve the wlan preferences */
1519 wlan_prefs = prefs_find_module("wlan");
1520
1521 /* Run the callback on each 802.11 preference */
1522 prefs_pref_foreach(wlan_prefs, test_if_on, (gpointer)&is_on);
1523
1524 return is_on;
1525 }
1526
1527 /*
1528  * Returns TRUE if the AirPcap decryption is active, false otherwise
1529  */
1530 gboolean
1531 airpcap_decryption_on()
1532 {
1533 gboolean is_on = FALSE;
1534
1535 if(airpcap_if_selected != NULL)
1536     {
1537     is_on = (gboolean)airpcap_if_selected->DecryptionOn;
1538     }
1539  
1540 return is_on;
1541 }
1542
1543 static guint
1544 set_on_off(pref_t *pref, gpointer ud _U_)
1545 {
1546 gboolean *is_on;
1547 gboolean number;
1548
1549 /* Retrieve user data info */
1550 is_on = (gboolean*)ud; 
1551
1552 if (g_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL)
1553     {
1554     number = *pref->varp.boolp;
1555     
1556     g_free((void *)*pref->varp.boolp);
1557     if(*is_on)
1558         *pref->varp.boolp = TRUE; 
1559     else
1560         *pref->varp.boolp = FALSE;
1561         
1562     return 1;
1563     }
1564 return 0;
1565 }
1566
1567 /*
1568  * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise.
1569  */
1570 void
1571 set_wireshark_decryption(gboolean on_off)
1572 {
1573 gboolean is_on;
1574
1575 is_on = on_off;
1576
1577 /* Retrieve the wlan preferences */
1578 wlan_prefs = prefs_find_module("wlan");
1579
1580 /* Run the callback on each 802.11 preference */
1581 prefs_pref_foreach(wlan_prefs, set_on_off, (gpointer)&is_on);
1582
1583 /* 
1584  * Signal that we've changed things, and run the 802.11 dissector's
1585  * callback 
1586  */
1587 wlan_prefs->prefs_changed = TRUE;
1588
1589 prefs_apply(wlan_prefs);
1590 }
1591
1592 /*
1593  * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise.
1594  */
1595 gboolean
1596 set_airpcap_decryption(gboolean on_off)
1597 {
1598 /* We need to directly access the .ddl functions here... */
1599 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
1600 PAirpcapHandle ad;
1601
1602 gboolean success = TRUE;
1603
1604 gint n = 0;
1605 gint i = 0;
1606 airpcap_if_info_t* curr_if = NULL;
1607
1608 n = g_list_length(airpcap_if_list);
1609
1610 /* The same kind of settings should be propagated to all the adapters */
1611 /* Apply this change to all the adapters !!! */
1612 for(i = 0; i < n; i++)
1613     {
1614     curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
1615
1616     if( curr_if != NULL )
1617         {
1618         ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,curr_if->description), ebuf);
1619                 if(ad)
1620             {                                                                                     
1621             curr_if->DecryptionOn = (gboolean)on_off;
1622                 airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
1623                 /* Save configuration for the curr_if */
1624                 if(!airpcap_if_store_cur_config_as_adapter_default(ad))
1625                         {
1626                         success = FALSE;
1627                         }
1628                 airpcap_if_close(ad);
1629             }
1630         }
1631     }
1632
1633 return success;
1634 }
1635
1636
1637 /* DINAMICALLY LIBRARY LOADER */
1638 /*
1639  *  Used to dinamically load the airpcap library in order link it only when
1640  *  it's present on the system
1641  */
1642 BOOL load_airpcap(void)
1643 {
1644  if((AirpcapLib =  LoadLibrary(TEXT("airpcap.dll"))) == NULL)
1645  {
1646   /* Report the error but go on */
1647   return FALSE;
1648  }
1649  else
1650  {
1651   if((g_PAirpcapGetLastError = (AirpcapGetLastErrorHandler) GetProcAddress(AirpcapLib, "AirpcapGetLastError")) == NULL) return FALSE;
1652   if((g_PAirpcapGetDeviceList = (AirpcapGetDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceList")) == NULL) return FALSE;
1653   if((g_PAirpcapFreeDeviceList = (AirpcapFreeDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapFreeDeviceList")) == NULL) return FALSE;
1654   if((g_PAirpcapOpen = (AirpcapOpenHandler) GetProcAddress(AirpcapLib, "AirpcapOpen")) == NULL) return FALSE;
1655   if((g_PAirpcapClose = (AirpcapCloseHandler) GetProcAddress(AirpcapLib, "AirpcapClose")) == NULL) return FALSE;
1656   if((g_PAirpcapGetLinkType = (AirpcapGetLinkTypeHandler) GetProcAddress(AirpcapLib, "AirpcapGetLinkType")) == NULL) return FALSE;
1657   if((g_PAirpcapSetLinkType = (AirpcapSetLinkTypeHandler) GetProcAddress(AirpcapLib, "AirpcapSetLinkType")) == NULL) return FALSE;
1658   if((g_PAirpcapSetKernelBuffer = (AirpcapSetKernelBufferHandler) GetProcAddress(AirpcapLib, "AirpcapSetKernelBuffer")) == NULL) return FALSE;
1659   if((g_PAirpcapSetFilter = (AirpcapSetFilterHandler) GetProcAddress(AirpcapLib, "AirpcapSetFilter")) == NULL) return FALSE;
1660   if((g_PAirpcapGetMacAddress = (AirpcapGetMacAddressHandler) GetProcAddress(AirpcapLib, "AirpcapGetMacAddress")) == NULL) return FALSE;
1661   if((g_PAirpcapSetMinToCopy = (AirpcapSetMinToCopyHandler) GetProcAddress(AirpcapLib, "AirpcapSetMinToCopy")) == NULL) return FALSE;
1662   if((g_PAirpcapGetReadEvent = (AirpcapGetReadEventHandler) GetProcAddress(AirpcapLib, "AirpcapGetReadEvent")) == NULL) return FALSE;
1663   if((g_PAirpcapRead = (AirpcapReadHandler) GetProcAddress(AirpcapLib, "AirpcapRead")) == NULL) return FALSE;
1664   if((g_PAirpcapGetStats = (AirpcapGetStatsHandler) GetProcAddress(AirpcapLib, "AirpcapGetStats")) == NULL) return FALSE;
1665   if((g_PAirpcapTurnLedOn = (AirpcapTurnLedOnHandler) GetProcAddress(AirpcapLib, "AirpcapTurnLedOn")) == NULL) return FALSE;
1666   if((g_PAirpcapTurnLedOff = (AirpcapTurnLedOffHandler) GetProcAddress(AirpcapLib, "AirpcapTurnLedOff")) == NULL) return FALSE;
1667   if((g_PAirpcapGetDeviceChannel = (AirpcapGetDeviceChannelHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceChannel")) == NULL) return FALSE;
1668   if((g_PAirpcapSetDeviceChannel = (AirpcapSetDeviceChannelHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceChannel")) == NULL) return FALSE;
1669   if((g_PAirpcapGetFcsPresence = (AirpcapGetFcsPresenceHandler) GetProcAddress(AirpcapLib, "AirpcapGetFcsPresence")) == NULL) return FALSE;
1670   if((g_PAirpcapSetFcsPresence = (AirpcapSetFcsPresenceHandler) GetProcAddress(AirpcapLib, "AirpcapSetFcsPresence")) == NULL) return FALSE;
1671   if((g_PAirpcapGetFcsValidation = (AirpcapGetFcsValidationHandler) GetProcAddress(AirpcapLib, "AirpcapGetFcsValidation")) == NULL) return FALSE;
1672   if((g_PAirpcapSetFcsValidation = (AirpcapSetFcsValidationHandler) GetProcAddress(AirpcapLib, "AirpcapSetFcsValidation")) == NULL) return FALSE;
1673   if((g_PAirpcapGetDeviceKeys = (AirpcapGetDeviceKeysHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceKeys")) == NULL) return FALSE;
1674   if((g_PAirpcapSetDeviceKeys = (AirpcapSetDeviceKeysHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceKeys")) == NULL) return FALSE;
1675   if((g_PAirpcapGetDecryptionState = (AirpcapGetDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapGetDecryptionState")) == NULL) return FALSE;
1676   if((g_PAirpcapSetDecryptionState = (AirpcapSetDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapSetDecryptionState")) == NULL) return FALSE;
1677   if((g_PAirpcapStoreCurConfigAsAdapterDefault = (AirpcapStoreCurConfigAsAdapterDefaultHandler) GetProcAddress(AirpcapLib, "AirpcapStoreCurConfigAsAdapterDefault")) == NULL) return FALSE;
1678   if((g_PAirpcapGetVersion = (AirpcapGetVersionHandler) GetProcAddress(AirpcapLib, "AirpcapGetVersion")) == NULL) return FALSE;
1679   return TRUE;
1680  }
1681 }
1682
1683 /*
1684  * Append the version of AirPcap with which we were compiled to a GString.
1685  */
1686 void
1687 get_compiled_airpcap_version(GString *str)
1688 {
1689         g_string_append(str, "with AirPcap");
1690 }
1691
1692 /*
1693  * Append the version of AirPcap with which we we're running to a GString.
1694  */
1695 void
1696 get_runtime_airpcap_version(GString *str)
1697 {
1698         guint vmaj, vmin, vrev, build;
1699
1700         /* See if the DLL has been loaded successfully.  Bail if it hasn't */
1701         if (AirpcapLib == NULL || g_PAirpcapGetVersion == NULL) {
1702                 g_string_append(str, "without AirPcap");
1703                 return;
1704         }
1705
1706         g_PAirpcapGetVersion(&vmaj, &vmin, &vrev, &build);
1707         g_string_sprintfa(str, "with AirPcap %d.%d.%d build %d", vmaj, vmin,
1708                 vrev, build);
1709 }
1710
1711 #endif /* _WIN32 */