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