Add support for:
authorgerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 19 Oct 2006 00:48:03 +0000 (00:48 +0000)
committergerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 19 Oct 2006 00:48:03 +0000 (00:48 +0000)
  - The AirPcap Multi-Channel Aggregator (which is marketspeak for an "any"
    device)
  - Merging the 802.11 dissector WEP key list with AirPcap's
  - Decrypting WEP in the adapter, in Wireshark, or not at all

Update the release notes.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@19599 f5534014-38df-0310-8fa8-9805f1628bb7

airpcap.h
airpcap_loader.c
airpcap_loader.h
docbook/release-notes.xml
gtk/airpcap_dlg.c
gtk/airpcap_dlg.h
gtk/airpcap_gui_utils.c
gtk/airpcap_gui_utils.h
gtk/keys.h
gtk/main.c
gtk/prefs_dlg.c

index 0c21955c86d5f4a730a3312862e1ea170b8ed41e..39bdf2fa480850c798f0ef1b812cc8bdb874457c 100644 (file)
--- a/airpcap.h
+++ b/airpcap.h
@@ -87,7 +87,7 @@ typedef struct _AirpcapDeviceDescription
 
 #define WEP_KEY_MAX_SIZE 32            /* Maximum size of a WEP key, in bytes. This is the size of an entry in the */
                                                                /* AirpcapWepKeysCollection structure */
-
+                                                               
 #ifndef __MINGW32__
 #pragma pack(push)
 #pragma pack(1)
index d65b06904ba1b5e1c642c908edf55d9cd489b72b..93395382ef39e9e631387be53cf22619567865c0 100644 (file)
 #include <pcap.h>
 #endif
 
-#include "capture_ui_utils.h"
+#include <epan/packet.h>
 #include <epan/prefs.h>
+#include <epan/prefs-int.h>
+#include "capture_ui_utils.h"
 
 #include "simple_dialog.h"
 
@@ -90,6 +92,355 @@ airpcap_if_info_t *airpcap_if_selected = NULL;
 /* Airpcap current active interface */
 airpcap_if_info_t *airpcap_if_active = NULL;
 
+/* WLAN preferences pointer */
+module_t *wlan_prefs = NULL;
+
+/* Callback used by the load_wlan_keys() routine in order to read a WEP decryption key */
+static guint
+get_wep_key(pref_t *pref, gpointer ud _U_)
+{
+gchar *my_string = NULL;
+keys_cb_data_t* user_data;
+
+decryption_key_t* new_key;
+
+/* Retrieve user data info */
+user_data = (keys_cb_data_t*)ud; 
+
+if (g_strncasecmp(pref->name, "wep_key", 7) == 0 && pref->type == PREF_STRING)
+    {
+    my_string = g_strdup(*pref->varp.string);
+    
+    if( my_string != NULL)
+        {
+        /* Key is added only if not null ... */
+        if( (g_strcasecmp(my_string,"") != 0) && (wep_key_is_valid(my_string)))
+            {
+            new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
+            
+            new_key->key = g_string_new(my_string);
+            g_free(my_string);
+            
+            new_key->bits = new_key->key->len * 4;
+            
+            new_key->type = AIRPCAP_KEYTYPE_WEP;
+            
+            new_key->ssid = NULL;
+            
+            user_data->list = g_list_append(user_data->list,new_key);
+            user_data->number_of_keys++;
+            user_data->current_index++;
+            }
+        }
+    }
+return 0;
+}
+
+/* Callback used by the load_wlan_keys() routine in order to read a WPA decryption key */
+static guint
+get_wpa_key(pref_t *pref, gpointer ud _U_)
+{
+return 1;
+}
+
+/* Callback used by the load_wlan_keys() routine in order to read a WPA2 decryption key */
+static guint
+get_wpa2_key(pref_t *pref, gpointer ud _U_)
+{
+return 1;
+}
+
+/* Returs TRUE if the WEP key is valid, false otherwise */
+gboolean
+wep_key_is_valid(char* key)
+{
+GString *new_key_string;
+gint i=0;
+
+if(key == NULL)
+       return FALSE;
+
+new_key_string = g_string_new(key);
+
+if( ((new_key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((new_key_string->len) < 2))
+       {
+       g_string_free(new_key_string,FALSE);
+       return FALSE;
+       }
+if((new_key_string->len % 2) != 0)
+       {
+       g_string_free(new_key_string,FALSE);
+       return FALSE;
+       }
+for(i = 0; i < new_key_string->len; i++)
+       {
+       if(!g_ascii_isxdigit(new_key_string->str[i]))
+               {
+               g_string_free(new_key_string,FALSE);
+               return FALSE;
+               }
+       }
+
+g_string_free(new_key_string,FALSE);
+return TRUE;
+}
+
+/* Callback used by the save_wlan_keys() routine in order to write a decryption key */
+static guint
+set_wep_key(pref_t *pref, gpointer ud _U_)
+{
+gchar *my_string = NULL;
+keys_cb_data_t* user_data;
+gint wep_key_number = 0;
+
+/* Retrieve user data info */
+user_data = (keys_cb_data_t*)ud; 
+
+if (g_strncasecmp(pref->name, "wep_key", 7) == 0 && pref->type == PREF_STRING)
+    {
+    /* Ok, the pref we're gonna set is a wep_key ... but what number? */
+    sscanf(pref->name,"wep_key%d",&wep_key_number);
+    
+    if(user_data->current_index < user_data->number_of_keys)
+        {
+        if(wep_key_number == (user_data->current_index+1))
+            {
+            my_string = g_strdup((char*)g_list_nth_data(user_data->list,user_data->current_index));
+            
+                       g_free((void *)*pref->varp.string);
+                       *pref->varp.string = (void *)g_strdup(my_string);  
+                          
+            g_free(my_string);
+            }
+        }
+    else /* If the number of keys has been reduced somehow, we need to delete all the other keys 
+          * (remember that the new ones have been probably overwritten)
+          */
+        {
+        g_free((void *)*pref->varp.string);
+        *pref->varp.string = (void *)g_strdup("");  /* Do not just free memory!!! Put an 'empty' string! */
+        }
+    user_data->current_index++;
+    }
+
+return 0;
+}
+
+/*
+ * Function used to read the Decryption Keys from the preferences and store them
+ * properly into the airpcap adapter.
+ */
+BOOL
+load_wlan_wep_keys(airpcap_if_info_t* info_if)
+{
+keys_cb_data_t* user_data;
+guint i;
+gchar *tmp = NULL;
+                                      
+if(info_if == NULL) return FALSE;
+
+/* Retrieve the wlan preferences */
+wlan_prefs = prefs_find_module("wlan");
+
+/* Allocate a structure used to keep infos  between the callbacks */
+user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
+
+/* Fill the structure */
+user_data->list = NULL;
+user_data->current_index = 0;
+user_data->number_of_keys= 0; /* Still unknown */
+
+/* Run the callback on each 802.11 preference */
+prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)user_data);
+
+/* Now the key list should be filled */
+
+/* 
+ * Signal that we've changed things, and run the 802.11 dissector's
+ * callback 
+ */
+wlan_prefs->prefs_changed = TRUE;
+
+prefs_apply(wlan_prefs);
+
+write_wlan_wep_keys_to_regitry(info_if,user_data->list);
+
+/* FREE MEMORY */
+/* free the WEP key string */
+for(i=0;i<g_list_length(user_data->list);i++)
+    {
+    g_free(g_list_nth(user_data->list,i)->data);
+    }
+
+/* free the (empty) list */
+g_list_free(user_data->list);
+
+/* free the user_data structure */
+g_free(user_data);
+
+return TRUE;
+}
+
+/*
+ * This function will tell the airpcap driver the key list to use
+ * This will be stored into the registry...
+ */
+BOOL
+write_wlan_wep_keys_to_regitry(airpcap_if_info_t* info_if, GList* key_list)
+{
+UINT i,j;
+GString *new_key;
+gchar s[3];
+PAirpcapKeysCollection KeysCollection;
+ULONG KeysCollectionSize;
+UCHAR KeyByte; 
+UINT keys_in_list = 0;
+decryption_key_t* key_item = NULL;
+
+keys_in_list = g_list_length(key_list);
+
+/*
+ * Save the encryption keys, if we have any of them
+ */
+KeysCollectionSize = 0;
+
+/*
+ * Calculate the size of the keys collection
+ */
+KeysCollectionSize = sizeof(AirpcapKeysCollection) + keys_in_list * sizeof(AirpcapKey);
+
+/*
+ * Allocate the collection
+ */
+KeysCollection = (PAirpcapKeysCollection)malloc(KeysCollectionSize);
+if(!KeysCollection)
+{
+       return FALSE;
+}
+
+/*
+ * Populate the key collection
+ */
+KeysCollection->nKeys = keys_in_list;
+
+for(i = 0; i < keys_in_list; i++)
+{
+    KeysCollection->Keys[i].KeyType = AIRPCAP_KEYTYPE_WEP;
+
+       /* Retrieve the Item corresponding to the i-th key */
+       key_item = (decryption_key_t*)g_list_nth_data(key_list,i);
+       new_key = g_string_new(key_item->key->str);
+       
+       KeysCollection->Keys[i].KeyLen = new_key->len / 2;
+       memset(&KeysCollection->Keys[i].KeyData, 0, sizeof(KeysCollection->Keys[i].KeyData));
+
+       for(j = 0 ; j < new_key->len; j += 2)
+       {
+               s[0] = new_key->str[j];
+               s[1] = new_key->str[j+1];
+               s[2] = '\0';
+               KeyByte = (UCHAR)strtol(s, NULL, 16);
+               KeysCollection->Keys[i].KeyData[j / 2] = KeyByte;
+       }
+       
+       g_string_free(new_key,TRUE);    
+}
+
+/*
+ * Free the old adapter key collection!
+ */
+if(info_if->keysCollection != NULL)
+       g_free(info_if->keysCollection);
+
+/*
+ * Set this collection ad the new one
+ */
+info_if->keysCollection = KeysCollection;
+info_if->keysCollectionSize = KeysCollectionSize;
+
+/*
+ * Configuration must be saved
+ */
+info_if->saved = FALSE;
+
+/*
+ * Write down the changes to the registry
+ */
+airpcap_save_selected_if_configuration(info_if);
+
+return TRUE;
+}
+
+/* 
+ *  Function used to save to the preference file the Decryption Keys.
+ */
+gboolean
+save_wlan_wep_keys(airpcap_if_info_t* info_if)
+{
+GList* key_list = NULL;
+char* tmp_key = NULL;
+guint keys_in_list,i;
+keys_cb_data_t* user_data;
+                                      
+if(info_if == NULL) return FALSE;
+
+/* Retrieve the wlan preferences */
+wlan_prefs = prefs_find_module("wlan");
+
+/* Allocate a structure used to keep infos  between the callbacks */
+user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
+
+/* Number of keys in key list */
+keys_in_list = (info_if->keysCollectionSize -  sizeof(AirpcapKeysCollection))/sizeof(AirpcapKey);
+
+for(i=0; i<keys_in_list; i++)
+{
+/* Only if it is a WEP key... */
+if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_WEP)
+    {
+    tmp_key = airpcap_get_key_string(info_if->keysCollection->Keys[i]);   
+    key_list = g_list_append(key_list,g_strdup(tmp_key));    
+    g_free(tmp_key);
+    }
+}
+
+/* Now we know the exact number of WEP keys in the list, so store it ... */
+keys_in_list = g_list_length(key_list);
+
+/* Fill the structure */
+user_data->list = key_list;
+user_data->current_index = 0;
+user_data->number_of_keys= keys_in_list; 
+
+/* Retrieve the wlan preferences */
+wlan_prefs = prefs_find_module("wlan");
+
+/* Run the callback on each 802.11 preference */
+prefs_pref_foreach(wlan_prefs, set_wep_key,  (gpointer)user_data);
+
+/* Signal that we've changed things, and run the 802.11 dissector's
+ * callback */
+wlan_prefs->prefs_changed = TRUE;
+
+/* Apply changes for the specified preference */
+prefs_apply(wlan_prefs);
+
+/* FREE MEMORY */
+/* free the WEP key string */
+for(i=0;i<g_list_length(user_data->list);i++)
+    {
+    g_free(g_list_nth(user_data->list,i)->data);
+    }
+
+/* free the (empty) list */
+g_list_free(user_data->list);
+
+/* free the user_data structure */
+g_free(user_data);
+
+return TRUE;
+}
+
 /*
  * Get an error message string for a CANT_GET_INTERFACE_LIST error from
  * "get_airpcap_interface_list()".
@@ -250,7 +601,7 @@ airpcap_if_set_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection
  */
 BOOL
 airpcap_if_get_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, PUINT PKeysCollectionSize)
-{
+{   
        return g_PAirpcapGetDeviceKeys(AdapterHandle,KeysCollection,PKeysCollectionSize);
 }
 
@@ -273,7 +624,7 @@ gchar ebuf[AIRPCAP_ERRBUF_SIZE];
                if_info->description = g_strdup(description);
        if_info->ip_addr = NULL;
        if_info->loopback = FALSE;
-
+       
        /* Probably I have to switch on the leds!!! */
        ad = airpcap_if_open(if_info->name, ebuf);
        if(ad)
@@ -385,19 +736,13 @@ get_airpcap_interface_list(int *err, char *err_str)
        GList  *il = NULL;
        airpcap_if_info_t *if_info;
        int i, n_adapts;
-       AirpcapDeviceDescription *devsList, *adListEntry;
-
-       if(g_PAirpcapGetDeviceList == NULL) {
-               /* Airpcap.dll not available */
-               *err = NO_AIRPCAP_INTERFACES_FOUND;
-               return NULL;
-       }
+    AirpcapDeviceDescription *devsList, *adListEntry;
 
        if(!g_PAirpcapGetDeviceList(&devsList, err_str))
        {
-               /* No interfaces */
+               /* No interfaces, return il = NULL; */
                *err = NO_AIRPCAP_INTERFACES_FOUND;
-               return NULL;
+               return il;
        }
 
        /*
@@ -530,6 +875,18 @@ if(key.KeyType == AIRPCAP_KEYTYPE_WEP)
        g_free(src);
         }
        }
+else if(key.KeyType == AIRPCAP_KEYTYPE_TKIP)
+    {
+    /* XXX - Add code here */
+    }
+else if(key.KeyType == AIRPCAP_KEYTYPE_CCMP)
+    {
+    /* XXX - Add code here */
+    }
+else
+    {
+    /* XXX - Add code here */
+    }
 
 return dst;
 }
@@ -727,6 +1084,556 @@ if(if_info != NULL)
        }
 }
 
+/*
+ * DECRYPTION KEYS FUNCTIONS
+ */
+/*
+ * This function is used for DEBUG POURPOSES ONLY!!!
+ */
+void
+print_key_list(GList* key_list)
+{
+gint n,i;
+decryption_key_t* tmp;
+                      
+n = g_list_length(key_list);
+
+g_print("\n\n********* KEY LIST **********\n\n");
+
+g_print("NUMBER OF KEYS IN LIST : %d\n\n",n);
+
+for(i =0; i < n; i++)
+{
+g_print("[%d] :\n",i+1);
+tmp = (decryption_key_t*)(g_list_nth_data(key_list,i));
+g_print("KEY : %s\n",tmp->key->str);
+
+g_print("BITS: %d\n",tmp->bits);
+
+if(tmp->type == AIRPCAP_KEYTYPE_WEP)
+    g_print("TYPE: %s\n",AIRPCAP_WEP_KEY_STRING);
+else if(tmp->type == AIRPCAP_KEYTYPE_TKIP)
+    g_print("TYPE: %s\n",AIRPCAP_WPA_KEY_STRING);
+else if(tmp->type == AIRPCAP_KEYTYPE_CCMP)
+    g_print("TYPE: %s\n",AIRPCAP_WPA2_KEY_STRING);
+else 
+    g_print("TYPE: %s\n","???");
+
+g_print("SSID: %s\n",(tmp->ssid != NULL) ? tmp->ssid->str : "---");
+g_print("\n");
+}
+
+g_print("\n*****************************\n\n");
+}
+
+/*
+ * Retrieves a GList of decryption_key_t structures containing infos about the
+ * keys for the given adapter... returns NULL if no keys are found.
+ */
+GList*
+get_airpcap_device_keys(airpcap_if_info_t* info_if)
+{
+/* tmp vars */
+char* tmp_key = NULL;
+guint i,keys_in_list = 0;
+
+/* real vars*/
+decryption_key_t *new_key  = NULL;
+GList            *key_list = NULL;
+            
+/* Number of keys in key list */
+if(info_if->keysCollectionSize != 0)
+    keys_in_list = (guint)(info_if->keysCollectionSize -  sizeof(AirpcapKeysCollection))/sizeof(AirpcapKey);
+else
+    keys_in_list = 0;
+    
+for(i=0; i<keys_in_list; i++)
+{
+/* Different things to do depending on the key type  */
+if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_WEP)
+    {
+    /* allocate memory for the new key item */
+    new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
+    
+    /* fill the fields */
+    /* KEY */
+    tmp_key = airpcap_get_key_string(info_if->keysCollection->Keys[i]);
+    new_key->key = g_string_new(tmp_key);
+    g_free(tmp_key);
+    
+    /* BITS */
+    new_key->bits = new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an exadecimal number) */
+    
+    /* SSID not used in WEP keys */
+    new_key->ssid = NULL;
+    
+    /* TYPE (WEP in this case) */
+    new_key->type = info_if->keysCollection->Keys[i].KeyType;
+    
+    /* Append the new element in the list */
+    key_list = g_list_append(key_list,(gpointer)new_key);    
+    }
+else if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_TKIP)
+    {
+    /* XXX - Not supported yet */
+    }
+else if(info_if->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_CCMP)
+    {
+    /* XXX - Not supported yet */
+    }
+}
+
+return key_list;
+}
+
+/*
+ * Returns the list of the decryption keys specified for wireshark, NULL if
+ * no key is found 
+ */
+GList*
+get_wireshark_keys()
+{
+keys_cb_data_t* wep_user_data = NULL;
+keys_cb_data_t* wpa_user_data = NULL;
+keys_cb_data_t* wpa2_user_data= NULL;
+
+gchar *tmp = NULL;
+
+GList* final_list = NULL;
+GList* wep_final_list = NULL;
+GList* wpa_final_list = NULL;
+GList* wpa2_final_list = NULL;
+                
+/* Retrieve the wlan preferences */
+wlan_prefs = prefs_find_module("wlan");
+
+/* Allocate a structure used to keep infos  between the callbacks */
+wep_user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t));
+
+/* Fill the structure */
+wep_user_data->list = NULL;
+wep_user_data->current_index = 0;
+wep_user_data->number_of_keys= 0; /* Still unknown */
+
+/* Run the callback on each 802.11 preference */
+/* XXX - Right now, only WEP keys will be loaded */
+prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)wep_user_data);
+prefs_pref_foreach(wlan_prefs, get_wpa_key, (gpointer)wpa_user_data);
+prefs_pref_foreach(wlan_prefs, get_wpa2_key, (gpointer)wpa2_user_data);
+
+/* Copy the list field in the user data structure pointer into the final_list */
+if(wep_user_data != NULL)  wep_final_list  = wep_user_data->list;
+if(wpa_user_data != NULL)  wpa_final_list  = wpa_user_data->list;
+if(wpa2_user_data != NULL) wpa2_final_list = wpa2_user_data->list;
+
+/* XXX - Merge the three lists!!!!! */
+final_list = wep_final_list;
+
+/* free the wep_user_data structure */
+g_free(wep_user_data);
+/* free the wpa_user_data structure */
+g_free(wpa_user_data);
+/* free the wpa2_user_data structure */
+g_free(wpa2_user_data);
+
+return final_list;
+}
+
+/*
+ * Merges two lists of keys and return a newly created GList. If a key is 
+ * found multiple times, it will just appear once!
+ * list1 and list 2 pointer will have to be freed manually if needed!!! 
+ * If the total number of keys exceeeds the maximum number allowed, 
+ * exceeding keys will be discarded...
+ */
+GList*
+merge_key_list(GList* list1, GList* list2)
+{
+guint n1=0,n2=0;
+guint i;
+decryption_key_t *dk1=NULL,
+                 *dk2=NULL, 
+                 *new_dk=NULL;
+
+GList* merged_list = NULL;
+
+if( (list1 == NULL) && (list2 == NULL) )
+    return NULL;
+
+if(list1 == NULL)
+    {
+    n1 = 0;
+    n2 = g_list_length(list2);
+    
+    for(i=0;i<n2;i++)
+        {
+        new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
+        dk2 = (decryption_key_t *)g_list_nth_data(list2,i);
+        
+        new_dk->bits = dk2->bits;
+        new_dk->type = dk2->type;
+        new_dk->key  = g_string_new(dk2->key->str);
+        if(dk2->ssid != NULL)
+            new_dk->ssid = g_string_new(dk2->ssid->str);
+        else
+            new_dk->ssid = NULL;
+
+               /* Check the total length of the merged list */
+               if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)      
+                       merged_list = g_list_append(merged_list,(gpointer)new_dk);
+        }   
+    }
+else if(list2 == NULL)
+    {
+    n1 = g_list_length(list1);
+    n2 = 0;
+    
+    for(i=0;i<n1;i++)
+        {
+        new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
+        dk1 = (decryption_key_t*)g_list_nth_data(list1,i);
+        
+        new_dk->bits = dk1->bits;
+        new_dk->type = dk1->type;
+        new_dk->key  = g_string_new(dk1->key->str);
+        if(dk1->ssid != NULL)
+            new_dk->ssid = g_string_new(dk1->ssid->str);
+        else
+            new_dk->ssid = NULL;
+        
+               /* Check the total length of the merged list */
+               if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)      
+                       merged_list = g_list_append(merged_list,(gpointer)new_dk);
+        }   
+    }
+else
+    {
+    n1 = g_list_length(list1);
+    n2 = g_list_length(list2);
+    
+    /* Copy the whole list1 into merged_list */
+    for(i=0;i<n1;i++)
+    {
+    new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
+    dk1 = (decryption_key_t *)g_list_nth_data(list1,i);
+    
+    new_dk->bits = dk1->bits;
+    new_dk->type = dk1->type;
+    new_dk->key  = g_string_new(dk1->key->str);
+    
+    if(dk1->ssid != NULL)
+        new_dk->ssid = g_string_new(dk1->ssid->str);
+    else
+        new_dk->ssid = NULL;
+
+       /* Check the total length of the merged list */
+       if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)  
+               merged_list = g_list_append(merged_list,(gpointer)new_dk);
+    }   
+    
+    /* Look for keys that are present in list2 but aren't in list1 yet...
+     * Add them to merged_list
+     */
+    for(i=0;i<n2;i++)
+        {
+        dk2 = (decryption_key_t *)g_list_nth_data(list2,i);
+        
+        if(!key_is_in_list(dk2,merged_list))
+            {
+            new_dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
+            
+            new_dk->bits = dk2->bits;
+            new_dk->type = dk2->type;
+            new_dk->key  = g_string_new(dk2->key->str);
+            if(dk2->ssid != NULL)
+                new_dk->ssid = g_string_new(dk2->ssid->str);
+            else
+                new_dk->ssid = NULL;
+            
+                       /* Check the total length of the merged list */
+                       if(g_list_length(merged_list) < MAX_ENCRYPTION_KEYS)
+                               merged_list = g_list_append(merged_list,(gpointer)new_dk);
+            }        
+        }
+    }
+
+return merged_list;
+}
+
+/*
+ * Use this function to free a key list. 
+ */
+void
+free_key_list(GList *list)
+{
+guint i,n;
+decryption_key_t *curr_key;
+
+if(list == NULL)
+    return;
+    
+n = g_list_length(list);
+
+for(i = 0; i < n; i++)
+{
+curr_key = (decryption_key_t*)g_list_nth_data(list,i);
+
+/* Free all the strings */
+if(curr_key->key != NULL)
+    g_string_free(curr_key->key,TRUE);
+    
+if(curr_key->ssid != NULL)
+g_string_free(curr_key->ssid,TRUE);
+
+/* free the decryption_key_t structure*/
+g_free(curr_key);
+curr_key = NULL;
+}
+
+/* Free the list */
+g_list_free(list);
+
+return;
+}
+
+
+/*
+ * If the given key is contained in the list, returns TRUE.
+ * Returns FALSE otherwise. 
+ */
+gboolean
+key_is_in_list(decryption_key_t *dk,GList *list)
+{
+guint i,n;
+decryption_key_t* curr_key = NULL;
+gboolean found = FALSE;
+
+if( (list == NULL) || (dk == NULL) )
+    return FALSE;
+
+n = g_list_length(list);
+
+if(n < 1)
+    return FALSE;
+
+for(i = 0; i < n; i++)
+{
+curr_key = (decryption_key_t*)g_list_nth_data(list,i); 
+if(keys_are_equals(dk,curr_key))
+    found = TRUE;  
+}     
+
+return found;
+}
+
+/*
+ * Returns TRUE if keys are equals, FALSE otherwise
+ */
+gboolean
+keys_are_equals(decryption_key_t *k1,decryption_key_t *k2)
+{
+
+if((k1==NULL) || (k2==NULL))
+    return FALSE;
+    
+if( g_string_equal(k1->key,k2->key) &&
+    (k1->bits == k2->bits) && /* If the previous is TRUE, this must be TRUE as well */
+    k1->type == k2->type)
+    {
+    /* Check the ssid... if the key type is WEP, the two fields should be NULL */
+    if((k1->ssid == NULL) && (k2->ssid == NULL))
+        return TRUE;
+    
+    /* Check if one of them is null and one is not... */
+    if((k1->ssid == NULL) || (k2->ssid == NULL))
+        return FALSE;
+        
+    /* If they are not null, they must share the same ssid */
+    return g_string_equal(k1->ssid,k2->ssid);
+    }
+
+/* Some field is not equal ... */
+return FALSE;
+}
+
+/*
+ * Tests if two collection of keys are equal or not, to be considered equals, they have to
+ * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will
+ * return TRUE)
+ */
+gboolean
+key_lists_are_equal(GList* list1, GList* list2)
+{
+guint n1=0,n2=0;
+guint i;
+decryption_key_t *dk1=NULL,*dk2=NULL;
+
+n1 = g_list_length(list1);
+n2 = g_list_length(list2);
+
+if(n1 != n2) return FALSE;
+
+for(i=0;i<n1;i++)
+{
+dk1=(decryption_key_t*)g_list_nth_data(list1,i);
+dk2=(decryption_key_t*)g_list_nth_data(list2,i);
+
+if(!g_string_equal(dk1->key,dk2->key)) return FALSE;
+}
+
+return TRUE;
+}
+
+static guint
+test_if_on(pref_t *pref, gpointer ud _U_)
+{
+gboolean *is_on;
+gboolean number;
+
+/* Retrieve user data info */
+is_on = (gboolean*)ud; 
+
+
+if (g_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL)
+    {
+    number = *pref->varp.boolp;
+    
+    if(number) *is_on = TRUE;
+    else *is_on = FALSE;
+
+    return 1;
+    }
+return 0;
+}
+
+/*
+ * Returns TRUE if the Wireshark decryption is active, false otherwise
+ */
+gboolean
+wireshark_decryption_on()
+{
+gboolean is_on;
+
+/* Retrieve the wlan preferences */
+wlan_prefs = prefs_find_module("wlan");
+
+/* Run the callback on each 802.11 preference */
+prefs_pref_foreach(wlan_prefs, test_if_on, (gpointer)&is_on);
+
+return is_on;
+}
+
+/*
+ * Returns TRUE if the AirPcap decryption is active, false otherwise
+ */
+gboolean
+airpcap_decryption_on()
+{
+gboolean is_on = FALSE;
+
+if(airpcap_if_selected != NULL)
+    {
+    is_on = (gboolean)airpcap_if_selected->DecryptionOn;
+    }
+return is_on;
+}
+
+static guint
+set_on_off(pref_t *pref, gpointer ud _U_)
+{
+gboolean *is_on;
+gboolean number;
+
+/* Retrieve user data info */
+is_on = (gboolean*)ud; 
+
+if (g_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL)
+    {
+    number = *pref->varp.boolp;
+    
+    g_free((void *)*pref->varp.boolp);
+    if(*is_on)
+        *pref->varp.boolp = TRUE; 
+    else
+        *pref->varp.boolp = FALSE;
+        
+    return 1;
+    }
+return 0;
+}
+
+/*
+ * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise.
+ */
+void
+set_wireshark_decryption(gboolean on_off)
+{
+gboolean is_on;
+
+is_on = on_off;
+
+/* Retrieve the wlan preferences */
+wlan_prefs = prefs_find_module("wlan");
+
+/* Run the callback on each 802.11 preference */
+prefs_pref_foreach(wlan_prefs, set_on_off, (gpointer)&is_on);
+
+/* 
+ * Signal that we've changed things, and run the 802.11 dissector's
+ * callback 
+ */
+wlan_prefs->prefs_changed = TRUE;
+
+prefs_apply(wlan_prefs);
+}
+
+/*
+ * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise.
+ */
+gboolean
+set_airpcap_decryption(gboolean on_off)
+{
+/* We need to directly access the .ddl functions here... */
+gchar ebuf[AIRPCAP_ERRBUF_SIZE];
+PAirpcapHandle ad;
+
+gboolean success = TRUE;
+
+gint n = 0;
+gint i = 0;
+airpcap_if_info_t* curr_if = NULL;
+
+n = g_list_length(airpcap_if_list);
+
+/* The same kind of settings should be propagated to all the adapters */
+/* Apply this change to all the adapters !!! */
+for(i = 0; i < n; i++)
+    {
+    curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
+
+    if( curr_if != NULL )
+       {
+       ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,curr_if->description), ebuf);
+               if(ad)
+            {                                                                                     
+            curr_if->DecryptionOn = (gboolean)on_off;
+               airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
+               /* Save configuration for the curr_if */
+               if(!airpcap_if_store_cur_config_as_adapter_default(ad))
+                       {
+                       success = FALSE;
+                       }
+               airpcap_if_close(ad);
+            }
+        }
+    }
+
+return success;
+}
+
+
+/* DINAMICALLY LIBRARY LOADER */
 /*
  *  Used to dinamically load the airpcap library in order link it only when
  *  it's present on the system
index e0d58a7f24d460a7aa810720e2da0267e89855b6..81169c2e72fc8b41a069ce64eb217e89f082a6c4 100644 (file)
 #define AIRPCAP_CHANNEL_ANY_NAME "ANY"
 
 /*
- * WEP_KEY_MAX_SIZE is in bytes. but each byte is rapresented in strings with an ascii char
+ * WEP_KEY_MAX_SIZE is in bytes, but each byte is rapresented in strings with an ascii char
  * 4 bit are needed to store an exadecimal number, 8 bit to store a char...
  */
 #define WEP_KEY_MAX_CHAR_SIZE (WEP_KEY_MAX_SIZE*2)
 
+/*
+ * WEP_KEY_MAX_SIZE is in bytes, this is in bits...
+ */
+#define WEP_KEY_MAX_BIT_SIZE (WEP_KEY_MAX_SIZE*8)
+
+#define AIRPCAP_WEP_KEY_STRING  "WEP"
+#define AIRPCAP_WPA_KEY_STRING  "WPA"
+#define AIRPCAP_WPA2_KEY_STRING "WPA2"
+
 typedef PCHAR (*AirpcapGetLastErrorHandler)(PAirpcapHandle AdapterHandle);
 typedef BOOL (*AirpcapGetDeviceListHandler)(PAirpcapDeviceDescription *PPAllDevs, PCHAR Ebuf);
 typedef VOID (*AirpcapFreeDeviceListHandler)(PAirpcapDeviceDescription PAllDevs);
@@ -89,6 +98,25 @@ typedef struct {
        gint                                    tag;                            /* int for the gtk blinking callback */
 } airpcap_if_info_t;
 
+/*
+ * Struct used to store infos to pass to the preferences manager callbacks
+ */
+typedef struct {
+   GList *list;
+   int current_index;
+   int number_of_keys; 
+} keys_cb_data_t;
+
+/*
+ * Struct to store infos about a specific decryption key.
+ */
+typedef struct {
+    GString *key;
+    GString *ssid;
+    guint   bits;
+    guint   type; 
+} decryption_key_t;
+
 /* Airpcap interface list */
 extern GList *airpcap_if_list;
 
@@ -98,6 +126,33 @@ extern airpcap_if_info_t *airpcap_if_selected;
 /* Airpcap current active interface */
 extern airpcap_if_info_t *airpcap_if_active;
 
+/* WLAN preferences pointer */
+//extern module_t *wlan_prefs;
+
+/*
+ * Function used to read the Decryption Keys from the preferences and store them
+ * properly into the airpcap adapter.
+ */
+BOOL 
+load_wlan_wep_keys(airpcap_if_info_t* info_if);
+
+/* 
+ *  Function used to save to the prefereces file the Decryption Keys.
+ */
+BOOL 
+save_wlan_wep_keys(airpcap_if_info_t* info_if);
+
+/*
+ * This function will tell the airpcap driver the key list to use
+ * This will be stored into the registry...
+ */
+gboolean
+write_wlan_wep_keys_to_regitry(airpcap_if_info_t* info_if, GList* key_list);
+
+/* Returs TRUE if the WEP key is valid, false otherwise */
+gboolean
+wep_key_is_valid(char* key);
+
 /*
  * Callback used to free an instance of airpcap_if_info_t
  */
@@ -300,4 +355,85 @@ airpcap_if_set_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection
  */
 BOOL
 airpcap_if_get_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, PUINT PKeysCollectionSize);
+
+/*
+ * DECRYPTION KEYS FUNCTIONS
+ */
+/*
+ * This function is used for DEBUG PURPOSES ONLY!!!
+ */
+void
+print_key_list(GList* key_list);
+
+/*
+ * Retrieves a GList of decryption_key_t structures containing infos about the
+ * keys for the given adapter... returns NULL if no keys are found.
+ */
+GList*
+get_airpcap_device_keys(airpcap_if_info_t* if_info);
+
+/*
+ * Returns the list of the decryption keys specified for wireshark, NULL if
+ * no key is found 
+ */
+GList*
+get_wireshark_keys();
+
+/*
+ * Tests if two collection of keys are equal or not, to be considered equals, they have to
+ * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will
+ * return TRUE)
+ */
+gboolean
+key_lists_are_equal(GList* list1, GList* list2);
+
+/*
+ * Merges two lists of keys. If a key is found multiple times, it will just appear once!
+ */
+GList*
+merge_key_list(GList* list1, GList* list2);
+
+/*
+ * If the given key is contained in the list, returns TRUE.
+ * Returns FALSE otherwise. 
+ */
+gboolean
+key_is_in_list(decryption_key_t *dk,GList *list);
+
+/*
+ * Returns TRUE if keys are equals, FALSE otherwise
+ */
+gboolean
+keys_are_equals(decryption_key_t *k1,decryption_key_t *k2);
+
+/*
+ * Use this function to free a key list. 
+ */
+void
+free_key_list(GList *list);
+
+/*
+ * Returns TRUE if the Wireshark decryption is active, false otherwise
+ */
+gboolean
+wireshark_decryption_on();
+
+/*
+ * Returns TRUE if the AirPcap decryption is active, false otherwise
+ */
+gboolean
+airpcap_decryption_on();
+
+/*
+ * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise.
+ */
+void
+set_wireshark_decryption(gboolean on_off);
+
+/*
+ * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise.
+ */
+gboolean
+set_airpcap_decryption(gboolean on_off);
+
 #endif
index 57ff7998fdbcdeabff8014c7664ed67ae988da69..1c4391d7463febf294ec18a0396b6764541af2e0 100644 (file)
@@ -157,7 +157,8 @@ Wireshark Info
         <listitem><para>
         <ulink url="http://www.cacetech.com/products/airpcap.htm">AirPcap</ulink>,
         support (which provides raw mode capture under Windows) has been
-        enhanced.
+        enhanced to allow capturing on multiple AirPcap adapters
+        simultaneously using the Multi-Channel Aggregator.
         </para></listitem>
 
         <listitem><para>
index ba72c531edb108242c0e598c3e8bc8aa4f4bbbd9..8cd7cc2fd6f7f5d7f5b7f7692c4fa9810888e8fb 100644 (file)
@@ -37,6 +37,8 @@
 #include <string.h>
 
 #include <epan/filesystem.h>
+#include <epan/prefs.h>
+#include <epan/prefs-int.h>
 
 #include <pcap.h>
 
@@ -49,6 +51,7 @@
 #include "gtkglobals.h"
 #include "help_dlg.h"
 
+
 #include <airpcap.h>
 #include "airpcap_loader.h"
 #include "airpcap_gui_utils.h"
 /* temporary block signals to widgets */
 BOOL block_advanced_signals;
 
+/*
+ * This function is used to write the preferences to the preferences file.
+ * It has the same behaviour as prefs_main_write() in prefs_dlg.c
+ */
+static void
+write_prefs_to_file(void)
+{
+  int err;
+  char *pf_dir_path;
+  char *pf_path;
+
+  /* Create the directory that holds personal configuration files, if
+     necessary.  */
+  if (create_persconffile_dir(&pf_dir_path) == -1) {
+     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+      "Can't create directory\n\"%s\"\nfor preferences file: %s.", pf_dir_path,
+      strerror(errno));
+     g_free(pf_dir_path);
+  } else {
+    /* Write the preferencs out. */
+    err = write_prefs(&pf_path);
+    if (err != 0) {
+       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+        "Can't open preferences file\n\"%s\": %s.", pf_path,
+        strerror(err));
+       g_free(pf_path);
+    }
+  }
+}
+
 /*
  * This struct will contain useful data for the selected (actual) airpcap device
  */
@@ -98,11 +131,58 @@ airpcap_if_info_t* if_info = NULL;
                }
 }
 
+/*
+ * Callback for the select row event in the key list widget
+ */
+void
+on_key_ls_select_row(GtkWidget *widget, 
+                     gint row,
+                     gint column,
+                     GdkEventButton *event,
+                     gpointer data)
+{
+airpcap_key_ls_selected_info_t*  selected_item;
+                             
+selected_item = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
+
+selected_item->row = row;
+selected_item->column = column;
+}
+
+/*
+ * Callback for the unselect row event in the key list widget
+ */
+void
+on_key_ls_unselect_row(GtkWidget *widget,
+                       gint row,
+                       gint column,
+                       GdkEventButton *event,
+                       gpointer data)
+{
+airpcap_key_ls_selected_info_t*  selected_item;
+                             
+selected_item = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
+
+selected_item->row = NO_ROW_SELECTED;
+selected_item->column = NO_COLUMN_SELECTED;
+}
+
+/*
+ * Callback for the click column event in the key list widget
+ */
+void
+on_key_ls_click_column(GtkWidget *widget,
+                       gint column,
+                       gpointer data)
+{
+
+}
+
 /*
  * Callback for the crc chackbox
  */
 static void
-crc_check_cb(GtkWidget *w, gpointer user_data)
+on_fcs_ck_toggled(GtkWidget *w, gpointer user_data)
 {
 if( !block_advanced_signals && (airpcap_if_selected != NULL))
        {
@@ -123,11 +203,102 @@ if( !block_advanced_signals && (airpcap_if_selected != NULL))
  * Callback for the wrong crc combo
  */
 static void
-wrong_crc_combo_cb(GtkWidget *w, gpointer data)
+on_edit_type_en_changed(GtkWidget *w, gpointer data)
+{
+GtkWidget *edit_key_w;
+GtkWidget *edit_ssid_te;
+GtkWidget *type_te;
+
+gchar* type_text = NULL;
+
+edit_key_w = GTK_WIDGET(data);
+type_te    = w;
+
+edit_ssid_te = OBJECT_GET_DATA(edit_key_w,AIRPCAP_ADVANCED_EDIT_KEY_SSID_KEY);
+
+type_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(type_te)));
+
+if(string_is_not_empty(type_text))
+    {
+    /* 
+     * If it is a WEP key, no SSID is required! Gray out rhe entry text so 
+     * it doesn't create confusion ...
+     */
+    if(g_strcasecmp(type_text,AIRPCAP_WEP_KEY_STRING) == 0)
+        {
+        gtk_widget_set_sensitive(edit_ssid_te,FALSE);
+        }
+    else
+        {
+        gtk_widget_set_sensitive(edit_ssid_te,TRUE);
+        }
+    }
+gtk_widget_show(edit_ssid_te);
+
+g_free(type_text);
+}
+
+/*
+ * Callback for the wrong crc combo
+ */
+static void
+on_add_type_en_changed(GtkWidget *w, gpointer data)
+{
+GtkWidget *add_key_w;
+GtkWidget *add_ssid_te;
+GtkWidget *type_te;
+
+gchar* type_text = NULL;
+
+add_key_w = GTK_WIDGET(data);
+type_te    = w;
+
+add_ssid_te = OBJECT_GET_DATA(add_key_w,AIRPCAP_ADVANCED_ADD_KEY_SSID_KEY);
+
+type_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(type_te)));
+
+if(string_is_not_empty(type_text))
+    {
+    /* 
+     * If it is a WEP key, no SSID is required! Gray out rhe entry text so 
+     * it doesn't create confusion ...
+     */
+    if(g_strcasecmp(type_text,AIRPCAP_WEP_KEY_STRING) == 0)
+        {
+        gtk_widget_set_sensitive(add_ssid_te,FALSE);
+        }
+    else
+        {
+        gtk_widget_set_sensitive(add_ssid_te,TRUE);
+        }
+    }
+gtk_widget_show(add_ssid_te);
+
+g_free(type_text);
+}
+
+/*
+ * Returns FALSE if a text string has lenght 0, i.e. the first char 
+ * is '\0', TRUE otherwise
+ */
+gboolean
+string_is_not_empty(gchar *s)
+{
+if(g_strcasecmp(s,"") != 0)
+    return TRUE;
+else
+    return FALSE;
+}
+
+/*
+ * Callback for the wrong crc combo
+ */
+static void
+on_fcs_filter_en_changed(GtkWidget *w, gpointer data)
 {
 const gchar *s;
 
-s = gtk_entry_get_text(GTK_ENTRY(data));
+s = gtk_entry_get_text(GTK_ENTRY(w));
 
 if( !block_advanced_signals && (data != NULL) && (w != NULL) )
        {
@@ -143,15 +314,15 @@ if( !block_advanced_signals && (data != NULL) && (w != NULL) )
  * Changed callback for the channel combobox
  */
 static void
-channel_changed_cb(GtkWidget *w _U_, gpointer data)
+on_channel_en_changed(GtkWidget *w _U_, gpointer data)
 {
 const gchar *s;
 
-  s = gtk_entry_get_text(GTK_ENTRY(data));
+  s = gtk_entry_get_text(GTK_ENTRY(w));
 
 if( !block_advanced_signals && (data != NULL) && (w != NULL) )
        {
-       s = gtk_entry_get_text(GTK_ENTRY(data));
+       s = gtk_entry_get_text(GTK_ENTRY(w));
        if((g_strcasecmp("",s)))
                {
                if(airpcap_if_selected != NULL)
@@ -164,14 +335,14 @@ if( !block_advanced_signals && (data != NULL) && (w != NULL) )
 }
 
 /*
- * Changed callback for the link layer combobox
+ * Changed callback for the capture type combobox
  */
 static void
-link_type_changed_cb(GtkWidget *w _U_, gpointer data)
+on_capture_type_en_changed(GtkWidget *w _U_, gpointer data)
 {
 const gchar *s;
 
-s = gtk_entry_get_text(GTK_ENTRY(data));
+s = gtk_entry_get_text(GTK_ENTRY(w));
 
 if( !block_advanced_signals && (data != NULL) && (w != NULL) )
        {
@@ -191,137 +362,6 @@ combo_if_activate_cb(GtkWidget *entry _U_, gpointer data)
 {
 }
 
-/*
- * Changed callback for the adapter combobox
- */
-static void
-airpcap_advanced_combo_if_changed_cb(GtkWidget *w _U_, gpointer data)
-{
-const gchar* s = NULL;
-
-s = gtk_entry_get_text(GTK_ENTRY(w));
-
-if((g_strcasecmp("",s)))
-       {
-  /* We are trying to change the interface to set up...*/
-  /* Check if the current interface settings need to be SAVED! */
-  if( (airpcap_if_selected != NULL) && !block_advanced_signals)
-               {
-               if( (airpcap_if_selected->saved) ) /* Just change interface */
-                       {
-                       /* No changes for this interface, no need to save anything */
-                       airpcap_change_if(w,data);
-                       }
-               else
-                       {
-                       /* Popup a dialog to ask if user wants to save settings for selected
-                        * interface before changing it...
-                        */
-                       airpcap_ask_for_save(w,data);
-                       }
-               }
-       }
-}
-
-/*
- * Takes the keys from the GtkList widget, and add them to the interface list
- */
-void
-airpcap_add_keys_from_list(GtkWidget *keylist, airpcap_if_info_t *if_info)
-{
-GtkWidget      *key_ls;
-
-GString                *new_key;
-
-gchar          *text_entered = NULL;
-
-GtkWidget      *nl_item,*nl_lb;
-
-GList          *list,
-                       *children;
-
-/* airpcap stuff */
-UINT i, j;
-gchar s[3];
-PAirpcapKeysCollection KeysCollection;
-ULONG KeysCollectionSize;
-UCHAR KeyByte;
-
-UINT keys_in_list = 0;
-
-key_ls = keylist;
-
-keys_in_list = (UINT)g_list_length(GTK_LIST(key_ls)->children);
-
-if(keys_in_list > 0)
-{
-       /*
-        * Save the encryption keys, if we have any of them
-        */
-       KeysCollectionSize = 0;
-
-       /*
-        * Calculate the size of the keys collection
-        */
-       KeysCollectionSize = sizeof(AirpcapKeysCollection) + keys_in_list * sizeof(AirpcapKey);
-
-       /*
-        * Allocate the collection
-        */
-       KeysCollection = (PAirpcapKeysCollection)malloc(KeysCollectionSize);
-       if(!KeysCollection)
-       {
-               /* Simple dialog ERROR */
-               simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"%s","Failed memory allocation for KeysCollection!");
-               return;
-       }
-
-       /*
-        * Populate the key collection
-        */
-       list = GTK_LIST(key_ls)->children;
-       KeysCollection->nKeys = keys_in_list;
-
-       for(i = 0; i < keys_in_list; i++)
-       {
-               KeysCollection->Keys[i].KeyType = AIRPCAP_KEYTYPE_WEP;
-
-               /* Retrieve the Item corresponding to the i-th key */
-               nl_item = g_list_nth_data(list, i);
-               children = gtk_container_children(GTK_CONTAINER(nl_item));
-               nl_lb = g_list_nth_data(children,0);
-               new_key = g_string_new(GTK_LABEL(nl_lb)->label);
-
-               KeysCollection->Keys[i].KeyLen = new_key->len / 2;
-               memset(&KeysCollection->Keys[i].KeyData, 0, sizeof(KeysCollection->Keys[i].KeyData));
-
-               for(j = 0 ; j < new_key->len; j += 2)
-               {
-                       s[0] = new_key->str[j];
-                       s[1] = new_key->str[j+1];
-                       s[2] = '\0';
-                       KeyByte = (UCHAR)strtol(s, NULL, 16);
-                       KeysCollection->Keys[i].KeyData[j / 2] = KeyByte;
-               }
-       }
-
-       /*
-        * Free the old adapter key collection!
-        */
-       if(airpcap_if_selected->keysCollection != NULL)
-               g_free(airpcap_if_selected->keysCollection);
-
-       /*
-        * Set this collection ad the new one
-        */
-       airpcap_if_selected->keysCollection = KeysCollection;
-       airpcap_if_selected->keysCollectionSize = KeysCollectionSize;
-}
-
-return;
-}
-
-
 /*
  * Pop-up window, used to ask the user if he wants to save the selected interface settings
  * when closing the window.
@@ -439,8 +479,8 @@ airpcap_change_if(GtkWidget *entry _U_, gpointer data)
   interface_combo   = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_INTERFACE_KEY));
   channel_combo                = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_CHANNEL_KEY));
   capture_combo                = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_LINK_TYPE_KEY));
-  crc_check                    = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_CRC_KEY));
-  wrong_crc_combo      = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_WRONG_CRC_KEY));
+  crc_check                    = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_FCS_CHECK_KEY));
+  wrong_crc_combo      = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_FCS_FILTER_KEY));
   blink_bt                     = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_BLINK_KEY));
   key_ls                       = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_KEYLIST_KEY));
 
@@ -557,7 +597,7 @@ if(ad)
  * Blink button callback
  */
 void
-blink_cb( GtkWidget *blink_bt _U_, gpointer if_data )
+on_blink_bt_clicked( GtkWidget *blink_bt _U_, gpointer if_data )
 {
 PAirpcapHandle ad = NULL;
 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
@@ -595,175 +635,145 @@ if(airpcap_if_selected != NULL)
                }
 }
 
+/*
+ * Callback for the 'Any' adapter What's This button.
+ */
+void
+on_what_s_this_bt_clicked( GtkWidget *blink_bt _U_, gpointer if_data )
+{
+simple_dialog(ESD_TYPE_INFO,ESD_BTN_OK,"The Multi-Channel Aggregator is a virtual device that can be used to capture packets from all the AirPcap adapters at the same time.\nThe Capture Type, FCS and Encryption settings of this virtual device can be configured as for any real adapter.\nThe channel cannot be changed for this adapter.\nRefer to the AirPcap manual for more information.");
+}
+
 /* the window was closed, cleanup things */
-static void
-airpcap_if_destroy_cb(GtkWidget *w _U_, gpointer user_data _U_)
-{
-       PAirpcapHandle ad = NULL;
-       gchar ebuf[AIRPCAP_ERRBUF_SIZE];
-
-       /* Retrieve object data */
-    GtkWidget *main_w;
-    GtkWidget *channel_combo;
-    GtkWidget *capture_combo;
-    GtkWidget *crc_check;
-    GtkWidget *wrong_crc_combo;
-    GtkWidget *blink_bt;
-       GtkWidget *interface_combo;
-       GtkWidget *cancel_bt;
-       GtkWidget *ok_bt;
-       GtkWidget *key_ls;
+void
+on_key_management_destroy(GtkWidget *w _U_, gpointer data _U_)
+{
+GtkWidget      *airpcap_advanced_w,
+                       *toolbar;
+       
+gint *from_widget = NULL;
 
-       /* widgets in the toolbar */
-       GtkWidget       *toolbar,
-                               *toolbar_if_lb,
-                               *toolbar_channel_cm,
-                               *toolbar_wrong_crc_cm,
-                               *toolbar_decryption_ck,
-                               *advanced_bt;
-
-       gint *from_widget = NULL;
-
-    /* Retrieve the GUI object pointers */
-    main_w = GTK_WIDGET(user_data);
-       interface_combo         = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_INTERFACE_KEY));
-    channel_combo              = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_CHANNEL_KEY));
-    capture_combo              = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_LINK_TYPE_KEY));
-    crc_check                  = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_CRC_KEY));
-    wrong_crc_combo            = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_WRONG_CRC_KEY));
-    blink_bt                   = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_BLINK_KEY));
-       cancel_bt                       = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_CANCEL_KEY));
-       ok_bt                           = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_OK_KEY));
-       key_ls                          = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_KEYLIST_KEY));
-       advanced_bt                     = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_KEY));
+/* Retrieve the GUI object pointers */
+airpcap_advanced_w  = GTK_WIDGET(data);
 
-       toolbar = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_TOOLBAR_KEY));
+toolbar        = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_TOOLBAR_KEY));
 
-       /* retrieve toolbar info */
-       toolbar_if_lb                   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_INTERFACE_KEY));
-       toolbar_channel_cm              = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_CHANNEL_KEY));
-       toolbar_wrong_crc_cm    = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_WRONG_CRC_KEY));
-       toolbar_decryption_ck   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_DECRYPTION_KEY));
+/* ... */
+from_widget    = (gint*)OBJECT_GET_DATA(toolbar,AIRPCAP_ADVANCED_FROM_KEY);
+/* gray out the toolbar (if we came here from the toolbar advanced button)*/
+if( *from_widget == AIRPCAP_ADVANCED_FROM_TOOLBAR)
+       gtk_widget_set_sensitive(toolbar,TRUE);
+else
+       gtk_widget_set_sensitive(toolbar,FALSE);
+g_free(from_widget);
 
-       from_widget     = (gint*)OBJECT_GET_DATA(toolbar,AIRPCAP_ADVANCED_FROM_KEY);
+/* reload the configuration!!! Configuration has not been saved but
+the corresponding structure has been modified probably...*/
+if(!airpcap_if_selected->saved)
+       {
+       airpcap_load_selected_if_configuration(airpcap_if_selected);
+       }
+}
 
-       /* ... */
-       /* gray out the toolbar (if we came here from the toolbar advanced button)*/
-       if( *from_widget == AIRPCAP_ADVANCED_FROM_TOOLBAR)
-               gtk_widget_set_sensitive(toolbar,TRUE);
+/* the Advenced wireless Settings window was closed, cleanup things */
+static void
+on_airpcap_advanced_destroy(GtkWidget *w _U_, gpointer data _U_)
+{
+GtkWidget      *airpcap_advanced_w,
+                       *toolbar;
+       
+gint *from_widget = NULL;
 
-       /* Stop blinking ALL leds (go through the airpcap_if_list) */
-       if(airpcap_if_selected != NULL)
+/* Retrieve the GUI object pointers */
+airpcap_advanced_w  = GTK_WIDGET(data);
+
+toolbar        = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_TOOLBAR_KEY));
+
+/* ... */
+from_widget    = (gint*)OBJECT_GET_DATA(toolbar,AIRPCAP_ADVANCED_FROM_KEY);
+/* gray out the toolbar (if we came here from the toolbar advanced button)*/
+if( *from_widget == AIRPCAP_ADVANCED_FROM_TOOLBAR)
+       gtk_widget_set_sensitive(toolbar,TRUE);
+else
+       gtk_widget_set_sensitive(toolbar,FALSE);
+g_free(from_widget);
+
+/* reload the configuration!!! Configuration has not been saved but
+the corresponding structure has been modified probably...*/
+if(!airpcap_if_selected->saved)
        {
-       ad = airpcap_if_open(airpcap_if_selected->name, ebuf);
-       if(ad)
-               {
-               gtk_timeout_remove(airpcap_if_selected->tag);
-               airpcap_if_turn_led_on(ad, 0);
-               airpcap_if_selected->blinking = FALSE;
-               airpcap_if_selected->led = TRUE;
-               airpcap_if_close(ad);
-               }
+       airpcap_load_selected_if_configuration(airpcap_if_selected);
        }
+}
 
-       /* See if the 'Cancel' button was pressed or not
-        * if button is pressed, don't save configuration!
-        */
-       if(GTK_BUTTON(cancel_bt)->in_button)
-               {
-               /* reload the configuration!!! Configuration has not been saved but
-                  the corresponding structure has been modified probably...*/
-               if(!airpcap_if_selected->saved)
-                       {
-                       airpcap_load_selected_if_configuration(airpcap_if_selected);
-                       }
+/*
+ * Callback for the 'Apply' button.
+ */
+void
+on_key_management_apply_bt_clicked(GtkWidget *button, gpointer data _U_)
+{
+/* advenced window */
+GtkWidget      *key_management_w;
 
-               /* NULL to everything */
-               main_w = NULL;
-               blink_bt = NULL;
-               channel_combo = NULL;
-               interface_combo = NULL;
-               capture_combo = NULL;
-               crc_check = NULL;
-               wrong_crc_combo = NULL;
-
-               /* ... */
-               /* gray out the toolbar (if we came here from the toolbar advanced button)*/
-               if( *from_widget == AIRPCAP_ADVANCED_FROM_TOOLBAR)
-                       gtk_widget_set_sensitive(toolbar,TRUE);
-
-               g_free(from_widget);
-               return;
-               }
-       else if(GTK_BUTTON(ok_bt)->in_button)
-               {
+/* widgets in the toolbar */
+GtkWidget      *toolbar;
+GtkWidget *toolbar_cm;
 
-               /* ??? - Ask if want to save configuration */
+GtkWidget   *key_ls;
 
-               /* Save the configuration */
-               airpcap_add_keys_from_list(key_ls,airpcap_if_selected);
-               airpcap_save_selected_if_configuration(airpcap_if_selected);
-               /* Remove gtk timeout */
-               gtk_timeout_remove(airpcap_if_selected->tag);
+GtkWidget   *decryption_en;
 
-               /* Update toolbar (only if airpcap_if_selected is airpcap_if_active)*/
-               if( g_strcasecmp(airpcap_if_selected->description,airpcap_if_active->description) == 0)
-                       {
-                       gtk_label_set_text(GTK_LABEL(toolbar_if_lb), g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_selected)));
-                       
-                       airpcap_update_channel_combo(GTK_WIDGET(toolbar_channel_cm),airpcap_if_selected);
-                       
-            airpcap_validation_type_combo_set_by_type(toolbar_wrong_crc_cm,airpcap_if_selected->CrcValidationOn);
-
-                       gtk_signal_handler_block_by_func (GTK_OBJECT(toolbar_decryption_ck),GTK_SIGNAL_FUNC(airpcap_toolbar_encryption_cb), toolbar);
-                       if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON)
-                               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_decryption_ck),TRUE);
-                       else
-                               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_decryption_ck),FALSE);
-                       gtk_signal_handler_unblock_by_func (GTK_OBJECT(toolbar_decryption_ck),GTK_SIGNAL_FUNC(airpcap_toolbar_encryption_cb), toolbar);
-                       }
+char* decryption_mode_string = NULL;
 
-               /* If interface active is airpcap, set sensitive TRUE for airpcap toolbar */
-               if( get_airpcap_if_by_name(airpcap_if_list,airpcap_if_active->description) != NULL)
-                       {
-                       airpcap_set_toolbar_start_capture(airpcap_if_active);
-                       }
-               else
-                       {
-                       airpcap_set_toolbar_stop_capture(airpcap_if_active);
-                       }
+/* retrieve main window */
+key_management_w      = GTK_WIDGET(data);
+decryption_en         = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_WEP_DECRYPTION_KEY));
+key_ls               = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_KEYLIST_KEY));
+toolbar               = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_TOOLBAR_KEY));
+toolbar_cm            = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_TOOLBAR_DECRYPTION_KEY));
 
-                       /* NULL to everything */
-                       main_w = NULL;
-                       blink_bt = NULL;
-                       channel_combo = NULL;
-                       interface_combo = NULL;
-                       capture_combo = NULL;
-                       crc_check = NULL;
-                       wrong_crc_combo = NULL;
-
-                               /* ... */
-               /* gray out the toolbar (if we came here from the toolbar advanced button)*/
-               if( *from_widget == AIRPCAP_ADVANCED_FROM_OPTIONS)
-                       gtk_widget_set_sensitive(toolbar,FALSE);
-
-               g_free(from_widget);
-               return;
-               }
+#define CANT_SAVE_ERR_STR "Cannot save configuration!\n" \
+       "In order to store the configuration in the registry you must:\n\n" \
+       "- Close all the airpcap-based applications.\n"\
+       "- Have administrative privileges."
+/* Set the Decryption Mode */
+if(g_strcasecmp(gtk_entry_get_text(GTK_ENTRY(decryption_en)),AIRPCAP_DECRYPTION_TYPE_STRING_WIRESHARK) == 0)
+    {
+    set_wireshark_decryption(TRUE);
+    if(!set_airpcap_decryption(FALSE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+else if(g_strcasecmp(gtk_entry_get_text(GTK_ENTRY(decryption_en)),AIRPCAP_DECRYPTION_TYPE_STRING_AIRPCAP) == 0)
+    {
+    set_wireshark_decryption(FALSE);
+    if(!set_airpcap_decryption(TRUE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+else if(g_strcasecmp(gtk_entry_get_text(GTK_ENTRY(decryption_en)),AIRPCAP_DECRYPTION_TYPE_STRING_NONE) == 0)
+    {
+    set_wireshark_decryption(FALSE);
+    if(!set_airpcap_decryption(FALSE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
 
-               /* reload the configuration!!! Configuration has not been saved but
-          the corresponding structure has been modified probably...*/
-       if(!airpcap_if_selected->saved)
-               {
-               airpcap_load_selected_if_configuration(airpcap_if_selected);
+/* Save the configuration */
+if( (airpcap_if_selected != NULL) )
+    {
+    airpcap_read_and_save_decryption_keys_from_clist(key_ls,airpcap_if_selected,airpcap_if_list); /* This will save the keys for every adapter */
+    
+    /* Update toolbar (only if airpcap_if_selected is airpcap_if_active)*/
+    if( g_strcasecmp(airpcap_if_selected->description,airpcap_if_active->description) == 0)
+       {
+               update_decryption_mode_cm(toolbar_cm);
                }
+    }
+
+/* Redissect all the packets, and re-evaluate the display filter. */
+cf_redissect_packets(&cfile);
 }
 
 /*
- * Callback for the 'Apply' button.
+ * Callback for the Wireless Advanced Settings 'Apply' button.
  */
-static void
-airpcap_advanced_apply_cb(GtkWidget *button, gpointer data _U_)
+void
+on_advanced_apply_bt_clicked(GtkWidget *button, gpointer data _U_)
 {
        /* advenced window */
        GtkWidget       *main_w;
@@ -772,40 +782,27 @@ airpcap_advanced_apply_cb(GtkWidget *button, gpointer data _U_)
        GtkWidget       *toolbar,
                                *toolbar_if_lb,
                                *toolbar_channel_cm,
-                               *toolbar_wrong_crc_cm,
-                               *toolbar_decryption_ck;
-
-       GtkWidget   *key_ls;
-
+                               *toolbar_wrong_crc_cm;
+                               
        /* retrieve main window */
        main_w = GTK_WIDGET(data);
-       key_ls  = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_ADVANCED_KEYLIST_KEY));
 
        toolbar = GTK_WIDGET(OBJECT_GET_DATA(main_w,AIRPCAP_TOOLBAR_KEY));
 
        /* retrieve toolbar info */
        toolbar_if_lb                   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_INTERFACE_KEY));
        toolbar_channel_cm              = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_CHANNEL_KEY));
-       toolbar_wrong_crc_cm    = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_WRONG_CRC_KEY));
-       toolbar_decryption_ck   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_DECRYPTION_KEY));
+       toolbar_wrong_crc_cm    = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_FCS_FILTER_KEY));
 
-       /* Save the configuration */
-       airpcap_add_keys_from_list(key_ls,airpcap_if_selected);
+       /* Save the configuration (for all ) */
        airpcap_save_selected_if_configuration(airpcap_if_selected);
 
        /* Update toolbar (only if airpcap_if_selected is airpcap_if_active)*/
        if( g_strcasecmp(airpcap_if_selected->description,airpcap_if_active->description) == 0)
                {
                gtk_label_set_text(GTK_LABEL(toolbar_if_lb), g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_selected)));
-               airpcap_update_channel_combo(GTK_WIDGET(toolbar_channel_cm),airpcap_if_selected);
+        airpcap_update_channel_combo(GTK_WIDGET(toolbar_channel_cm),airpcap_if_selected);
                airpcap_validation_type_combo_set_by_type(toolbar_wrong_crc_cm,airpcap_if_selected->CrcValidationOn);
-
-       gtk_signal_handler_block_by_func (GTK_OBJECT(toolbar_decryption_ck),GTK_SIGNAL_FUNC(airpcap_toolbar_encryption_cb), toolbar);
-               if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON)
-                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_decryption_ck),TRUE);
-               else
-                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar_decryption_ck),FALSE);
-               gtk_signal_handler_unblock_by_func (GTK_OBJECT(toolbar_decryption_ck),GTK_SIGNAL_FUNC(airpcap_toolbar_encryption_cb), toolbar);
                }
 }
 
@@ -837,7 +834,7 @@ airpcap_advanced_ok_cb(GtkWidget *w, gpointer data _U_)
        /* retrieve toolbar info */
        toolbar_if_lb                   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_INTERFACE_KEY));
        toolbar_channel_cm              = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_CHANNEL_KEY));
-       toolbar_wrong_crc_cm    = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_WRONG_CRC_KEY));
+       toolbar_wrong_crc_cm    = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_FCS_FILTER_KEY));
        toolbar_decryption_ck   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_DECRYPTION_KEY));
 
        /* Save the configuration */
@@ -865,19 +862,10 @@ airpcap_advanced_ok_cb(GtkWidget *w, gpointer data _U_)
 /*
  * Callback for the 'Reset Configuration' button.
  */
-static void
-airpcap_advanced_reset_configuration_cb(GtkWidget *button, gpointer data _U_)
-{
-
-}
-
-/*
- * Callback for the 'About' button.
- */
-static void
-airpcap_advanced_about_cb(GtkWidget *button, gpointer data _U_)
+void
+on_reset_configuration_bt_clicked(GtkWidget *button, gpointer data _U_)
 {
-       /* retrieve toolbar info */
+return;
 }
 
 /*
@@ -886,133 +874,275 @@ airpcap_advanced_about_cb(GtkWidget *button, gpointer data _U_)
 static void
 add_key(GtkWidget *widget, gpointer data _U_)
 {
-GtkWidget      *text,
-                       *key_ls,
-                       *ok_bt;
+GtkWidget      *type_cm,
+                       *key_en,
+                       *ssid_en;
+                       
+GtkWidget   *key_ls;
+
+GString     *new_type_string,  
+            *new_key_string,            
+            *new_ssid_string;
 
-GString                *new_key;
+gchar          *type_entered = NULL;
+gchar          *key_entered = NULL;
+gchar          *ssid_entered = NULL;
 
-gchar          *text_entered = NULL;
+airpcap_key_ls_selected_info_t *selected_item;
 
 int keys_in_list = 0;
+
 unsigned int i;
 
-text   = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_ADD_KEY_TEXT_KEY);
-ok_bt  = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_ADD_KEY_OK_KEY);
-key_ls = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_KEYLIST_KEY);
+gint r = NO_ROW_SELECTED;
+gint c = NO_COLUMN_SELECTED;
 
-keys_in_list = g_list_length(GTK_LIST(key_ls)->children);
-text_entered = g_strdup(gtk_entry_get_text(GTK_ENTRY(text)));
+key_ls = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_ADD_KEY_LIST_KEY);
+selected_item = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
+type_cm = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_ADD_KEY_TYPE_KEY);
+key_en = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_ADD_KEY_KEY_KEY);
+ssid_en = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_ADD_KEY_SSID_KEY);
 
-/* Too many keys? */
-if(keys_in_list == MAX_ENCRYPTION_KEYS)
-       {
-       simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"%s","Reached the Wep Keys Limit for this Interface.");
-       return;
-       }
+r = selected_item->row;
+c = selected_item->column;
+
+keys_in_list = GTK_CLIST(key_ls)->rows;
+
+type_entered = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(type_cm)->entry)));
+key_entered  = g_strdup(gtk_entry_get_text(GTK_ENTRY(key_en)));
+ssid_entered = g_strdup(gtk_entry_get_text(GTK_ENTRY(ssid_en)));
 
 /* Check if key is correct */
-new_key = g_string_new(text_entered);
+new_type_string = g_string_new(type_entered);
+new_key_string = g_string_new(key_entered);
+new_ssid_string = g_string_new(ssid_entered);
+
+g_strchug(new_key_string->str);
+g_strchomp(new_key_string->str);
 
-g_strchug(new_key->str);
-g_strchomp(new_key->str);
+g_strchug(new_ssid_string->str);
+g_strchomp(new_ssid_string->str);
 
-if((new_key->len) > WEP_KEY_MAX_CHAR_SIZE)
+/* Check which type of key the user has entered */
+if(g_strcasecmp(new_type_string->str,AIRPCAP_WEP_KEY_STRING) == 0) /* WEP key */
+{
+                                                             
+if( ((new_key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((new_key_string->len) < 2))
        {
        simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"WEP key size out of range!\nValid key size range is 2-%d characters (8-%d bits).",WEP_KEY_MAX_CHAR_SIZE,WEP_KEY_MAX_SIZE*8);   
+    
+    g_string_free(new_type_string,TRUE);
+    g_string_free(new_key_string, TRUE);
+    g_string_free(new_ssid_string,TRUE);
+    
+    g_free(type_entered);
+    g_free(key_entered );
+    g_free(ssid_entered);
     return;
        }
 
-if((new_key->len % 2) != 0)
+if((new_key_string->len % 2) != 0)
        {
-       simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Wrong WEP key!\nThe number of characters must be even.");
-       return;
+       simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Invalid WEP key!\nThe number of characters must be even.");
+       
+    g_string_free(new_type_string,TRUE);
+    g_string_free(new_key_string, TRUE);
+    g_string_free(new_ssid_string,TRUE);
+    
+    g_free(type_entered);
+    g_free(key_entered );
+    g_free(ssid_entered);
+    return;
        }
 
-for(i = 0; i < new_key->len; i++)
+for(i = 0; i < new_key_string->len; i++)
        {
-       if(!g_ascii_isxdigit(new_key->str[i]))
+       if(!g_ascii_isxdigit(new_key_string->str[i]))
                {
-               simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Wrong WEP key!\nA WEP key must be an hexadecimal number.\nThe valid characters are: 0123456789ABCDEF.");
-               return;
+               simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Invalid WEP key!\nA WEP key must be a hexadecimal number.\nThe valid characters are: 0123456789ABCDEF.");
+               
+        g_string_free(new_type_string,TRUE);
+        g_string_free(new_key_string, TRUE);
+        g_string_free(new_ssid_string,TRUE);
+        
+        g_free(type_entered);
+        g_free(key_entered );
+        g_free(ssid_entered);
+        return;
                }
        }
 
-/* If so... Add key */
-airpcap_add_key_to_list(key_ls,new_key->str);
+/* If so... Modify key */
+airpcap_add_key_to_list(key_ls, new_type_string->str, new_key_string->str, new_ssid_string->str);
+
+airpcap_if_selected->saved = FALSE;    
+}
+else if(g_strcasecmp(new_type_string->str,AIRPCAP_WPA_KEY_STRING) == 0) /* WPA Key */
+{
+/* XXX - Perform some WPA related input fields check */
+/* If everything is ok, modify the entry int he list */
 
 airpcap_if_selected->saved = FALSE;
+}
+else if(g_strcasecmp(new_type_string->str,AIRPCAP_WPA2_KEY_STRING) == 0) /* WPA2 Key */
+{
+/* XXX - Perform some WPA2 related input fields check */
+/* If everything is ok, modify the entry int he list */
 
-g_string_free(new_key,TRUE);
-g_free(text_entered);
+airpcap_if_selected->saved = FALSE;
+}
+else /* Should never happen!!! */
+{ 
+simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Unknown error in the key \"Type\" field!"); 
+}
 
-window_destroy(GTK_WIDGET(data));
+g_string_free(new_type_string,TRUE);
+g_string_free(new_key_string, TRUE);
+g_string_free(new_ssid_string,TRUE);
 
+g_free(type_entered);
+g_free(key_entered );
+g_free(ssid_entered); 
+
+window_destroy(GTK_WIDGET(data));
 return;
 }
 
 /*
- * Callback used to add a WEP key in the edit key box;
+ * Callback used to edit a WEP key in the edit key box;
  */
 static void
-edit_key(GtkWidget *widget, gpointer data _U_)
+on_edit_key_ok_bt_clicked(GtkWidget *widget, gpointer data _U_)
 {
-GtkWidget      *text,
-                       *key_ls,
-                       *ok_bt;
-
-GString                *new_key;
+GtkWidget      *type_cm,
+                       *key_en,
+                       *ssid_en;
+                       
+GtkWidget   *key_ls;
 
-gchar          *text_entered = NULL;
+GString     *new_type_string,  
+            *new_key_string,            
+            *new_ssid_string;
 
-GtkWidget      *label;
+gchar          *type_entered = NULL;
+gchar          *key_entered = NULL;
+gchar          *ssid_entered = NULL;
 
+airpcap_key_ls_selected_info_t *selected_item;
 
 int keys_in_list = 0;
+
 unsigned int i;
 
-text   = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_TEXT_KEY);
-ok_bt  = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_OK_KEY);
-key_ls = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_KEYLIST_KEY);
-label   = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_LABEL_KEY);
+gint r = NO_ROW_SELECTED;
+gint c = NO_COLUMN_SELECTED;
+
+key_ls = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_LIST_KEY);
+selected_item = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_SELECTED_KEY);
+type_cm = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_TYPE_KEY);
+key_en = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_KEY_KEY);
+ssid_en = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_EDIT_KEY_SSID_KEY);
+
+r = selected_item->row;
+c = selected_item->column;
+
+keys_in_list = GTK_CLIST(key_ls)->rows;
 
-keys_in_list = g_list_length(GTK_LIST(key_ls)->children);
-text_entered = g_strdup(gtk_entry_get_text(GTK_ENTRY(text)));
+type_entered = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(type_cm)->entry)));
+key_entered  = g_strdup(gtk_entry_get_text(GTK_ENTRY(key_en)));
+ssid_entered = g_strdup(gtk_entry_get_text(GTK_ENTRY(ssid_en)));
 
 /* Check if key is correct */
-new_key = g_string_new(text_entered);
+new_type_string = g_string_new(type_entered);
+new_key_string = g_string_new(key_entered);
+new_ssid_string = g_string_new(ssid_entered);
 
-g_strchug(new_key->str);
-g_strchomp(new_key->str);
+g_strchug(new_key_string->str);
+g_strchomp(new_key_string->str);
 
-if((new_key->len) > WEP_KEY_MAX_CHAR_SIZE)
+g_strchug(new_ssid_string->str);
+g_strchomp(new_ssid_string->str);
+
+/* Check which type of key the user has entered */
+if(g_strcasecmp(new_type_string->str,AIRPCAP_WEP_KEY_STRING) == 0) /* WEP key */
+{
+                                                             
+if( ((new_key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((new_key_string->len) < 2))
        {
        simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"WEP key size out of range!\nValid key size range is 2-%d characters (8-%d bits).",WEP_KEY_MAX_CHAR_SIZE,WEP_KEY_MAX_SIZE*8);   
+    
+    g_string_free(new_type_string,TRUE);
+    g_string_free(new_key_string, TRUE);
+    g_string_free(new_ssid_string,TRUE);
+    
+    g_free(type_entered);
+    g_free(key_entered );
+    g_free(ssid_entered);
     return;
        }
 
-if((new_key->len % 2) != 0)
+if((new_key_string->len % 2) != 0)
        {
-       simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Wrong WEP key!\nThe number of characters must be even.");
-       return;
+       simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Invalid WEP key!\nThe number of characters must be even.");
+       
+    g_string_free(new_type_string,TRUE);
+    g_string_free(new_key_string, TRUE);
+    g_string_free(new_ssid_string,TRUE);
+    
+    g_free(type_entered);
+    g_free(key_entered );
+    g_free(ssid_entered);
+    return;
        }
 
-for(i = 0; i < new_key->len; i++)
+for(i = 0; i < new_key_string->len; i++)
        {
-       if(!g_ascii_isxdigit(new_key->str[i]))
+       if(!g_ascii_isxdigit(new_key_string->str[i]))
                {
-               simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Wrong WEP key!\nA WEP key must be an hexadecimal number.\nThe valid characters are: 0123456789ABCDEF.");
-               return;
+               simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Invalid WEP key!\nA WEP key must be an hexadecimal number.\nThe valid characters are: 0123456789ABCDEF.");
+               
+        g_string_free(new_type_string,TRUE);
+        g_string_free(new_key_string, TRUE);
+        g_string_free(new_ssid_string,TRUE);
+        
+        g_free(type_entered);
+        g_free(key_entered );
+        g_free(ssid_entered);
+        return;
                }
        }
 
-/* If so... modify key */
-gtk_label_set_text(GTK_LABEL(label),new_key->str);
+/* If so... Modify key */
+airpcap_modify_key_in_list(key_ls, r, new_type_string->str, new_key_string->str, new_ssid_string->str);
+
+airpcap_if_selected->saved = FALSE;    
+}
+else if(g_strcasecmp(new_type_string->str,AIRPCAP_WPA_KEY_STRING) == 0) /* WPA Key */
+{
+/* XXX - Perform some WPA related input fields check */
+/* If everything is ok, modify the entry int he list */
 
 airpcap_if_selected->saved = FALSE;
+}
+else if(g_strcasecmp(new_type_string->str,AIRPCAP_WPA2_KEY_STRING) == 0) /* WPA2 Key */
+{
+/* XXX - Perform some WPA2 related input fields check */
+/* If everything is ok, modify the entry int he list */
 
-g_string_free(new_key,TRUE);
-g_free(text_entered);
+airpcap_if_selected->saved = FALSE;
+}
+else /* Should never happen!!! */
+{ 
+simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Unknown error in the key \"Type\" field!"); 
+}
+
+g_string_free(new_type_string,TRUE);
+g_string_free(new_key_string, TRUE);
+g_string_free(new_ssid_string,TRUE);
+
+g_free(type_entered);
+g_free(key_entered );
+g_free(ssid_entered); 
 
 window_destroy(GTK_WIDGET(data));
 return;
@@ -1021,120 +1151,223 @@ return;
 /*
  * Callback for the 'Add Key' button.
  */
-static void
-airpcap_advanced_add_key_cb(GtkWidget *button, gpointer data _U_)
+void
+on_add_new_key_bt_clicked(GtkWidget *button, gpointer data _U_)
 {
-/* Window */
-GtkWidget      *add_key_w;
+GtkWidget *add_key_window;
+GtkWidget *add_frame;
+GtkWidget *main_v_box;
+GtkWidget *add_tb;
+GtkWidget *add_frame_al;
+GtkWidget *add_type_cm;
+GList *add_type_cm_items = NULL;
+GtkWidget *add_type_en;
+GtkWidget *add_key_te;
+GtkWidget *add_ssid_te;
+GtkWidget *add_type_lb;
+GtkWidget *add_key_lb;
+GtkWidget *add_ssid_lb;
+GtkWidget *low_h_button_box;
+GtkWidget *ok_bt;
+GtkWidget *cancel_bt;
+GtkWidget *add_frame_lb;
+
+GtkWidget *airpcap_advanced_w;
 
-/*  Frame */
-GtkWidget      *add_key_frame;
+/* Key List Widget */
+GtkWidget      *key_ls;
 
-/* Boxes */
-GtkWidget      *main_box,      /* vertical */
-                       *key_box,       /* orizontal */
-                       *text_box,  /* orizontal */
-                       *button_box;/* orizontal (packed to end)*/
+gint keys_in_list = 0;
 
-/* Text Entry */
-GtkWidget      *key_text_entry;
+/* Selected entry in the key list (if any)*/
+airpcap_key_ls_selected_info_t* selected_item;
 
-/* Buttons */
-GtkWidget      *key_ok_bt,
-                       *key_cancel_bt;
+GList *item = NULL;
+gint r,c;
 
-/* Key List Widget */
-GtkWidget      *key_ls;
+airpcap_advanced_w = GTK_WIDGET(data);
 
-       /* Pop-up a new window */
-       add_key_w = window_new (GTK_WINDOW_TOPLEVEL,"Add a WEP Key");
-
-       /* Connect events */
-    SIGNAL_CONNECT(add_key_w, "delete_event",window_delete_event_cb, add_key_w);
-    SIGNAL_CONNECT(add_key_w, "destroy",add_key_w_destroy_cb, add_key_w);
-
-       /* Sets the border width of the window. */
-       gtk_container_set_border_width (GTK_CONTAINER (add_key_w), 5);
-
-       /* Retrieve the key list widget pointer, and add it to the add_key_w */
-       key_ls = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_KEYLIST_KEY);
-       OBJECT_SET_DATA(GTK_WIDGET(add_key_w),AIRPCAP_ADVANCED_KEYLIST_KEY,key_ls);
-       OBJECT_SET_DATA(GTK_WIDGET(add_key_w),AIRPCAP_ADVANCED_KEY,data);
-
-       /* Create boxes */
-       main_box = gtk_vbox_new(FALSE,1);
-       key_box = gtk_hbox_new(FALSE,1);
-       button_box = gtk_hbox_new(FALSE,1);
-       text_box = gtk_hbox_new(TRUE,1);
-
-       /* Add the two sub boxes to the main box */
-       gtk_box_pack_start(GTK_BOX(main_box), key_box, FALSE, FALSE, 1);
-       gtk_box_pack_start(GTK_BOX(main_box), button_box, FALSE, FALSE, 1);
-
-       /* Add the main box to the main window */
-       gtk_container_add(GTK_CONTAINER(add_key_w),main_box);
-
-       /* Crete key frame */
-       add_key_frame = gtk_frame_new("");
-       gtk_frame_set_label(GTK_FRAME(add_key_frame),"Key");
-       #if GTK_MAJOR_VERSION < 2
-       gtk_widget_set_usize( GTK_WIDGET(add_key_frame),
-                                  200,
-                                  -1 );
-       #else
-       gtk_widget_set_size_request( GTK_WIDGET(add_key_frame),
-                                  200,
-                                  -1 );
-    #endif
+/* Retrieve the selected item... if no row is selected, this is null... */
+selected_item = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
 
-       gtk_box_pack_start(GTK_BOX(key_box), add_key_frame, FALSE, FALSE, 1);
-
-       /* Create and Add text entry*/
-       key_text_entry = gtk_entry_new();
-       OBJECT_SET_DATA(add_key_w, AIRPCAP_ADVANCED_ADD_KEY_TEXT_KEY, key_text_entry);
-       SIGNAL_CONNECT(key_text_entry, "activate", add_key, add_key_w );
-       gtk_box_pack_start(GTK_BOX(text_box), key_text_entry, FALSE, FALSE, 1);
-       gtk_container_add(GTK_CONTAINER(add_key_frame),text_box);
-       gtk_container_set_border_width (GTK_CONTAINER (text_box), 5);
-
-       /* Create and add buttons */
-       key_ok_bt = gtk_button_new_with_label("OK");
-       SIGNAL_CONNECT(key_ok_bt, "clicked", add_key, add_key_w );
-       OBJECT_SET_DATA(add_key_w, AIRPCAP_ADVANCED_ADD_KEY_OK_KEY, key_ok_bt);
-               #if GTK_MAJOR_VERSION < 2
-       gtk_widget_set_usize( GTK_WIDGET(key_ok_bt),
-                                  50,
-                                  -1 );
-       #else
-       gtk_widget_set_size_request( GTK_WIDGET(key_ok_bt),
-                                  50,
-                                  -1 );
-    #endif
-       key_cancel_bt = gtk_button_new_with_label("Cancel");
-       SIGNAL_CONNECT(key_cancel_bt, "clicked", window_cancel_button_cb, add_key_w );
-               #if GTK_MAJOR_VERSION < 2
-       gtk_widget_set_usize( GTK_WIDGET(key_cancel_bt),
-                                  50,
-                                  -1 );
-       #else
-       gtk_widget_set_size_request( GTK_WIDGET(key_cancel_bt),
-                                  50,
-                                  -1 );
-    #endif
+r = selected_item->row;
+c = selected_item->column;
+
+/* Retrieve the key list widget pointer, and add it to the add_key_w */
+key_ls = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEYLIST_KEY);
+
+keys_in_list = GTK_CLIST(key_ls)->rows;
 
-       gtk_box_pack_end(GTK_BOX(button_box), key_cancel_bt, FALSE, FALSE, 1);
-       gtk_box_pack_end(GTK_BOX(button_box), key_ok_bt, FALSE, FALSE, 1);
+if(keys_in_list >= MAX_ENCRYPTION_KEYS) /* Check if we have already reached the maximum number of allowed keys... */
+{
+       simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"Maximum number (%d) of decryption keys reached! You cannot add another key!\n",MAX_ENCRYPTION_KEYS);   
+    return;
+}
+
+/* Gray out the Advanced Wireless Setting window */
+gtk_widget_set_sensitive(airpcap_advanced_w,FALSE);
+
+/* Pop-up a new window */   
+add_key_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+gtk_widget_set_name (add_key_window, "add_key_window");
+gtk_container_set_border_width (GTK_CONTAINER (add_key_window), 5);
+gtk_window_set_title (GTK_WINDOW (add_key_window), "Add Decryption Key");
+#if GTK_MAJOR_VERSION >= 2
+gtk_window_set_resizable (GTK_WINDOW (add_key_window), FALSE);
+#else
+gtk_window_set_policy(GTK_WINDOW(add_key_window), FALSE, FALSE, TRUE);
+#endif
+
+main_v_box = gtk_vbox_new (FALSE, 0);
+gtk_widget_set_name (main_v_box, "main_v_box");
+gtk_widget_show (main_v_box);
+gtk_container_add (GTK_CONTAINER (add_key_window), main_v_box);
+
+add_frame = gtk_frame_new (NULL);
+gtk_widget_set_name (add_frame, "add_frame");
+gtk_widget_show (add_frame);
+gtk_box_pack_start (GTK_BOX (main_v_box), add_frame, TRUE, TRUE, 0);
+
+add_frame_al = gtk_alignment_new (0.5, 0.5, 1, 1);
+gtk_widget_set_name (add_frame_al, "add_frame_al");
+gtk_widget_show (add_frame_al);
+gtk_container_add (GTK_CONTAINER (add_frame), add_frame_al);
+#if GTK_MAJOR_VERSION >= 2
+gtk_alignment_set_padding (GTK_ALIGNMENT (add_frame_al), 0, 0, 12, 0);
+#else
+gtk_alignment_set (GTK_ALIGNMENT (add_frame_al), 0, 0, 12, 0);
+#endif
 
-       /* Show all */
-       gtk_widget_show(key_ok_bt);
-       gtk_widget_show(key_cancel_bt);
-       gtk_widget_show(key_text_entry);
-       gtk_widget_show(add_key_frame);
-       gtk_widget_show(text_box);
-       gtk_widget_show(button_box);
-       gtk_widget_show(key_box);
-       gtk_widget_show(main_box);
-       gtk_widget_show(add_key_w);
+add_tb = gtk_table_new (2, 3, FALSE);
+gtk_widget_set_name (add_tb, "add_tb");
+gtk_container_set_border_width(GTK_CONTAINER(add_tb),5);
+gtk_widget_show (add_tb);
+gtk_container_add (GTK_CONTAINER (add_frame_al), add_tb);
+
+add_type_cm = gtk_combo_new ();
+gtk_widget_set_name (add_type_cm, "add_type_cm");
+gtk_widget_show (add_type_cm);
+gtk_table_attach (GTK_TABLE (add_tb), add_type_cm, 0, 1, 1, 2,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+#if GTK_MAJOR_VERSION >= 2
+gtk_widget_set_size_request (add_type_cm, 63, -1);
+#else
+gtk_widget_set_usize (add_type_cm, 63, -1);
+#endif
+add_type_cm_items = g_list_append (add_type_cm_items, (gpointer) AIRPCAP_WEP_KEY_STRING);
+
+/* XXX - DEcomment only when WPA and WPA2 will be ready */
+/*
+add_type_cm_items = g_list_append (add_type_cm_items, (gpointer) AIRPCAP_WPA_KEY_STRING);
+add_type_cm_items = g_list_append (add_type_cm_items, (gpointer) AIRPCAP_WPA2_KEY_STRING);*/
+gtk_combo_set_popdown_strings (GTK_COMBO (add_type_cm),
+                        add_type_cm_items);
+g_list_free (add_type_cm_items);
+
+add_type_en = GTK_COMBO (add_type_cm)->entry;
+gtk_widget_set_name (add_type_en, "add_type_en");
+gtk_editable_set_editable (GTK_EDITABLE (add_type_en), FALSE);
+gtk_widget_show (add_type_en);
+
+add_key_te = gtk_entry_new ();
+gtk_widget_set_name (add_key_te, "add_key_te");
+
+gtk_widget_show (add_key_te);
+gtk_table_attach (GTK_TABLE (add_tb), add_key_te, 1, 2, 1, 2,
+           (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0);
+#if GTK_MAJOR_VERSION >= 2
+gtk_widget_set_size_request (add_key_te, 178, -1);
+#else
+gtk_widget_set_usize (add_key_te, 178, -1);
+#endif
+
+add_ssid_te = gtk_entry_new ();
+gtk_widget_set_name (add_ssid_te, "add_ssid_te");
+gtk_widget_set_sensitive(add_ssid_te,FALSE);
+/* XXX - Decomment only when WPA and WPA2 will be ready */
+/* gtk_widget_show (add_ssid_te); */
+gtk_table_attach (GTK_TABLE (add_tb), add_ssid_te, 2, 3, 1, 2,
+           (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0);
+
+add_type_lb = gtk_label_new ("Type");
+gtk_widget_set_name (add_type_lb, "add_type_lb");
+gtk_widget_show (add_type_lb);
+gtk_table_attach (GTK_TABLE (add_tb), add_type_lb, 0, 1, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_label_set_justify (GTK_LABEL (add_type_lb), GTK_JUSTIFY_CENTER);
+
+add_key_lb = gtk_label_new ("Key");
+gtk_widget_set_name (add_key_lb, "add_key_lb");
+gtk_widget_show (add_key_lb); 
+gtk_table_attach (GTK_TABLE (add_tb), add_key_lb, 1, 2, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_label_set_justify (GTK_LABEL (add_key_lb), GTK_JUSTIFY_CENTER);
+
+add_ssid_lb = gtk_label_new ("SSID");
+gtk_widget_set_name (add_ssid_lb, "add_ssid_lb");
+/* XXX - Decomment only when WPA and WPA2 will be ready */
+/* gtk_widget_show (add_ssid_lb); */
+gtk_table_attach (GTK_TABLE (add_tb), add_ssid_lb, 2, 3, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_label_set_justify (GTK_LABEL (add_ssid_lb), GTK_JUSTIFY_CENTER);
+
+low_h_button_box = gtk_hbutton_box_new ();
+gtk_widget_set_name (low_h_button_box, "low_h_button_box");
+ gtk_container_set_border_width (GTK_CONTAINER (low_h_button_box), 5);
+gtk_widget_show (low_h_button_box);
+gtk_box_pack_end (GTK_BOX (main_v_box), low_h_button_box, FALSE, FALSE, 0);
+gtk_button_box_set_layout (GTK_BUTTON_BOX (low_h_button_box),
+                    GTK_BUTTONBOX_END);
+
+#if GTK_MAJOR_VERISON >= 2
+ok_bt = gtk_button_new_with_mnemonic ("Ok");
+#else
+ok_bt = gtk_button_new_with_label ("Ok");
+#endif
+gtk_widget_set_name (ok_bt, "ok_bt");
+gtk_widget_show (ok_bt);
+gtk_container_add (GTK_CONTAINER (low_h_button_box), ok_bt);
+GTK_WIDGET_SET_FLAGS (ok_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERISON >= 2
+cancel_bt = gtk_button_new_with_mnemonic ("Cancel");
+#else
+cancel_bt = gtk_button_new_with_label ("Cancel");
+#endif
+gtk_widget_set_name (cancel_bt, "cancel_bt");
+gtk_widget_show (cancel_bt);
+gtk_container_add (GTK_CONTAINER (low_h_button_box), cancel_bt);
+GTK_WIDGET_SET_FLAGS (cancel_bt, GTK_CAN_DEFAULT);
+
+add_frame_lb = gtk_label_new ("<b>Modify Selected Key</b>");
+gtk_widget_set_name (add_frame_lb, "add_frame_lb");
+gtk_widget_show (add_frame_lb);
+#if GTK_MAJOR_VERSION >= 2
+gtk_frame_set_label_widget (GTK_FRAME (add_frame), add_frame_lb);
+gtk_label_set_use_markup (GTK_LABEL (add_frame_lb), TRUE);
+#else
+gtk_frame_set_label (GTK_FRAME (add_frame), "Modify Selected Key");
+#endif
+
+/* Add callbacks */
+SIGNAL_CONNECT(ok_bt, "clicked", add_key, add_key_window );
+SIGNAL_CONNECT(cancel_bt, "clicked", window_cancel_button_cb, add_key_window );
+SIGNAL_CONNECT(add_type_en, "changed",on_add_type_en_changed, add_key_window);
+SIGNAL_CONNECT(add_key_window, "delete_event",window_delete_event_cb, add_key_window);
+SIGNAL_CONNECT(add_key_window, "destroy",on_add_key_w_destroy, data);
+
+/* Add widget data */
+OBJECT_SET_DATA(add_key_window,AIRPCAP_ADVANCED_ADD_KEY_LIST_KEY,key_ls);
+OBJECT_SET_DATA(add_key_window,AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY,selected_item);
+OBJECT_SET_DATA(add_key_window,AIRPCAP_ADVANCED_ADD_KEY_TYPE_KEY,add_type_cm);
+OBJECT_SET_DATA(add_key_window,AIRPCAP_ADVANCED_ADD_KEY_KEY_KEY,add_key_te);
+OBJECT_SET_DATA(add_key_window,AIRPCAP_ADVANCED_ADD_KEY_SSID_KEY,add_ssid_te);
+
+gtk_widget_show(add_key_window);
 }
 
 /*
@@ -1149,37 +1382,75 @@ return;
 /*
  * Edit key window destroy callback
  */
-static void
-edit_key_w_destroy_cb(GtkWidget *button, gpointer data _U_)
+void
+on_edit_key_w_destroy(GtkWidget *button, gpointer data _U_)
+{
+GtkWidget *airpcap_advanced_w;
+
+airpcap_advanced_w = GTK_WIDGET(data);
+
+gtk_widget_set_sensitive(GTK_WIDGET(airpcap_advanced_w),TRUE);
+
+return;
+}
+
+/*
+ * Add key window destroy callback
+ */
+void
+on_add_key_w_destroy(GtkWidget *button, gpointer data _U_)
 {
+GtkWidget *airpcap_advanced_w;
+
+airpcap_advanced_w = GTK_WIDGET(data);
+
+gtk_widget_set_sensitive(GTK_WIDGET(airpcap_advanced_w),TRUE);
+
 return;
 }
 
 /*
  * Callback for the 'Remove Key' button.
  */
-static void
-airpcap_advanced_remove_key_cb(GtkWidget *button, gpointer data _U_)
+void
+on_remove_key_bt_clicked(GtkWidget *button, gpointer data _U_)
 {
-GtkList *key_ls;
-GtkWidget *label;
-GList *item = NULL;
-gint n;
+GtkWidget *key_ls;
+GtkWidget *airpcap_advanced_w;
 
-/* retrieve key list */
-key_ls = GTK_LIST(data);
+gint keys_in_list;
 
-/* Remove selected keys*/
-if(key_ls->selection != NULL)
-       {
-       item = g_list_nth(key_ls->selection,0);
-       if(item != NULL)
-               {
-               n = gtk_list_child_position(key_ls,item->data);
-               label = GTK_BIN(item->data)->child;
-               gtk_list_clear_items(key_ls,n,n+1);
-               }
-       }
+airpcap_key_ls_selected_info_t *selected_item;
+
+gint c = NO_COLUMN_SELECTED;
+gint r = NO_ROW_SELECTED;
+
+airpcap_advanced_w = GTK_WIDGET(data);
+
+/* retrieve needed stuff */
+key_ls        = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEYLIST_KEY);
+selected_item = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
+
+/* 
+ * Better to store the selected_item data in two new variables, because maybe some 
+ * select_row signal will be emitted somewhere...
+ */
+r = selected_item->row;
+c = selected_item->column;
+
+keys_in_list = GTK_CLIST(key_ls)->rows;
+
+if( r == NO_ROW_SELECTED ) /* No key selected */
+    return;
+
+/* Remove selected key*/
+gtk_clist_remove(GTK_CLIST(key_ls),r);
+
+/* Reselect another row, if any... */
+if( r < (keys_in_list-1) )
+    gtk_clist_select_row(GTK_CLIST(key_ls),r,c);
+else
+    gtk_clist_select_row(GTK_CLIST(key_ls),r-1,c);  
 
 /* Need to save config... */
 airpcap_if_selected->saved = FALSE;
@@ -1188,188 +1459,285 @@ airpcap_if_selected->saved = FALSE;
 /*
  * Callback for the 'Edit Key' button.
  */
-static void
-airpcap_advanced_edit_key_cb(GtkWidget *button, gpointer data _U_)
+void
+on_edit_key_bt_clicked(GtkWidget *button, gpointer data _U_)
 {
-/* Window */
-GtkWidget      *edit_key_w;
+GtkWidget *edit_key_window;
+GtkWidget *edit_frame;
+GtkWidget *main_v_box;
+GtkWidget *edit_tb;
+GtkWidget *edit_frame_al;
+GtkWidget *edit_type_cm;
+GList *edit_type_cm_items = NULL;
+GtkWidget *edit_type_en;
+GtkWidget *edit_key_te;
+GtkWidget *edit_ssid_te;
+GtkWidget *edit_type_lb;
+GtkWidget *edit_key_lb;
+GtkWidget *edit_ssid_lb;
+GtkWidget *low_h_button_box;
+GtkWidget *ok_bt;
+GtkWidget *cancel_bt;
+GtkWidget *edit_frame_lb;
+
+GtkWidget *airpcap_advanced_w;
 
-/*  Frame */
-GtkWidget      *edit_key_frame;
+/* Key List Widget */
+GtkWidget      *key_ls;
 
-/* Boxes */
-GtkWidget      *main_box,      /* vertical */
-                       *key_box,       /* orizontal */
-                       *text_box,  /* orizontal */
-                       *button_box;/* orizontal (packed to end)*/
+/* Selected entry in the key list (if any)*/
+airpcap_key_ls_selected_info_t* selected_item;
 
-/* Text Entry */
-GtkWidget      *key_text_entry;
+gchar *row_type,
+      *row_key,
+      *row_ssid;
 
-/* Buttons */
-GtkWidget      *key_ok_bt,
-                       *key_cancel_bt;
+GList *item = NULL;
+gint r,c;
 
-/* Key List Widget */
-GtkWidget      *key_ls;
+airpcap_advanced_w = GTK_WIDGET(data);
 
-GtkWidget *label;
-GList *item = NULL;
-gint n;
+/* Retrieve the selected item... if no row is selected, this is null... */
+selected_item = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
+
+r = selected_item->row;
+c = selected_item->column;
 
 /* Retrieve the key list widget pointer, and add it to the edit_key_w */
-key_ls = OBJECT_GET_DATA(GTK_WIDGET(data),AIRPCAP_ADVANCED_KEYLIST_KEY);
+key_ls = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEYLIST_KEY);
 
-/*
- * Check if a key has been selected. If not, just do nothing.
- */
-if(GTK_LIST(key_ls)->selection != NULL)
+if((r != NO_ROW_SELECTED) && (c != NO_COLUMN_SELECTED))
     {
-    item = g_list_nth(GTK_LIST(key_ls)->selection,0);
-    if(item != NULL)
-       {
-       /* Pop-up a new window */
-       edit_key_w = window_new (GTK_WINDOW_TOPLEVEL,"Edit a WEP Key");
-
-       /* Connect events */
-        SIGNAL_CONNECT(edit_key_w, "delete_event",window_delete_event_cb, edit_key_w);
-        SIGNAL_CONNECT(edit_key_w, "destroy",edit_key_w_destroy_cb, edit_key_w);
-
-       /* Sets the border width of the window. */
-       gtk_container_set_border_width (GTK_CONTAINER (edit_key_w), 5);
-
-       OBJECT_SET_DATA(GTK_WIDGET(edit_key_w),AIRPCAP_ADVANCED_KEYLIST_KEY,key_ls);
-       OBJECT_SET_DATA(GTK_WIDGET(edit_key_w),AIRPCAP_ADVANCED_KEY,data);
-
-       /* Create boxes */
-       main_box = gtk_vbox_new(FALSE,1);
-       key_box = gtk_hbox_new(FALSE,1);
-       button_box = gtk_hbox_new(FALSE,1);
-       text_box = gtk_hbox_new(TRUE,1);
-
-       /* Add the two sub boxes to the main box */
-       gtk_box_pack_start(GTK_BOX(main_box), key_box, FALSE, FALSE, 1);
-       gtk_box_pack_start(GTK_BOX(main_box), button_box, FALSE, FALSE, 1);
-
-       /* Add the main box to the main window */
-       gtk_container_add(GTK_CONTAINER(edit_key_w),main_box);
-
-       /* Crete key frame */
-       edit_key_frame = gtk_frame_new("");
-       gtk_frame_set_label(GTK_FRAME(edit_key_frame),"Key");
-       #if GTK_MAJOR_VERSION < 2
-       gtk_widget_set_usize( GTK_WIDGET(edit_key_frame),
-                                      200,
-                                      -1 );
-       #else
-       gtk_widget_set_size_request( GTK_WIDGET(edit_key_frame),
-                                      200,
-                                      -1 );
-        #endif
-
-       gtk_box_pack_start(GTK_BOX(key_box), edit_key_frame, FALSE, FALSE, 1);
-
-       /* Create and Add text entry*/
-       key_text_entry = gtk_entry_new();
-       /* Retrieve the currently selected entry */
-       if(GTK_LIST(key_ls)->selection != NULL)
-               {
-               item = g_list_nth(GTK_LIST(key_ls)->selection,0);
-               if(item != NULL)
-                       {
-                       n = gtk_list_child_position(GTK_LIST(key_ls),item->data);
-                       label = GTK_BIN(item->data)->child;
-                       /* Pass the pointer as data */
-                       OBJECT_SET_DATA(edit_key_w,AIRPCAP_ADVANCED_EDIT_KEY_LABEL_KEY,label);
-                       }
-               }
-       gtk_entry_set_text(GTK_ENTRY(key_text_entry),GTK_LABEL(label)->label);
-       OBJECT_SET_DATA(edit_key_w, AIRPCAP_ADVANCED_EDIT_KEY_TEXT_KEY, key_text_entry);
-       SIGNAL_CONNECT(key_text_entry, "activate", edit_key, edit_key_w );
-       gtk_box_pack_start(GTK_BOX(text_box), key_text_entry, FALSE, FALSE, 1);
-       gtk_container_add(GTK_CONTAINER(edit_key_frame),text_box);
-       gtk_container_set_border_width (GTK_CONTAINER (text_box), 5);
-
-       /* Create and add buttons */
-       key_ok_bt = gtk_button_new_with_label("OK");
-       SIGNAL_CONNECT(key_ok_bt, "clicked", edit_key, edit_key_w );
-       OBJECT_SET_DATA(edit_key_w, AIRPCAP_ADVANCED_EDIT_KEY_OK_KEY, key_ok_bt);
-               #if GTK_MAJOR_VERSION < 2
-       gtk_widget_set_usize( GTK_WIDGET(key_ok_bt),
-                                      50,
-                                      -1 );
-       #else
-       gtk_widget_set_size_request( GTK_WIDGET(key_ok_bt),
-                                      50,
-                                      -1 );
-        #endif
-       key_cancel_bt = gtk_button_new_with_label("Cancel");
-       SIGNAL_CONNECT(key_cancel_bt, "clicked", window_cancel_button_cb, edit_key_w );
-               #if GTK_MAJOR_VERSION < 2
-       gtk_widget_set_usize( GTK_WIDGET(key_cancel_bt),
-                                      50,
-                                      -1 );
-       #else
-       gtk_widget_set_size_request( GTK_WIDGET(key_cancel_bt),
-                                      50,
-                                      -1 );
-        #endif
-
-       gtk_box_pack_end(GTK_BOX(button_box), key_cancel_bt, FALSE, FALSE, 1);
-       gtk_box_pack_end(GTK_BOX(button_box), key_ok_bt, FALSE, FALSE, 1);
-
-       /* Show all */
-       gtk_widget_show(key_ok_bt);
-       gtk_widget_show(key_cancel_bt);
-       gtk_widget_show(key_text_entry);
-       gtk_widget_show(edit_key_frame);
-       gtk_widget_show(text_box);
-       gtk_widget_show(button_box);
-       gtk_widget_show(key_box);
-       gtk_widget_show(main_box);
-       gtk_widget_show(edit_key_w);
-        }
+    gtk_clist_get_text(GTK_CLIST(key_ls),r,0,&row_type);
+    gtk_clist_get_text(GTK_CLIST(key_ls),r,1,&row_key);
+    gtk_clist_get_text(GTK_CLIST(key_ls),r,2,&row_ssid);
+    
+    /* Gray out the Advanced Wireless Setting window */
+    gtk_widget_set_sensitive(airpcap_advanced_w,FALSE);
+    
+    /* Pop-up a new window */   
+    edit_key_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_name (edit_key_window, "edit_key_window");
+    gtk_container_set_border_width (GTK_CONTAINER (edit_key_window), 5);
+    gtk_window_set_title (GTK_WINDOW (edit_key_window), "Edit Decryption Key");
+    #if GTK_MAJOR_VERSION >= 2
+    gtk_window_set_resizable (GTK_WINDOW (edit_key_window), FALSE);
+    #else
+    gtk_window_set_policy(GTK_WINDOW(edit_key_window), FALSE, FALSE, TRUE);
+    #endif
+    
+    main_v_box = gtk_vbox_new (FALSE, 0);
+    gtk_widget_set_name (main_v_box, "main_v_box");
+    gtk_widget_show (main_v_box);
+    gtk_container_add (GTK_CONTAINER (edit_key_window), main_v_box);
+    
+    edit_frame = gtk_frame_new (NULL);
+    gtk_widget_set_name (edit_frame, "edit_frame");
+    gtk_widget_show (edit_frame);
+    gtk_box_pack_start (GTK_BOX (main_v_box), edit_frame, TRUE, TRUE, 0);
+    
+    edit_frame_al = gtk_alignment_new (0.5, 0.5, 1, 1);
+    gtk_widget_set_name (edit_frame_al, "edit_frame_al");
+    gtk_widget_show (edit_frame_al);
+    gtk_container_add (GTK_CONTAINER (edit_frame), edit_frame_al);
+    #if GTK_MAJOR_VERSION >= 2
+    gtk_alignment_set_padding (GTK_ALIGNMENT (edit_frame_al), 0, 0, 12, 0);
+    #else
+    gtk_alignment_set (GTK_ALIGNMENT (edit_frame_al), 0, 0, 12, 0);
+    #endif
+    
+    edit_tb = gtk_table_new (2, 3, FALSE);
+    gtk_widget_set_name (edit_tb, "edit_tb");
+    gtk_container_set_border_width(GTK_CONTAINER(edit_tb),5);
+    gtk_widget_show (edit_tb);
+    gtk_container_add (GTK_CONTAINER (edit_frame_al), edit_tb);
+    
+    edit_type_cm = gtk_combo_new ();
+    gtk_widget_set_name (edit_type_cm, "edit_type_cm");
+    gtk_widget_show (edit_type_cm);
+    gtk_table_attach (GTK_TABLE (edit_tb), edit_type_cm, 0, 1, 1, 2,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+    #if GTK_MAJOR_VERSION >= 2
+    gtk_widget_set_size_request (edit_type_cm, 63, -1);
+    #else
+    gtk_widget_set_usize (edit_type_cm, 63, -1);
+    #endif
+    edit_type_cm_items = g_list_append (edit_type_cm_items, (gpointer) AIRPCAP_WEP_KEY_STRING);
+    /* XXX - Decomment only when WPA and WPA2 support will be ready!!! */
+/*  edit_type_cm_items = g_list_append (edit_type_cm_items, (gpointer) AIRPCAP_WPA_KEY_STRING);
+    edit_type_cm_items = g_list_append (edit_type_cm_items, (gpointer) AIRPCAP_WPA2_KEY_STRING);*/
+    gtk_combo_set_popdown_strings (GTK_COMBO (edit_type_cm),
+                        edit_type_cm_items);
+    g_list_free (edit_type_cm_items);
+    
+    edit_type_en = GTK_COMBO (edit_type_cm)->entry;
+    gtk_widget_set_name (edit_type_en, "edit_type_en");
+    /* Set current type */
+    gtk_entry_set_text(GTK_ENTRY(edit_type_en),row_type);
+    gtk_editable_set_editable (GTK_EDITABLE (edit_type_en), FALSE);
+    gtk_widget_show (edit_type_en);
+    
+    edit_key_te = gtk_entry_new ();
+    gtk_widget_set_name (edit_key_te, "edit_key_te");
+    /* Set current key */
+    gtk_entry_set_text(GTK_ENTRY(edit_key_te),row_key);
+    gtk_widget_show (edit_key_te);
+    gtk_table_attach (GTK_TABLE (edit_tb), edit_key_te, 1, 2, 1, 2,
+           (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0);
+    #if GTK_MAJOR_VERSION >= 2
+    gtk_widget_set_size_request (edit_key_te, 178, -1);
+    #else
+    gtk_widget_set_usize (edit_key_te, 178, -1);
+    #endif
+    
+    edit_ssid_te = gtk_entry_new ();
+    gtk_widget_set_name (edit_ssid_te, "edit_ssid_te");
+
+    /* Set current ssid (if key type is not WEP!)*/
+    if(g_strcasecmp(row_type,AIRPCAP_WEP_KEY_STRING) == 0)
+    {
+    gtk_widget_set_sensitive(edit_ssid_te,FALSE);
+    }
+    else
+    {
+    gtk_widget_set_sensitive(edit_ssid_te,TRUE);
+    gtk_entry_set_text(GTK_ENTRY(edit_ssid_te),row_ssid);
+    }
+    
+    /* XXX - Decomment only when WPA and WPA@ will be ready */
+    /* gtk_widget_show (edit_ssid_te); */
+    gtk_table_attach (GTK_TABLE (edit_tb), edit_ssid_te, 2, 3, 1, 2,
+           (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0);
+    
+    edit_type_lb = gtk_label_new ("Type");
+    gtk_widget_set_name (edit_type_lb, "edit_type_lb");
+    gtk_widget_show (edit_type_lb);
+    gtk_table_attach (GTK_TABLE (edit_tb), edit_type_lb, 0, 1, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+    gtk_label_set_justify (GTK_LABEL (edit_type_lb), GTK_JUSTIFY_CENTER);
+    
+    edit_key_lb = gtk_label_new ("Key");
+    gtk_widget_set_name (edit_key_lb, "edit_key_lb");
+    gtk_widget_show (edit_key_lb);
+    gtk_table_attach (GTK_TABLE (edit_tb), edit_key_lb, 1, 2, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+    gtk_label_set_justify (GTK_LABEL (edit_key_lb), GTK_JUSTIFY_CENTER);
+    
+    edit_ssid_lb = gtk_label_new ("SSID");
+    gtk_widget_set_name (edit_ssid_lb, "edit_ssid_lb");
+    /* XXX - Decomment only when WPA and WPA2 will be ready */
+    /* gtk_widget_show (edit_ssid_lb); */
+    gtk_table_attach (GTK_TABLE (edit_tb), edit_ssid_lb, 2, 3, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+    gtk_label_set_justify (GTK_LABEL (edit_ssid_lb), GTK_JUSTIFY_CENTER);
+    
+    low_h_button_box = gtk_hbutton_box_new ();
+    gtk_widget_set_name (low_h_button_box, "low_h_button_box");
+     gtk_container_set_border_width (GTK_CONTAINER (low_h_button_box), 5);
+    gtk_widget_show (low_h_button_box);
+    gtk_box_pack_end (GTK_BOX (main_v_box), low_h_button_box, FALSE, FALSE, 0);
+    gtk_button_box_set_layout (GTK_BUTTON_BOX (low_h_button_box),
+                    GTK_BUTTONBOX_END);
+    
+    #if GTK_MAJOR_VERISON >= 2
+    ok_bt = gtk_button_new_with_mnemonic ("Ok");
+    #else
+    ok_bt = gtk_button_new_with_label ("Ok");
+    #endif
+    gtk_widget_set_name (ok_bt, "ok_bt");
+    gtk_widget_show (ok_bt);
+    gtk_container_add (GTK_CONTAINER (low_h_button_box), ok_bt);
+    GTK_WIDGET_SET_FLAGS (ok_bt, GTK_CAN_DEFAULT);
+    
+    #if GTK_MAJOR_VERISON >= 2
+    cancel_bt = gtk_button_new_with_mnemonic ("Cancel");
+    #else
+    cancel_bt = gtk_button_new_with_label ("Cancel");
+    #endif
+    gtk_widget_set_name (cancel_bt, "cancel_bt");
+    gtk_widget_show (cancel_bt);
+    gtk_container_add (GTK_CONTAINER (low_h_button_box), cancel_bt);
+    GTK_WIDGET_SET_FLAGS (cancel_bt, GTK_CAN_DEFAULT);
+    
+    edit_frame_lb = gtk_label_new ("<b>Modify Selected Key</b>");
+    gtk_widget_set_name (edit_frame_lb, "edit_frame_lb");
+    gtk_widget_show (edit_frame_lb);
+    #if GTK_MAJOR_VERSION >= 2
+    gtk_frame_set_label_widget (GTK_FRAME (edit_frame), edit_frame_lb);
+    gtk_label_set_use_markup (GTK_LABEL (edit_frame_lb), TRUE);
+    #else
+    gtk_frame_set_label (GTK_FRAME (edit_frame), "Modify Selected Key");
+    #endif
+    
+    /* Add callbacks */
+    SIGNAL_CONNECT(ok_bt, "clicked", on_edit_key_ok_bt_clicked, edit_key_window );
+    SIGNAL_CONNECT(cancel_bt, "clicked", window_cancel_button_cb, edit_key_window );
+    SIGNAL_CONNECT(edit_type_en, "changed",on_edit_type_en_changed, edit_key_window);
+    SIGNAL_CONNECT(edit_key_window, "delete_event",window_delete_event_cb, edit_key_window);
+    SIGNAL_CONNECT(edit_key_window, "destroy",on_edit_key_w_destroy, data);
+    
+    /* Add widget data */
+    OBJECT_SET_DATA(edit_key_window,AIRPCAP_ADVANCED_EDIT_KEY_LIST_KEY,key_ls);
+    OBJECT_SET_DATA(edit_key_window,AIRPCAP_ADVANCED_EDIT_KEY_SELECTED_KEY,selected_item);
+    OBJECT_SET_DATA(edit_key_window,AIRPCAP_ADVANCED_EDIT_KEY_TYPE_KEY,edit_type_cm);
+    OBJECT_SET_DATA(edit_key_window,AIRPCAP_ADVANCED_EDIT_KEY_KEY_KEY,edit_key_te);
+    OBJECT_SET_DATA(edit_key_window,AIRPCAP_ADVANCED_EDIT_KEY_SSID_KEY,edit_ssid_te);
+    
+    gtk_widget_show(edit_key_window);
     }
 }
 
 /*
  * Callback for the 'Move Key Up' button.
  */
-static void
-airpcap_advanced_move_key_up_cb(GtkWidget *button, gpointer data _U_)
+void
+on_move_key_up_bt_clicked(GtkWidget *button, gpointer data _U_)
 {
-GtkList *key_ls;
-GtkWidget *label,*nl_lb,*nl_item;
+GtkWidget *airpcap_advanced_w;
+GtkWidget *key_ls;
 GList *new_list = NULL;
 GList *item = NULL;
-gint n;
 
-/* retrieve key list */
-key_ls = GTK_LIST(data);
+gint keys_in_list;
 
-/* Remove selected keys*/
-if(key_ls->selection != NULL)
-       {
-       item = g_list_nth(key_ls->selection,0);
-       if(item != NULL)
-               {
-               n = gtk_list_child_position(key_ls,item->data);
-               if(n>0)
-                       {
-                       label = GTK_BIN(item->data)->child;
-                       nl_lb = gtk_label_new(GTK_LABEL(label)->label);
-                       gtk_list_clear_items(key_ls,n,n+1);
-                       nl_item = gtk_list_item_new();
-                       gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
-                       gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
-                       gtk_widget_show(nl_lb);
-                       gtk_widget_show(nl_item);
-                       new_list = g_list_append(new_list,nl_item);
-                       gtk_list_insert_items(key_ls,new_list,n-1);
-                       gtk_list_select_item(key_ls,n-1);
-                       }
-               }
-       }
+airpcap_key_ls_selected_info_t *selected_item;
+
+gint c = NO_COLUMN_SELECTED;
+gint r = NO_ROW_SELECTED;
+
+airpcap_advanced_w = GTK_WIDGET(data);
+
+/* retrieve needed stuff */
+key_ls        = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEYLIST_KEY);
+selected_item = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
+
+/* 
+ * Better to store the selected_item data in two new variables, because maybe some 
+ * select_row signal will be emitted somewhere...
+ */
+r = selected_item->row;
+c = selected_item->column;
+
+keys_in_list = GTK_CLIST(key_ls)->rows;
+
+if(keys_in_list < 2) /* With less than 2 keys, nothing can be moved ... */
+    return;
+
+if( r == 0 ) /* Cannot move up the first row */
+    return;
+
+/* Move up selected key */
+gtk_clist_swap_rows (GTK_CLIST(key_ls),r-1,r);
+
+/* 
+ * Re-select the just moved key... so the user can keep pressing 'Move Key Up'
+ * without re-select the row...
+ */
+gtk_clist_select_row (GTK_CLIST(key_ls),r-1,c);
 
 /* Need to save config... */
 airpcap_if_selected->saved = FALSE;
@@ -1378,513 +1746,1658 @@ airpcap_if_selected->saved = FALSE;
 /*
  * Callback for the 'Move Key Down' button.
  */
-static void
-airpcap_advanced_move_key_down_cb(GtkWidget *button, gpointer data _U_)
+void
+on_move_key_down_bt_clicked(GtkWidget *button, gpointer data _U_)
 {
-GtkList *key_ls;
-GtkWidget *label,*nl_lb,*nl_item;
+GtkWidget *airpcap_advanced_w;
+GtkWidget *key_ls;
 GList *new_list = NULL;
 GList *item = NULL;
-unsigned int n;
 
-/* retrieve key list */
-key_ls = GTK_LIST(data);
+gint keys_in_list;
 
-/* Remove selected keys*/
-if(key_ls->selection != NULL)
-       {
-       item = g_list_nth(key_ls->selection,0);
-       if(item != NULL)
-               {
-               n = gtk_list_child_position(key_ls,item->data);
-               if(n< (g_list_length(key_ls->children)-1))
-                       {
-                       label = GTK_BIN(item->data)->child;
-                       nl_lb = gtk_label_new(GTK_LABEL(label)->label);
-                       gtk_list_clear_items(key_ls,n,n+1);
-
-                       nl_item = gtk_list_item_new();
-                       gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
-                       gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
-                       gtk_widget_show(nl_lb);
-                       gtk_widget_show(nl_item);
-
-                       new_list = g_list_append(new_list,nl_item);
-                       gtk_list_insert_items(key_ls,new_list,n+1);
-                       gtk_list_select_item(key_ls,n+1);
-                       }
-               }
-       }
+airpcap_key_ls_selected_info_t *selected_item;
+
+gint c = NO_COLUMN_SELECTED;
+gint r = NO_ROW_SELECTED;
+
+airpcap_advanced_w = GTK_WIDGET(data);
+
+/* retrieve needed stuff */
+key_ls        = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEYLIST_KEY);
+selected_item = OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY);
+
+/* 
+ * Better to store the selected_item data in two new variables, because maybe some 
+ * select_row signal will be emitted somewhere...
+ */
+r = selected_item->row;
+c = selected_item->column;
+
+keys_in_list = GTK_CLIST(key_ls)->rows;
+
+if(keys_in_list < 2) /* With less than 2 keys, nothing can be moved ... */
+    return;
+
+if( (r+1) == keys_in_list ) /* Cannot move down the last row */
+    return;
+
+/* Move down selected key */
+gtk_clist_swap_rows (GTK_CLIST(key_ls),r,r+1);
+
+/* 
+ * Re-select the just moved key... so the user can keep pressing 'Move Key Down'
+ * without re-select the row...
+ */
+gtk_clist_select_row (GTK_CLIST(key_ls),r+1,c);
 
 /* Need to save config... */
 airpcap_if_selected->saved = FALSE;
 }
 
 /* Turns the decryption on or off */
-static void
-wep_encryption_check_cb(GtkWidget *w, gpointer data)
+void
+on_enable_decryption_en_changed(GtkWidget *w, gpointer data)
 {
-if( !block_advanced_signals && (airpcap_if_selected != NULL))
-       {
-       if(airpcap_if_selected->DecryptionOn == AIRPCAP_DECRYPTION_ON)
-               {
-               airpcap_if_selected->DecryptionOn = AIRPCAP_DECRYPTION_OFF;
-               airpcap_if_selected->saved = FALSE;
-               }
-       else
-               {
-               airpcap_if_selected->DecryptionOn = AIRPCAP_DECRYPTION_ON;
-               airpcap_if_selected->saved = FALSE;
-               }
-       }
+GtkEntry *decryption_en;
+
+char* decryption_mode_string = NULL;
+
+decryption_en = GTK_ENTRY(w);
+
+if(g_strcasecmp(gtk_entry_get_text(decryption_en),AIRPCAP_DECRYPTION_TYPE_STRING_WIRESHARK) == 0)
+    {
+    set_wireshark_decryption(TRUE);
+    if(!set_airpcap_decryption(FALSE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+else if(g_strcasecmp(gtk_entry_get_text(decryption_en),AIRPCAP_DECRYPTION_TYPE_STRING_AIRPCAP) == 0)
+    {
+    set_wireshark_decryption(FALSE);
+    if(!set_airpcap_decryption(TRUE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+else if(g_strcasecmp(gtk_entry_get_text(decryption_en),AIRPCAP_DECRYPTION_TYPE_STRING_NONE) == 0)
+    {
+    set_wireshark_decryption(FALSE);
+    if(!set_airpcap_decryption(FALSE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+
+/* Redissect all the packets, and re-evaluate the display filter. */
+cf_redissect_packets(&cfile);
+}
+
+/*
+ * Will fill the given combo box with the current decryption mode string
+ */
+void
+update_decryption_mode_cm(GtkWidget *w)
+{
+
+/* Wireshark decryption is on */                       
+if(wireshark_decryption_on())
+    {
+    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w)->entry),AIRPCAP_DECRYPTION_TYPE_STRING_WIRESHARK);
+    /* We don't know if AirPcap decryption is on or off, but we just turn it off */
+    if(!set_airpcap_decryption(FALSE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+/* AirPcap decryption is on */
+else if(airpcap_decryption_on())
+    {
+    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w)->entry),AIRPCAP_DECRYPTION_TYPE_STRING_AIRPCAP);
+    }
+/* No decryption enabled */
+else
+    {
+    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w)->entry),AIRPCAP_DECRYPTION_TYPE_STRING_NONE);
+    }
+return;
 }
 
 /* Called to create the airpcap settings' window */
 void
 display_airpcap_advanced_cb(GtkWidget *w, gpointer data)
 {
-       /* Main window */
-       GtkWidget   *airpcap_advanced_w;
+GtkWidget *airpcap_advanced_w;
+GtkWidget *main_box;
+GtkWidget *settings_sub_box;
+GtkWidget *interface_fr;
+GtkWidget *interface_al;
+GtkWidget *interface_sub_h_box;
+GtkWidget *interface_name_lb;
+GtkWidget *blink_bt;
+GtkWidget *interface_frame_lb;
+GtkWidget *basic_parameters_fr;
+GtkWidget *basic_parameters_al;
+GtkWidget *basic_parameters_tb;
+GtkWidget *channel_lb;
+GtkWidget *capture_type_lb;
+GtkWidget *channel_cm;
+GList *channel_cm_items = NULL;
+GtkWidget *channel_en;
+GtkWidget *capture_type_cm;
+GList *capture_type_cm_items = NULL;
+GtkWidget *capture_type_en;
+GtkWidget *fcs_ck;
+GtkWidget *basic_parameters_fcs_h_box;
+GtkWidget *basic_parameters_fcs_filter_lb;
+GtkWidget *fcs_filter_cm;
+GList *fcs_filter_cm_items = NULL;
+GtkWidget *fcs_filter_en;
+GtkWidget *basic_parameters_frame_lb;
+GtkWidget *low_buttons_h_box;
+GtkWidget *left_h_button_box;
+GtkWidget *reset_configuration_bt;
+GtkWidget *right_h_button_box;
+GtkWidget *ok_bt;
+GtkWidget *apply_bt;
+GtkWidget *cancel_bt;
+
+/* widgets in the toolbar */
+GtkWidget      *toolbar,
+                       *toolbar_if_lb,
+                       *toolbar_channel_cm,
+                       *toolbar_wrong_crc_cm;
+
+/* other stuff */
+/*GList                                *channel_list,*capture_list;*/
+GList                          *linktype_list = NULL;
+gchar                          *capture_s;
+
+/* user data - RETRIEVE pointers of toolbar widgets */
+toolbar                                = GTK_WIDGET(data);
+toolbar_if_lb          = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_INTERFACE_KEY));
+toolbar_channel_cm     = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_CHANNEL_KEY));
+toolbar_wrong_crc_cm= GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_FCS_FILTER_KEY));
+
+/* gray out the toolbar */
+gtk_widget_set_sensitive(toolbar,FALSE);
+
+/* main window */
+/* global */
+
+/* NULL to global widgets */
+block_advanced_signals = FALSE;
+
+/* the selected is the active, for now */
+airpcap_if_selected = airpcap_if_active;
+
+/* Create the new window */
+airpcap_advanced_w = window_new(GTK_WINDOW_TOPLEVEL, "Advanced Wireless Settings");
+
+gtk_container_set_border_width (GTK_CONTAINER (airpcap_advanced_w), 5);
+gtk_window_set_title (GTK_WINDOW (airpcap_advanced_w),
+               "Advanced Wireless Settings");
+gtk_window_set_position (GTK_WINDOW (airpcap_advanced_w),
+                  GTK_WIN_POS_CENTER);
+                  
+#if GTK_MAJOR_VERSION >= 2
+gtk_window_set_resizable (GTK_WINDOW (airpcap_advanced_w), FALSE);
+gtk_window_set_type_hint (GTK_WINDOW (airpcap_advanced_w), GDK_WINDOW_TYPE_HINT_DIALOG);
+#else
+gtk_window_set_policy(GTK_WINDOW(airpcap_advanced_w), FALSE, FALSE, TRUE);
+#endif
+
+main_box = gtk_vbox_new (FALSE, 0);
+gtk_widget_set_name (main_box, "main_box");
+gtk_widget_show (main_box);
+gtk_container_add (GTK_CONTAINER (airpcap_advanced_w), main_box);
+
+settings_sub_box = gtk_vbox_new (FALSE, 0);
+gtk_widget_set_name (settings_sub_box, "settings_sub_box");
+gtk_widget_show (settings_sub_box);
+gtk_box_pack_start (GTK_BOX (main_box), settings_sub_box, FALSE, TRUE, 0);
+
+interface_fr = gtk_frame_new (NULL);
+gtk_widget_set_name (interface_fr, "interface_fr");
+gtk_widget_show (interface_fr);
+gtk_box_pack_start (GTK_BOX (settings_sub_box), interface_fr, FALSE, FALSE,
+             0);
+gtk_container_set_border_width (GTK_CONTAINER (interface_fr), 10);
+
+interface_al = gtk_alignment_new (0.5, 0.5, 1, 1);
+gtk_widget_set_name (interface_al, "interface_al");
+gtk_widget_show (interface_al);
+gtk_container_add (GTK_CONTAINER (interface_fr), interface_al);
+#if GTK_MAJOR_VERSION >= 2
+gtk_alignment_set_padding (GTK_ALIGNMENT (interface_al), 5, 5, 0, 0);
+#else
+gtk_alignment_set (GTK_ALIGNMENT (interface_al), 5, 5, 0, 0);
+#endif
+
+interface_sub_h_box = gtk_hbox_new (FALSE, 0);
+gtk_widget_set_name (interface_sub_h_box, "interface_sub_h_box");
+gtk_widget_show (interface_sub_h_box);
+gtk_container_add (GTK_CONTAINER (interface_al), interface_sub_h_box);
+gtk_container_set_border_width (GTK_CONTAINER (interface_sub_h_box), 5);
+
+/* Fill the interface_box */
+if(airpcap_if_active != NULL)
+       {
+       interface_name_lb = gtk_label_new(airpcap_if_active->description);
+       }
+else
+       {
+       interface_name_lb = gtk_label_new("No airpcap interface found!");
+       gtk_widget_set_sensitive(main_box,FALSE);
+       }
        
-       /* Blink button */
-       GtkWidget       *blink_bt,
-                               *channel_combo;
-       /* Combos */
-       GtkWidget       *interface_combo,
-                               *capture_combo;
-
-       /* check */
-       GtkWidget   *wrong_crc_combo;
-
-       /* key list*/
-       GtkWidget   *key_ls;
-
-       /* frames */
-       GtkWidget   *interface_frame,
-                               *basic_frame,
-                               *wep_frame;
-       /* boxes */
-       GtkWidget       *main_box,
-                               *buttons_box_1,
-                               *buttons_box_2,
-                               *interface_box,
-                               *basic_box,
-                               *basic_combo_box,
-                               *basic_check_box,
-                               *basic_label_box,
-                               *basic_wrong_box,
-                               *wep_box,
-                               *wep_sub_box,
-                               *encryption_box,
-                               *wep_buttons_box;
-       /* buttons */
-       /* blink button is global */
-       GtkWidget       *add_new_key_bt,
-                               *remove_key_bt,
-                               *edit_key_bt,
-                               *move_key_up_bt,
-                               *move_key_down_bt,
-                               *reset_configuration_bt,
-                               *about_bt,
-                               *apply_bt,
-                               *ok_bt,
-                               *cancel_bt;
-       /* combo */
-
-       /* shortcut to combo entry */
-       GtkWidget       *link_type_te,
-                               *wrong_crc_te,
-                               *channel_te;
-       /* check */
-       /* global check buttons */
-       GtkWidget   *crc_check,
-                               *encryption_check;
-       /* label */
-       GtkWidget       *channel_lb,
-                               *wrong_lb,
-                               *capture_lb;
-       /* text field */
-       GtkWidget   *key_text;
+gtk_widget_set_name (interface_name_lb, "interface_name_lb");
+gtk_widget_show (interface_name_lb);
+gtk_box_pack_start (GTK_BOX (interface_sub_h_box), interface_name_lb, TRUE,
+             FALSE, 0);
 
-       /* widgets in the toolbar */
-       GtkWidget       *toolbar,
-                               *toolbar_if_lb,
-                               *toolbar_channel_cm,
-                               *toolbar_wrong_crc_cm;
+/* If it is NOT the 'Any' Interface */
+if(!airpcap_if_is_any(airpcap_if_selected))
+       {
+       #if GTK_MAJOR_VERSION >= 2
+       blink_bt = gtk_button_new_with_mnemonic ("Blink Led");
+       #else
+       blink_bt = gtk_button_new_with_label("Blink Led");
+       #endif
+       }
+else /* It is the any interface, so it doesn't make sense to have 'Blink' button... */
+       {
+       #if GTK_MAJOR_VERSION >= 2
+       blink_bt = gtk_button_new_with_mnemonic ("What's This?");
+       #else
+       blink_bt = gtk_button_new_with_label("What's This?");
+       #endif
+       }
+gtk_widget_set_name (blink_bt, "blink_bt");
+gtk_widget_show (blink_bt);
+gtk_box_pack_end (GTK_BOX (interface_sub_h_box), blink_bt, FALSE, FALSE, 0);
+
+interface_frame_lb = gtk_label_new ("<b>Interface</b>");
+gtk_widget_set_name (interface_frame_lb, "interface_frame_lb");
+gtk_widget_show (interface_frame_lb);
+#if GTK_MAJOR_VERSION >= 2
+gtk_frame_set_label_widget (GTK_FRAME (interface_fr), interface_frame_lb);
+gtk_label_set_use_markup (GTK_LABEL (interface_frame_lb), TRUE);
+#else
+gtk_frame_set_label(GTK_FRAME(interface_fr),"Interface");
+#endif  
+
+basic_parameters_fr = gtk_frame_new (NULL);
+gtk_widget_set_name (basic_parameters_fr, "basic_parameters_fr");
+gtk_widget_show (basic_parameters_fr);
+gtk_box_pack_start (GTK_BOX (settings_sub_box), basic_parameters_fr, TRUE,FALSE, 0);
+gtk_container_set_border_width (GTK_CONTAINER (basic_parameters_fr), 10);
+
+basic_parameters_al = gtk_alignment_new (0.5, 0.5, 1, 1);
+gtk_widget_set_name (basic_parameters_al, "basic_parameters_al");
+gtk_widget_show (basic_parameters_al);
+gtk_container_add (GTK_CONTAINER (basic_parameters_fr),basic_parameters_al);
+#if GTK_MAJOR_VERSION >= 2
+gtk_alignment_set_padding (GTK_ALIGNMENT (basic_parameters_al), 10, 10, 0, 0);
+#else
+gtk_alignment_set (GTK_ALIGNMENT (basic_parameters_al), 10, 10, 0, 0);
+#endif
 
-       /* other stuff */
-       GList                           *channel_list,*capture_list;
-       GList                           *linktype_list = NULL;
-       gchar                           *capture_s;
+basic_parameters_tb = gtk_table_new (2, 3, FALSE);
+gtk_widget_set_name (basic_parameters_tb, "basic_parameters_tb");
+gtk_widget_show (basic_parameters_tb);
+gtk_container_add (GTK_CONTAINER (basic_parameters_al),
+            basic_parameters_tb);
+gtk_container_set_border_width (GTK_CONTAINER (basic_parameters_tb), 5);
+gtk_table_set_col_spacings (GTK_TABLE (basic_parameters_tb), 20);
+
+channel_lb = gtk_label_new ("Channel:");
+gtk_widget_set_name (channel_lb, "channel_lb");
+gtk_widget_show (channel_lb);
+gtk_table_attach (GTK_TABLE (basic_parameters_tb), channel_lb, 0, 1, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_misc_set_alignment (GTK_MISC (channel_lb), 0, 0.5);
+
+capture_type_lb = gtk_label_new ("Capture Type:");
+gtk_widget_set_name (capture_type_lb, "capture_type_lb");
+gtk_widget_show (capture_type_lb);
+gtk_table_attach (GTK_TABLE (basic_parameters_tb), capture_type_lb, 0, 1, 1,
+           2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0),
+           0, 0);
+gtk_misc_set_alignment (GTK_MISC (capture_type_lb), 0, 0.5);
+
+channel_cm = gtk_combo_new ();
+gtk_widget_set_name (channel_cm, "channel_cm");
+gtk_widget_show (channel_cm);
+gtk_table_attach (GTK_TABLE (basic_parameters_tb), channel_cm, 1, 2, 0, 1,
+           (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "1");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "2");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "3");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "4");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "5");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "6");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "7");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "8");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "9");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "10");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "11");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "12");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "13");
+channel_cm_items = g_list_append (channel_cm_items, (gpointer) "14");
+gtk_combo_set_popdown_strings (GTK_COMBO (channel_cm), channel_cm_items);
+
+  /* Select the first entry */
+if(airpcap_if_selected != NULL)
+       {
+       airpcap_update_channel_combo(GTK_WIDGET(channel_cm), airpcap_if_selected);
+       }
+       
+g_list_free (channel_cm_items);
+
+channel_en = GTK_COMBO (channel_cm)->entry;
+gtk_editable_set_editable(GTK_EDITABLE(channel_en),FALSE);
+gtk_widget_set_name (channel_en, "channel_en");
+gtk_widget_show (channel_en);
+
+capture_type_cm = gtk_combo_new ();
+gtk_widget_set_name (capture_type_cm, "capture_type_cm");
+gtk_widget_show (capture_type_cm);
+gtk_table_attach (GTK_TABLE (basic_parameters_tb), capture_type_cm, 1, 2, 1,
+           2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+capture_type_cm_items =
+g_list_append (capture_type_cm_items, (gpointer) AIRPCAP_LINK_TYPE_NAME_802_11_ONLY);
+capture_type_cm_items =
+g_list_append (capture_type_cm_items, (gpointer) AIRPCAP_LINK_TYPE_NAME_802_11_PLUS_RADIO);
+gtk_combo_set_popdown_strings (GTK_COMBO (capture_type_cm),
+                        capture_type_cm_items);
+                        
+/* Current interface value */
+capture_s = NULL;
+if(airpcap_if_selected != NULL)
+       {
+       if(airpcap_if_selected->linkType == AIRPCAP_LT_802_11)
+               capture_s = g_strdup_printf("%s",AIRPCAP_LINK_TYPE_NAME_802_11_ONLY);
+       else if(airpcap_if_selected->linkType == AIRPCAP_LT_802_11_PLUS_RADIO)
+               capture_s = g_strdup_printf("%s",AIRPCAP_LINK_TYPE_NAME_802_11_PLUS_RADIO);     
+       if(capture_s != NULL) gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(capture_type_cm)->entry), capture_s);
+       }
+g_free(capture_s);
 
+g_list_free (capture_type_cm_items);
 
-       /* user data - RETRIEVE pointers of toolbar widgets */
-       toolbar                         = GTK_WIDGET(data);
-    toolbar_if_lb              = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_INTERFACE_KEY));
-    toolbar_channel_cm = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_CHANNEL_KEY));
-    toolbar_wrong_crc_cm= GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_WRONG_CRC_KEY));
+capture_type_en = GTK_COMBO (capture_type_cm)->entry;
+gtk_widget_set_name (capture_type_en, "capture_type_en");
+gtk_widget_show (capture_type_en);
 
-       /* gray out the toolbar */
-       gtk_widget_set_sensitive(toolbar,FALSE);
+#if GTK_VERSION >= 2
+fcs_ck = gtk_check_button_new_with_mnemonic ("Include 802.11 FCS in Frames");
+#else
+fcs_ck = gtk_check_button_new_with_label ("Include 802.11 FCS in Frames");
+#endif
+gtk_widget_set_name (fcs_ck, "fcs_ck");
 
-       /* main window */
-       /* global */
+/* Fcs Presence check box */
+if(airpcap_if_selected != NULL)
+       {
+       if(airpcap_if_selected->IsFcsPresent)
+               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcs_ck),TRUE);
+       else
+               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcs_ck),FALSE);
+       }
+       
+gtk_widget_show (fcs_ck);
+gtk_table_attach (GTK_TABLE (basic_parameters_tb), fcs_ck, 2, 3, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+
+basic_parameters_fcs_h_box = gtk_hbox_new (FALSE, 1);
+gtk_widget_set_name (basic_parameters_fcs_h_box,
+              "basic_parameters_fcs_h_box");
+gtk_widget_show (basic_parameters_fcs_h_box);
+gtk_table_attach (GTK_TABLE (basic_parameters_tb),
+           basic_parameters_fcs_h_box, 2, 3, 1, 2,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (GTK_FILL), 3, 0);
+
+basic_parameters_fcs_filter_lb = gtk_label_new ("FCS Filter:");
+gtk_widget_set_name (basic_parameters_fcs_filter_lb,
+              "basic_parameters_fcs_filter_lb");
+gtk_widget_show (basic_parameters_fcs_filter_lb);
+gtk_box_pack_start (GTK_BOX (basic_parameters_fcs_h_box),
+             basic_parameters_fcs_filter_lb, FALSE, FALSE, 0);
+
+fcs_filter_cm = gtk_combo_new ();
+gtk_widget_set_name (fcs_filter_cm, "fcs_filter_cm");
+gtk_widget_show (fcs_filter_cm);
+gtk_box_pack_start (GTK_BOX (basic_parameters_fcs_h_box), fcs_filter_cm,
+             FALSE, FALSE, 0);
+#if GTK_MAJOR_VERSION >= 2
+gtk_widget_set_size_request (fcs_filter_cm, 112, -1);
+#else
+gtk_widget_set_usize (fcs_filter_cm, 112, -1);
+#endif
+fcs_filter_cm_items =
+g_list_append (fcs_filter_cm_items, (gpointer) "All Frames");
+fcs_filter_cm_items =
+g_list_append (fcs_filter_cm_items, (gpointer) "Valid Frames");
+fcs_filter_cm_items =
+g_list_append (fcs_filter_cm_items, (gpointer) "Invalid Frames");
+gtk_combo_set_popdown_strings (GTK_COMBO (fcs_filter_cm),
+                        fcs_filter_cm_items);
+g_list_free (fcs_filter_cm_items);
+
+fcs_filter_en = GTK_COMBO (fcs_filter_cm)->entry;
+gtk_widget_set_name (fcs_filter_en, "fcs_filter_en");
 
-       /* NULL to global widgets */
-       blink_bt = NULL;
-       channel_combo = NULL;
-       block_advanced_signals = FALSE;
+if(airpcap_if_selected != NULL)
+       {
+       airpcap_validation_type_combo_set_by_type(fcs_filter_cm,airpcap_if_selected->CrcValidationOn);
+       }
+       
+gtk_widget_show (fcs_filter_en);
+
+basic_parameters_frame_lb = gtk_label_new ("<b>Basic Parameters</b>");
+gtk_widget_set_name (basic_parameters_frame_lb,
+              "basic_parameters_frame_lb");
+gtk_widget_show (basic_parameters_frame_lb);
+
+#if GTK_MAJOR_VERSION >= 2
+gtk_frame_set_label_widget (GTK_FRAME (basic_parameters_fr),basic_parameters_frame_lb);
+gtk_label_set_use_markup (GTK_LABEL (basic_parameters_frame_lb), TRUE);
+#else
+gtk_frame_set_label(GTK_FRAME (basic_parameters_fr),"Basic Parameters");
+#endif
 
-       /* the selected is the active, for now */
-       airpcap_if_selected = airpcap_if_active;
+low_buttons_h_box = gtk_hbox_new (FALSE, 0);
+gtk_widget_set_name (low_buttons_h_box, "low_buttons_h_box");
+gtk_widget_show (low_buttons_h_box);
+gtk_box_pack_end (GTK_BOX (main_box), low_buttons_h_box, FALSE, FALSE, 0);
+
+left_h_button_box = gtk_hbutton_box_new ();
+gtk_widget_set_name (left_h_button_box, "left_h_button_box");
+gtk_widget_show (left_h_button_box);
+gtk_box_pack_start (GTK_BOX (low_buttons_h_box), left_h_button_box, FALSE,
+             FALSE, 0);
+
+#if GTK_MAJOR_VERSION >= 2
+reset_configuration_bt = gtk_button_new_with_mnemonic ("Reset Configuration");
+#else
+reset_configuration_bt = gtk_button_new_with_label ("Reset Configuration");
+#endif
+gtk_widget_set_name (reset_configuration_bt, "reset_configuration_bt");
+/* gtk_widget_show (reset_configuration_bt); */
+gtk_container_add (GTK_CONTAINER (left_h_button_box),
+            reset_configuration_bt);
+GTK_WIDGET_SET_FLAGS (reset_configuration_bt, GTK_CAN_DEFAULT);
+
+right_h_button_box = gtk_hbutton_box_new ();
+gtk_widget_set_name (right_h_button_box, "right_h_button_box");
+gtk_widget_show (right_h_button_box);
+gtk_box_pack_end (GTK_BOX (low_buttons_h_box), right_h_button_box, FALSE,
+           FALSE, 0);
+gtk_button_box_set_layout (GTK_BUTTON_BOX (right_h_button_box),
+                    GTK_BUTTONBOX_END);
+
+#if GTK_MAJOR_VERSION >= 2
+ok_bt = gtk_button_new_with_mnemonic ("Ok");
+#else
+ok_bt = gtk_button_new_with_label ("Ok");
+#endif
+gtk_widget_set_name (ok_bt, "ok_bt");
+gtk_widget_show (ok_bt);
+gtk_container_add (GTK_CONTAINER (right_h_button_box), ok_bt);
+GTK_WIDGET_SET_FLAGS (ok_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+apply_bt = gtk_button_new_with_mnemonic ("Apply");
+#else
+apply_bt = gtk_button_new_with_label ("Apply");
+#endif
+gtk_widget_set_name (apply_bt, "apply_bt");
+gtk_widget_show (apply_bt);
+gtk_container_add (GTK_CONTAINER (right_h_button_box), apply_bt);
+GTK_WIDGET_SET_FLAGS (apply_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+cancel_bt = gtk_button_new_with_mnemonic ("Cancel");
+#else
+cancel_bt = gtk_button_new_with_label ("Cancel");
+#endif
+gtk_widget_set_name (cancel_bt, "cancel_bt");
+gtk_widget_show (cancel_bt);
+gtk_container_add (GTK_CONTAINER (right_h_button_box), cancel_bt);
+GTK_WIDGET_SET_FLAGS (cancel_bt, GTK_CAN_DEFAULT);
 
-       /* Create the new window */
-       airpcap_advanced_w = window_new(GTK_WINDOW_TOPLEVEL, "Advanced Wireless Settings");
+/* Connect the callbacks */
+SIGNAL_CONNECT (airpcap_advanced_w, "delete_event", window_delete_event_cb, airpcap_advanced_w);
+SIGNAL_CONNECT (airpcap_advanced_w, "destroy", on_airpcap_advanced_destroy, airpcap_advanced_w);
 
-       /*
-        * I will need the toolbar and the main widget in some callback,
-        * so I will add the toolbar pointer to the airpcap_advanced_w
-        */
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_TOOLBAR_KEY,toolbar);
+if(!airpcap_if_is_any(airpcap_if_selected))
+{
+SIGNAL_CONNECT (blink_bt, "clicked", on_blink_bt_clicked, airpcap_advanced_w);
+}
+else
+{
+SIGNAL_CONNECT (blink_bt, "clicked", on_what_s_this_bt_clicked, airpcap_advanced_w);
+}
 
-       /* Connect the callbacks */
-       SIGNAL_CONNECT(airpcap_advanced_w, "delete_event", window_delete_event_cb, airpcap_advanced_w);
-    SIGNAL_CONNECT(airpcap_advanced_w, "destroy", airpcap_if_destroy_cb, airpcap_advanced_w);
+SIGNAL_CONNECT (channel_en, "changed",on_channel_en_changed, airpcap_advanced_w);
+SIGNAL_CONNECT (capture_type_en, "changed",on_capture_type_en_changed, airpcap_advanced_w);
+SIGNAL_CONNECT (fcs_ck, "toggled",on_fcs_ck_toggled, airpcap_advanced_w);
+SIGNAL_CONNECT (fcs_filter_en, "changed",on_fcs_filter_en_changed, airpcap_advanced_w);
+SIGNAL_CONNECT (reset_configuration_bt, "clicked",on_reset_configuration_bt_clicked, airpcap_advanced_w);
+SIGNAL_CONNECT (apply_bt, "clicked",on_advanced_apply_bt_clicked, airpcap_advanced_w);
+SIGNAL_CONNECT (ok_bt,"clicked",on_advanced_ok_bt_clicked,airpcap_advanced_w);
+SIGNAL_CONNECT (cancel_bt,"clicked",on_advanced_cancel_bt_clicked,airpcap_advanced_w);
+
+/* Different because the window will be closed ... */
+/*window_set_cancel_button(airpcap_advanced_w, ok_bt, window_cancel_button_cb);
+window_set_cancel_button(airpcap_advanced_w, cancel_bt, window_cancel_button_cb);*/
+
+
+/* Store pointers to all widgets, for use by lookup_widget(). */
+OBJECT_SET_DATA (airpcap_advanced_w, AIRPCAP_ADVANCED_BLINK_KEY, blink_bt);
+OBJECT_SET_DATA (airpcap_advanced_w, AIRPCAP_ADVANCED_CHANNEL_KEY,channel_cm);
+OBJECT_SET_DATA (airpcap_advanced_w, AIRPCAP_ADVANCED_LINK_TYPE_KEY,capture_type_cm);
+OBJECT_SET_DATA (airpcap_advanced_w, AIRPCAP_ADVANCED_FCS_CHECK_KEY, fcs_ck);
+OBJECT_SET_DATA (airpcap_advanced_w, AIRPCAP_ADVANCED_FCS_FILTER_KEY, fcs_filter_cm);
+OBJECT_SET_DATA (airpcap_advanced_w, AIRPCAP_ADVANCED_OK_KEY, ok_bt);
+OBJECT_SET_DATA (airpcap_advanced_w, AIRPCAP_ADVANCED_CANCEL_KEY, cancel_bt);
 
-       /* Set the size */
-       /* Sets the border width of the window. */
-       gtk_container_set_border_width (GTK_CONTAINER (airpcap_advanced_w), 10);
+/*
+ * I will need the toolbar and the main widget in some callback,
+ * so I will add the toolbar pointer to the airpcap_advanced_w
+ */
+OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_TOOLBAR_KEY,toolbar);
 
-       /* Create the main box */
-       main_box = gtk_vbox_new(FALSE,0);
+/* At the end, so that it appears completely all together ... */
+gtk_widget_show (airpcap_advanced_w);
+}
 
-       /* Create the button boxes */
-       buttons_box_1 = gtk_hbox_new(FALSE,0);
-       buttons_box_2 = gtk_hbox_new(FALSE,0);
+/*
+ * Callback for the OK button 'clicked' in the Advanced Wireless Settings window.
+ */
+void
+on_advanced_ok_bt_clicked(GtkWidget *button, gpointer data _U_)
+{
+PAirpcapHandle ad = NULL;
+gchar ebuf[AIRPCAP_ERRBUF_SIZE];
 
-       /* Create the buttons for box 1 */
-       reset_configuration_bt = gtk_button_new_with_label("Reset Configuration");
-       SIGNAL_CONNECT(reset_configuration_bt, "clicked", airpcap_advanced_reset_configuration_cb, toolbar);
-       gtk_widget_show(reset_configuration_bt);
+/* Retrieve object data */
+GtkWidget *airpcap_advanced_w;
+GtkWidget *channel_combo;
+GtkWidget *capture_combo;
+GtkWidget *crc_check;
+GtkWidget *wrong_crc_combo;
+GtkWidget *blink_bt;
+GtkWidget *interface_combo;
+GtkWidget *cancel_bt;
+GtkWidget *ok_bt;
+
+/* widgets in the toolbar */
+GtkWidget      *toolbar,
+                       *toolbar_if_lb,
+                       *toolbar_channel_cm,
+                       *toolbar_wrong_crc_cm,
+                       *advanced_bt;
+
+/* Retrieve the GUI object pointers */
+airpcap_advanced_w  = GTK_WIDGET(data);
+interface_combo                = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_INTERFACE_KEY));
+channel_combo          = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_CHANNEL_KEY));
+capture_combo          = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_LINK_TYPE_KEY));
+crc_check                      = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_FCS_CHECK_KEY));
+wrong_crc_combo                = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_FCS_FILTER_KEY));
+blink_bt                       = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_BLINK_KEY));
+cancel_bt                      = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_CANCEL_KEY));
+ok_bt                          = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_OK_KEY));
+advanced_bt                    = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEY));
+
+toolbar                                        = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_TOOLBAR_KEY));
+
+/* retrieve toolbar info */
+toolbar_if_lb                  = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_INTERFACE_KEY));
+toolbar_channel_cm             = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_CHANNEL_KEY));
+toolbar_wrong_crc_cm   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_FCS_FILTER_KEY));
+
+/* Stop blinking ALL leds (go through the airpcap_if_list) */
+if(airpcap_if_selected != NULL)
+{
+ad = airpcap_if_open(airpcap_if_selected->name, ebuf);
+if(ad)
+       {
+       gtk_timeout_remove(airpcap_if_selected->tag);
+       airpcap_if_turn_led_on(ad, 0);
+       airpcap_if_selected->blinking = FALSE;
+       airpcap_if_selected->led = TRUE;
+       airpcap_if_close(ad);
+       }
+}
 
-       about_bt = gtk_button_new_with_label("About");
-       SIGNAL_CONNECT(about_bt, "clicked", airpcap_advanced_about_cb, toolbar);
-       gtk_widget_show(about_bt);
+/* ??? - Ask if want to save configuration */
 
-       /* Add them to box 1 */
-       gtk_box_pack_start (GTK_BOX (buttons_box_1), reset_configuration_bt, FALSE, FALSE, 1);
-       gtk_box_pack_start (GTK_BOX (buttons_box_1), about_bt, FALSE, FALSE, 1);
+/* Save the configuration */
+airpcap_save_selected_if_configuration(airpcap_if_selected);
+/* Remove gtk timeout */
+gtk_timeout_remove(airpcap_if_selected->tag);
 
-    /* Create the buttons for box 2 */
-       apply_bt = gtk_button_new_with_label("Apply");
-       SIGNAL_CONNECT(apply_bt, "clicked", airpcap_advanced_apply_cb, airpcap_advanced_w);
-       gtk_widget_show(apply_bt);
+/* Update toolbar (only if airpcap_if_selected is airpcap_if_active)*/
+if( g_strcasecmp(airpcap_if_selected->description,airpcap_if_active->description) == 0)
+       {
+    gtk_label_set_text(GTK_LABEL(toolbar_if_lb), g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_selected)));
+       
+       airpcap_update_channel_combo(GTK_WIDGET(toolbar_channel_cm),airpcap_if_selected);
+       
+    airpcap_validation_type_combo_set_by_type(toolbar_wrong_crc_cm,airpcap_if_selected->CrcValidationOn);
+       }
 
-       ok_bt = gtk_button_new_with_label("Ok");
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_OK_KEY,ok_bt);
-       window_set_cancel_button(airpcap_advanced_w, ok_bt, window_cancel_button_cb);
-       gtk_widget_show(ok_bt);
+/* If interface active is airpcap, set sensitive TRUE for airpcap toolbar */
+if( get_airpcap_if_by_name(airpcap_if_list,airpcap_if_active->description) != NULL)
+       {
+       airpcap_set_toolbar_start_capture(airpcap_if_active);
+       }
+else
+       {
+       airpcap_set_toolbar_stop_capture(airpcap_if_active);
+       }
 
-       cancel_bt = gtk_button_new_with_label("Cancel");
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_CANCEL_KEY,cancel_bt);
-       window_set_cancel_button(airpcap_advanced_w, cancel_bt, window_cancel_button_cb);
-       gtk_widget_show(cancel_bt);
+gtk_widget_destroy(airpcap_advanced_w);
+}
 
-       /* Add them to box 2 */
-       gtk_box_pack_end (GTK_BOX (buttons_box_2), cancel_bt, FALSE, FALSE, 1);
-       gtk_box_pack_end (GTK_BOX (buttons_box_2), apply_bt,  FALSE, FALSE, 1);
-       gtk_box_pack_end (GTK_BOX (buttons_box_2), ok_bt,     FALSE, FALSE, 1);
+/*
+ * Callback for the CANCEL button 'clicked' in the Advanced Wireless Settings window.
+ */
+void
+on_advanced_cancel_bt_clicked(GtkWidget *button, gpointer data _U_)
+{
+PAirpcapHandle ad = NULL;
+gchar ebuf[AIRPCAP_ERRBUF_SIZE];
 
-       /* Create the three main frames */
-       interface_frame = gtk_frame_new("");
-       gtk_frame_set_label(GTK_FRAME(interface_frame),"Interface");
+/* Retrieve object data */
+GtkWidget *airpcap_advanced_w;
+GtkWidget *channel_combo;
+GtkWidget *capture_combo;
+GtkWidget *crc_check;
+GtkWidget *wrong_crc_combo;
+GtkWidget *blink_bt;
+GtkWidget *interface_combo;
+GtkWidget *cancel_bt;
+GtkWidget *ok_bt;
+
+/* widgets in the toolbar */
+GtkWidget      *toolbar,
+                       *toolbar_if_lb,
+                       *toolbar_channel_cm,
+                       *toolbar_wrong_crc_cm,
+                       *advanced_bt;
+
+/* Retrieve the GUI object pointers */
+airpcap_advanced_w  = GTK_WIDGET(data);
+interface_combo                = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_INTERFACE_KEY));
+channel_combo          = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_CHANNEL_KEY));
+capture_combo          = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_LINK_TYPE_KEY));
+crc_check                      = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_FCS_CHECK_KEY));
+wrong_crc_combo                = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_FCS_FILTER_KEY));
+blink_bt                       = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_BLINK_KEY));
+cancel_bt                      = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_CANCEL_KEY));
+ok_bt                          = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_OK_KEY));
+advanced_bt                    = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEY));
+
+toolbar = GTK_WIDGET(OBJECT_GET_DATA(airpcap_advanced_w,AIRPCAP_TOOLBAR_KEY));
+
+/* retrieve toolbar info */
+toolbar_if_lb                  = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_INTERFACE_KEY));
+toolbar_channel_cm             = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_CHANNEL_KEY));
+toolbar_wrong_crc_cm   = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_FCS_FILTER_KEY));
+
+/* Stop blinking ALL leds (go through the airpcap_if_list) */
+if(airpcap_if_selected != NULL)
+{
+ad = airpcap_if_open(airpcap_if_selected->name, ebuf);
+if(ad)
+       {
+       gtk_timeout_remove(airpcap_if_selected->tag);
+       airpcap_if_turn_led_on(ad, 0);
+       airpcap_if_selected->blinking = FALSE;
+       airpcap_if_selected->led = TRUE;
+       airpcap_if_close(ad);
+       }
+}
 
-       basic_frame = gtk_frame_new("");
-       gtk_frame_set_label(GTK_FRAME(basic_frame),"Basic Parameters");
+/* reload the configuration!!! Configuration has not been saved but
+       the corresponding structure has been modified probably...*/
+if(!airpcap_if_selected->saved)
+       {
+       airpcap_load_selected_if_configuration(airpcap_if_selected);
+       }
 
-       wep_frame = gtk_frame_new("");
-       gtk_frame_set_label(GTK_FRAME(wep_frame),"WEP Keys");
+gtk_widget_destroy(airpcap_advanced_w);
+}
 
-       /* Create the three sub boxes */
-       interface_box = gtk_hbox_new(FALSE,0);
-       basic_box     = gtk_hbox_new(FALSE,0);
-       wep_box       = gtk_vbox_new(FALSE,0);
+/* Called to create the key management window */
+void
+display_airpcap_key_management_cb(GtkWidget *w, gpointer data)
+{
+GtkWidget *key_management_w;
+GtkWidget *main_box;
+GtkWidget *keys_fr;
+GtkWidget *keys_al;
+GtkWidget *keys_h_sub_box;
+GtkWidget *enable_decryption_tb;
+GtkWidget *enable_decryption_lb;
+GtkWidget *enable_decryption_cb;
+GList     *enable_decryption_cb_items = NULL;
+GtkWidget *enable_decryption_en;
+GtkWidget *keys_v_sub_box;
+GtkWidget *keys_scrolled_w;
+GtkWidget *key_ls;
+GtkWidget *key_list_decryption_type_col_lb;
+GtkWidget *key_list_decryption_key_col_lb;
+GtkWidget *key_ls_decryption_ssid_col_lb;
+GtkWidget *key_v_button_box;
+GtkWidget *add_new_key_bt;
+GtkWidget *remove_key_bt;
+GtkWidget *edit_key_bt;
+GtkWidget *move_key_up_bt;
+GtkWidget *move_key_down_bt;
+GtkWidget *keys_frame_lb;
+GtkWidget *low_buttons_h_box;
+GtkWidget *left_h_button_box;
+GtkWidget *reset_configuration_bt;
+GtkWidget *right_h_button_box;
+GtkWidget *ok_bt;
+GtkWidget *apply_bt;
+GtkWidget *cancel_bt;
+  
+/* widgets in the toolbar */
+GtkWidget      *toolbar,
+                       *toolbar_decryption_ck;
+
+/* other stuff */
+/*GList                                *channel_list,*capture_list;*/
+GList                          *linktype_list = NULL;
+       
+/* Selected row/column structure */
+airpcap_key_ls_selected_info_t *key_ls_selected_item;
+key_ls_selected_item = (airpcap_key_ls_selected_info_t*)g_malloc(sizeof(airpcap_key_ls_selected_info_t));
+key_ls_selected_item->row = NO_ROW_SELECTED;
+key_ls_selected_item->column = NO_COLUMN_SELECTED;
+
+/* user data - RETRIEVE pointers of toolbar widgets */
+toolbar                                  = GTK_WIDGET(data);
+toolbar_decryption_ck = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_DECRYPTION_KEY));
+
+/* gray out the toolbar */
+gtk_widget_set_sensitive(toolbar,FALSE);
+
+/* main window */
+/* global */
+
+/* NULL to global widgets */
+block_advanced_signals = FALSE;
+
+/* the selected is the active, for now */
+airpcap_if_selected = airpcap_if_active;
+
+/* Create the new window */
+key_management_w = window_new(GTK_WINDOW_TOPLEVEL, "Decryption Keys Management");
+
+gtk_container_set_border_width (GTK_CONTAINER (key_management_w), 5);
+gtk_window_set_title (GTK_WINDOW (key_management_w),
+               "Decryption Keys Management");
+gtk_window_set_position (GTK_WINDOW (key_management_w),
+                  GTK_WIN_POS_CENTER);
+                          
+#if GTK_MAJOR_VERSION >= 2
+gtk_window_set_resizable (GTK_WINDOW (key_management_w), FALSE);
+gtk_window_set_type_hint (GTK_WINDOW (key_management_w), GDK_WINDOW_TYPE_HINT_DIALOG);
+#else
+gtk_window_set_policy(GTK_WINDOW(key_management_w), FALSE, FALSE, TRUE);
+#endif
 
-       /* Fill the interface_box */
-       if(airpcap_if_active != NULL)
-               {
-               interface_combo = gtk_label_new(airpcap_if_active->description);
-               }
-       else
-               {
-               interface_combo = gtk_label_new("No airpcap interface found!");
-               gtk_widget_set_sensitive(main_box,FALSE);
-               }
+main_box = gtk_vbox_new (FALSE, 0);
+gtk_widget_set_name (main_box, "main_box");
+gtk_widget_show (main_box);
+gtk_container_add (GTK_CONTAINER (key_management_w), main_box);
+
+keys_fr = gtk_frame_new (NULL);
+gtk_widget_set_name (keys_fr, "keys_fr");
+gtk_widget_show (keys_fr);
+gtk_box_pack_start (GTK_BOX (main_box), keys_fr, FALSE, FALSE, 0);
+gtk_container_set_border_width (GTK_CONTAINER (keys_fr), 10);
+
+keys_al = gtk_alignment_new (0.5, 0.5, 1, 1);
+gtk_widget_set_name (keys_al, "keys_al");
+gtk_widget_show (keys_al);
+gtk_container_add (GTK_CONTAINER (keys_fr), keys_al);
+gtk_container_set_border_width (GTK_CONTAINER (keys_al), 5);
+
+#if GTK_MAJOR_VERSION >= 2
+gtk_alignment_set_padding (GTK_ALIGNMENT (keys_al), 0, 0, 12, 0);
+#else
+gtk_alignment_set (GTK_ALIGNMENT (keys_al), 0, 0, 12, 0);
+#endif
 
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_INTERFACE_KEY,interface_combo);
-       gtk_box_pack_start (GTK_BOX (interface_box), interface_combo, TRUE, TRUE, 0);
-       gtk_widget_show(interface_combo);
-
-       /* blink led button (BEFORE interface_combo, 'cause its callback will need blink_bt)*/
-       blink_bt = gtk_button_new_with_label("  Blink Led  ");
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_BLINK_KEY,blink_bt);
-       gtk_box_pack_end (GTK_BOX (interface_box), blink_bt, FALSE, FALSE, 0);
-       SIGNAL_CONNECT(blink_bt, "clicked", blink_cb, NULL);
-       gtk_widget_show(blink_bt);
-
-       gtk_container_set_border_width (GTK_CONTAINER (interface_box), 10);
-
-       /* Fill the basic_box */
-       /* Create the two vertical boxes for combo and check */
-       basic_combo_box = gtk_vbox_new(TRUE,0);
-       basic_check_box = gtk_vbox_new(TRUE,0);
-       basic_label_box = gtk_vbox_new(TRUE,0);
-
-       /* Create the Wrong CRC horiziontal box */
-       basic_wrong_box = gtk_hbox_new(FALSE,0);
-
-       /* Fill the label vbox */
-       channel_lb = gtk_label_new("Channel:      ");
-       gtk_label_set_justify(GTK_LABEL(channel_lb),GTK_JUSTIFY_LEFT);
-       gtk_box_pack_start (GTK_BOX (basic_label_box), channel_lb, TRUE, TRUE, 0);
-       gtk_widget_show(channel_lb);
-       capture_lb = gtk_label_new("Capture Type:");
-       gtk_label_set_justify(GTK_LABEL(capture_lb),GTK_JUSTIFY_LEFT);
-       gtk_box_pack_start (GTK_BOX (basic_label_box), capture_lb, TRUE, TRUE, 0);
-       gtk_widget_show(capture_lb);
-
-       /* Create the two combo boxes */
-       channel_combo = gtk_combo_new();
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_CHANNEL_KEY,channel_combo);
-
-       channel_list = NULL;
-       channel_list = g_list_append(channel_list, "1");
-    channel_list = g_list_append(channel_list, "2");
-    channel_list = g_list_append(channel_list, "3");
-    channel_list = g_list_append(channel_list, "4");
-       channel_list = g_list_append(channel_list, "5");
-       channel_list = g_list_append(channel_list, "6");
-       channel_list = g_list_append(channel_list, "7");
-       channel_list = g_list_append(channel_list, "8");
-       channel_list = g_list_append(channel_list, "9");
-       channel_list = g_list_append(channel_list, "10");
-       channel_list = g_list_append(channel_list, "11");
-       channel_list = g_list_append(channel_list, "12");
-       channel_list = g_list_append(channel_list, "13");
-       channel_list = g_list_append(channel_list, "14");
-       gtk_combo_set_popdown_strings( GTK_COMBO(channel_combo), channel_list) ;
-
-       /* Select the first entry */
-       if(airpcap_if_selected != NULL)
-               {
-               airpcap_update_channel_combo(GTK_WIDGET(channel_combo), airpcap_if_selected);
-               }
+keys_h_sub_box = gtk_vbox_new (FALSE, 0);
+gtk_widget_set_name (keys_h_sub_box, "keys_h_sub_box");
+gtk_widget_show (keys_h_sub_box);
+gtk_container_add (GTK_CONTAINER (keys_al), keys_h_sub_box);
+
+enable_decryption_tb = gtk_table_new (1, 2, FALSE);
+gtk_widget_set_name (enable_decryption_tb, "enable_decryption_tb");
+gtk_widget_show (enable_decryption_tb);
+gtk_box_pack_start (GTK_BOX (keys_h_sub_box), enable_decryption_tb, FALSE,
+             FALSE, 0);
+gtk_table_set_col_spacings (GTK_TABLE (enable_decryption_tb), 6);
+
+enable_decryption_lb = gtk_label_new ("Select Decryption Mode");
+gtk_widget_set_name (enable_decryption_lb, "enable_decryption_lb");
+gtk_widget_show (enable_decryption_lb);
+gtk_table_attach (GTK_TABLE (enable_decryption_tb), enable_decryption_lb, 1,
+           2, 0, 1, (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_misc_set_alignment (GTK_MISC (enable_decryption_lb), 0, 0.5);
+
+enable_decryption_cb = gtk_combo_new ();
+gtk_widget_set_name (enable_decryption_cb, "enable_decryption_cb");
+gtk_widget_show (enable_decryption_cb);
+gtk_table_attach (GTK_TABLE (enable_decryption_tb), enable_decryption_cb, 0,
+           1, 0, 1, (GtkAttachOptions) (0), (GtkAttachOptions) (0),
+           0, 0);
+#if GTK_MAJOR_VERSION >= 2
+gtk_widget_set_size_request (enable_decryption_cb, 83, -1);
+#else
+gtk_widget_set_usize (enable_decryption_cb, 83, -1);
+#endif
+enable_decryption_cb_items = g_list_append (enable_decryption_cb_items, AIRPCAP_DECRYPTION_TYPE_STRING_NONE);
+enable_decryption_cb_items = g_list_append (enable_decryption_cb_items, AIRPCAP_DECRYPTION_TYPE_STRING_WIRESHARK);
+enable_decryption_cb_items = g_list_append (enable_decryption_cb_items, AIRPCAP_DECRYPTION_TYPE_STRING_AIRPCAP);
+gtk_combo_set_popdown_strings (GTK_COMBO (enable_decryption_cb), enable_decryption_cb_items);
+g_list_free (enable_decryption_cb_items);
+
+enable_decryption_en = GTK_COMBO (enable_decryption_cb)->entry;
+gtk_widget_set_name (enable_decryption_en, "enable_decryption_en");
+gtk_widget_show (enable_decryption_en);
+gtk_editable_set_editable (GTK_EDITABLE (enable_decryption_en), FALSE);
+GTK_WIDGET_UNSET_FLAGS (enable_decryption_en, GTK_CAN_FOCUS);
+
+/* Set correct decryption mode!!!! */
+update_decryption_mode_cm(enable_decryption_cb);
+
+keys_v_sub_box = gtk_hbox_new (FALSE, 0);
+gtk_widget_set_name (keys_v_sub_box, "keys_v_sub_box");
+gtk_widget_show (keys_v_sub_box);
+gtk_box_pack_start (GTK_BOX (keys_h_sub_box), keys_v_sub_box, TRUE, TRUE, 0);
+
+keys_scrolled_w = gtk_scrolled_window_new (NULL, NULL);
+gtk_widget_set_name (keys_scrolled_w, "keys_scrolled_w");
+gtk_widget_show (keys_scrolled_w);
+gtk_box_pack_start (GTK_BOX (keys_v_sub_box), keys_scrolled_w, TRUE, TRUE,
+             0);
+gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (keys_scrolled_w), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+key_ls = gtk_clist_new (3);
+gtk_widget_set_name (key_ls, "key_ls");
+gtk_widget_show (key_ls);
+
+airpcap_fill_key_list(key_ls,airpcap_if_selected);
+
+gtk_container_add (GTK_CONTAINER (keys_scrolled_w), key_ls);
+gtk_clist_set_column_width (GTK_CLIST (key_ls), 0, 54);
+gtk_clist_set_column_width (GTK_CLIST (key_ls), 1, 113);
+gtk_clist_set_column_width (GTK_CLIST (key_ls), 2, 80);
+gtk_clist_column_titles_show (GTK_CLIST (key_ls));
+gtk_clist_set_shadow_type (GTK_CLIST (key_ls), GTK_SHADOW_ETCHED_IN);
+gtk_clist_set_column_justification(GTK_CLIST (key_ls),0,GTK_JUSTIFY_CENTER);
+
+key_list_decryption_type_col_lb = gtk_label_new ("Type");
+gtk_widget_set_name (key_list_decryption_type_col_lb,
+              "key_list_decryption_type_col_lb");
+gtk_widget_show (key_list_decryption_type_col_lb);
+gtk_clist_set_column_widget (GTK_CLIST (key_ls), 0, key_list_decryption_type_col_lb);
+
+key_list_decryption_key_col_lb = gtk_label_new ("Key");
+gtk_widget_set_name (key_list_decryption_key_col_lb,
+              "key_list_decryption_key_col_lb");
+gtk_widget_show (key_list_decryption_key_col_lb);
+gtk_clist_set_column_widget (GTK_CLIST (key_ls), 1,
+                      key_list_decryption_key_col_lb);
+
+key_ls_decryption_ssid_col_lb = gtk_label_new ("SSID");
+gtk_widget_set_name (key_ls_decryption_ssid_col_lb,
+              "key_ls_decryption_ssid_col_lb");
+gtk_widget_show (key_ls_decryption_ssid_col_lb);
+gtk_clist_set_column_widget (GTK_CLIST (key_ls), 2,
+                      key_ls_decryption_ssid_col_lb);
+
+/* XXX - USED ONLY BECAUSE WPA and WPA2 are note ready YET... */
+gtk_clist_set_column_visibility(GTK_CLIST (key_ls), 2, FALSE);
+
+key_v_button_box = gtk_vbutton_box_new ();
+gtk_widget_set_name (key_v_button_box, "key_v_button_box");
+gtk_widget_show (key_v_button_box);
+gtk_box_pack_start (GTK_BOX (keys_v_sub_box), key_v_button_box, FALSE, TRUE,
+             0);
+
+#if GTK_MAJOR_VERSION >= 2
+add_new_key_bt = gtk_button_new_with_mnemonic ("Add New Key");
+#else
+add_new_key_bt = gtk_button_new_with_label ("Add New Key");
+#endif
+gtk_widget_set_name (add_new_key_bt, "add_new_key_bt");
+gtk_widget_show (add_new_key_bt);
+gtk_container_add (GTK_CONTAINER (key_v_button_box), add_new_key_bt);
+GTK_WIDGET_SET_FLAGS (add_new_key_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+remove_key_bt = gtk_button_new_with_mnemonic ("Remove Key");
+#else
+remove_key_bt = gtk_button_new_with_label ("Remove Key");
+#endif
+gtk_widget_set_name (remove_key_bt, "remove_key_bt");
+gtk_widget_show (remove_key_bt);
+gtk_container_add (GTK_CONTAINER (key_v_button_box), remove_key_bt);
+GTK_WIDGET_SET_FLAGS (remove_key_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+edit_key_bt = gtk_button_new_with_mnemonic ("Edit Key");
+#else
+edit_key_bt = gtk_button_new_with_label ("Edit Key");
+#endif  
+gtk_widget_set_name (edit_key_bt, "edit_key_bt");
+gtk_widget_show (edit_key_bt);
+gtk_container_add (GTK_CONTAINER (key_v_button_box), edit_key_bt);
+GTK_WIDGET_SET_FLAGS (edit_key_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+move_key_up_bt = gtk_button_new_with_mnemonic ("Move Key Up");
+#else
+move_key_up_bt = gtk_button_new_with_label ("Move Key Up");
+#endif
+gtk_widget_set_name (move_key_up_bt, "move_key_up_bt");
+gtk_widget_show (move_key_up_bt);
+gtk_container_add (GTK_CONTAINER (key_v_button_box), move_key_up_bt);
+GTK_WIDGET_SET_FLAGS (move_key_up_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+move_key_down_bt = gtk_button_new_with_mnemonic ("Move Key Down");
+#else
+move_key_down_bt = gtk_button_new_with_label ("Move Key Down");
+#endif
+gtk_widget_set_name (move_key_down_bt, "move_key_down_bt");
+gtk_widget_show (move_key_down_bt);
+gtk_container_add (GTK_CONTAINER (key_v_button_box), move_key_down_bt);
+GTK_WIDGET_SET_FLAGS (move_key_down_bt, GTK_CAN_DEFAULT);
+
+keys_frame_lb = gtk_label_new ("<b>Decryption Keys</b>");
+gtk_widget_set_name (keys_frame_lb, "keys_frame_lb");
+gtk_widget_show (keys_frame_lb);
+
+#if GTK_MAJOR_VERSION >= 2
+gtk_frame_set_label_widget (GTK_FRAME (keys_fr), keys_frame_lb);
+gtk_label_set_use_markup (GTK_LABEL (keys_frame_lb), TRUE);
+#else
+gtk_frame_set_label (GTK_FRAME (keys_fr), "Decryption Keys");
+#endif
 
-       channel_te = GTK_COMBO(channel_combo)->entry;
-       gtk_editable_set_editable(GTK_EDITABLE(channel_te),FALSE);
-    SIGNAL_CONNECT(channel_te, "changed",  channel_changed_cb, channel_te);
-       gtk_box_pack_start (GTK_BOX (basic_combo_box), channel_combo, FALSE, FALSE, 0);
-       gtk_widget_show(channel_combo);
+low_buttons_h_box = gtk_hbox_new (FALSE, 0);
+gtk_widget_set_name (low_buttons_h_box, "low_buttons_h_box");
+gtk_widget_show (low_buttons_h_box);
+gtk_box_pack_end (GTK_BOX (main_box), low_buttons_h_box, FALSE, FALSE, 0);
+
+left_h_button_box = gtk_hbutton_box_new ();
+gtk_widget_set_name (left_h_button_box, "left_h_button_box");
+gtk_widget_show (left_h_button_box);
+gtk_box_pack_start (GTK_BOX (low_buttons_h_box), left_h_button_box, FALSE,
+             FALSE, 0);
+
+#if GTK_MAJOR_VERSION >= 2
+reset_configuration_bt = gtk_button_new_with_mnemonic ("Reset Configuration");
+#else
+reset_configuration_bt = gtk_button_new_with_label ("Reset Configuration");
+#endif
+gtk_widget_set_name (reset_configuration_bt, "reset_configuration_bt");
+/* gtk_widget_show (reset_configuration_bt); */
+gtk_container_add (GTK_CONTAINER (left_h_button_box),
+            reset_configuration_bt);
+GTK_WIDGET_SET_FLAGS (reset_configuration_bt, GTK_CAN_DEFAULT);
+
+right_h_button_box = gtk_hbutton_box_new ();
+gtk_widget_set_name (right_h_button_box, "right_h_button_box");
+gtk_widget_show (right_h_button_box);
+gtk_box_pack_end (GTK_BOX (low_buttons_h_box), right_h_button_box, FALSE,
+           FALSE, 0);
+gtk_button_box_set_layout (GTK_BUTTON_BOX (right_h_button_box),
+                    GTK_BUTTONBOX_END);
+
+#if GTK_MAJOR_VERSION >= 2
+ok_bt = gtk_button_new_with_mnemonic ("Ok");
+#else
+ok_bt = gtk_button_new_with_label ("Ok");
+#endif
+gtk_widget_set_name (ok_bt, "ok_bt");
+gtk_widget_show (ok_bt);
+gtk_container_add (GTK_CONTAINER (right_h_button_box), ok_bt);
+GTK_WIDGET_SET_FLAGS (ok_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+apply_bt = gtk_button_new_with_mnemonic ("Apply");
+#else
+apply_bt = gtk_button_new_with_label ("Apply");
+#endif
+gtk_widget_set_name (apply_bt, "apply_bt");
+gtk_widget_show (apply_bt);
+gtk_container_add (GTK_CONTAINER (right_h_button_box), apply_bt);
+GTK_WIDGET_SET_FLAGS (apply_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+cancel_bt = gtk_button_new_with_mnemonic ("Cancel");
+#else
+cancel_bt = gtk_button_new_with_label ("Cancel");
+#endif
+gtk_widget_set_name (cancel_bt, "cancel_bt");
+gtk_widget_show (cancel_bt);
+gtk_container_add (GTK_CONTAINER (right_h_button_box), cancel_bt);
+GTK_WIDGET_SET_FLAGS (cancel_bt, GTK_CAN_DEFAULT);
+
+/* Connect the callbacks */
+SIGNAL_CONNECT (key_management_w, "delete_event", window_delete_event_cb, key_management_w);
+SIGNAL_CONNECT (key_management_w, "destroy", on_key_management_destroy, key_management_w);
+/*SIGNAL_CONNECT (enable_decryption_en, "changed",on_enable_decryption_en_changed, toolbar);*/
+SIGNAL_CONNECT (add_new_key_bt, "clicked",on_add_new_key_bt_clicked, key_management_w);
+SIGNAL_CONNECT (remove_key_bt, "clicked",on_remove_key_bt_clicked, key_management_w);
+SIGNAL_CONNECT (edit_key_bt, "clicked",on_edit_key_bt_clicked, key_management_w);
+SIGNAL_CONNECT (move_key_up_bt, "clicked",on_move_key_up_bt_clicked, key_management_w);
+SIGNAL_CONNECT (move_key_down_bt, "clicked",on_move_key_down_bt_clicked, key_management_w);
+SIGNAL_CONNECT (reset_configuration_bt, "clicked",on_reset_configuration_bt_clicked, key_management_w);
+SIGNAL_CONNECT (apply_bt, "clicked",on_key_management_apply_bt_clicked, key_management_w);
+SIGNAL_CONNECT (ok_bt, "clicked",on_key_management_ok_bt_clicked, key_management_w);
+SIGNAL_CONNECT (cancel_bt, "clicked",on_key_management_cancel_bt_clicked, key_management_w);
+SIGNAL_CONNECT (key_ls, "select_row",on_key_ls_select_row, key_management_w);
+SIGNAL_CONNECT (key_ls, "unselect_row",on_key_ls_unselect_row, key_management_w);
+SIGNAL_CONNECT (key_ls, "click_column",on_key_ls_click_column, key_management_w);
+
+/* Different because the window will be closed ... */
+/*window_set_cancel_button(key_management_w, ok_bt, window_cancel_button_cb);
+window_set_cancel_button(key_management_w, cancel_bt, window_cancel_button_cb);*/
+
+OBJECT_SET_DATA (key_management_w, AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY,key_ls_selected_item);
+
+/* Store pointers to all widgets, for use by lookup_widget(). */
+OBJECT_SET_DATA (key_management_w, AIRPCAP_ADVANCED_WEP_DECRYPTION_KEY, enable_decryption_en);
+OBJECT_SET_DATA (key_management_w, AIRPCAP_ADVANCED_KEYLIST_KEY, key_ls);
+OBJECT_SET_DATA (key_management_w, AIRPCAP_ADVANCED_OK_KEY, ok_bt);
+OBJECT_SET_DATA (key_management_w, AIRPCAP_ADVANCED_CANCEL_KEY, cancel_bt);
 
-       capture_combo = gtk_combo_new();
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_LINK_TYPE_KEY,capture_combo);
-       capture_list = NULL;
-       capture_list = g_list_append(capture_list, AIRPCAP_LINK_TYPE_NAME_802_11_ONLY);
-    capture_list = g_list_append(capture_list, AIRPCAP_LINK_TYPE_NAME_802_11_PLUS_RADIO);
-       gtk_combo_set_popdown_strings( GTK_COMBO(capture_combo), capture_list) ;
+/*
+ * I will need the toolbar and the main widget in some callback,
+ * so I will add the toolbar pointer to the key_management_w
+ */
+OBJECT_SET_DATA(key_management_w,AIRPCAP_TOOLBAR_KEY,toolbar);
+OBJECT_SET_DATA (key_management_w, AIRPCAP_TOOLBAR_DECRYPTION_KEY, toolbar_decryption_ck);
 
-       capture_s = NULL;
-       if(airpcap_if_selected != NULL)
-               {
-               if(airpcap_if_selected->linkType == AIRPCAP_LT_802_11)
-                       capture_s = g_strdup_printf("%s",AIRPCAP_LINK_TYPE_NAME_802_11_ONLY);
-               else if(airpcap_if_selected->linkType == AIRPCAP_LT_802_11_PLUS_RADIO)
-                       capture_s = g_strdup_printf("%s",AIRPCAP_LINK_TYPE_NAME_802_11_PLUS_RADIO);
-               if(capture_s != NULL) gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(capture_combo)->entry), capture_s);
-               }
-       g_free(capture_s);
+/* 
+ * This will read the decryption keys from the preferences file, and will store 
+ * them into the registry... 
+ */
+if(!airpcap_check_decryption_keys(airpcap_if_list))
+    {
+    /* Ask the user what to do ...*/
+    airpcap_keys_check_w(key_management_w,NULL);
+    }
+else /* Keys from lists are equals, or wireshark has got no keys */
+    {
+    airpcap_load_decryption_keys(airpcap_if_list);
+    /* At the end, so that it appears completely all together ... */
+    gtk_widget_show (key_management_w);    
+    }
+}
 
-       link_type_te = GTK_COMBO(capture_combo)->entry;
-       gtk_editable_set_editable(GTK_EDITABLE(link_type_te),FALSE);
-    SIGNAL_CONNECT(link_type_te, "changed",  link_type_changed_cb, link_type_te);
-       gtk_box_pack_start (GTK_BOX (basic_combo_box), capture_combo, FALSE, FALSE, 1);
-       gtk_widget_show(capture_combo);
+/*
+ * Callback for the OK button 'clicked' in the Decryption Key Management window.
+ */
+void
+on_key_management_ok_bt_clicked(GtkWidget *button, gpointer data _U_)
+{
+/* advenced window */
+GtkWidget      *key_management_w;
 
-       /* Create the two check boxes */
-       crc_check               = gtk_check_button_new_with_label("Include 802.11 FCS in Frames");
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_CRC_KEY,crc_check);
+/* widgets in the toolbar */
+GtkWidget      *toolbar;
+GtkWidget *toolbar_cm;
 
-       /* Fcs Presence check box */
-       if(airpcap_if_selected != NULL)
-               {
-               if(airpcap_if_selected->IsFcsPresent)
-                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(crc_check),TRUE);
-               else
-                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(crc_check),FALSE);
+GtkWidget   *key_ls;
+
+GtkWidget   *decryption_en;
+
+char* decryption_mode_string = NULL;
+
+/* retrieve main window */
+key_management_w      = GTK_WIDGET(data);
+decryption_en         = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_WEP_DECRYPTION_KEY));
+key_ls               = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_KEYLIST_KEY));
+toolbar               = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_TOOLBAR_KEY));
+toolbar_cm            = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_TOOLBAR_DECRYPTION_KEY));
+
+/* Set the Decryption Mode */
+if(g_strcasecmp(gtk_entry_get_text(GTK_ENTRY(decryption_en)),AIRPCAP_DECRYPTION_TYPE_STRING_WIRESHARK) == 0)
+    {
+    set_wireshark_decryption(TRUE);
+    if(!set_airpcap_decryption(FALSE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+else if(g_strcasecmp(gtk_entry_get_text(GTK_ENTRY(decryption_en)),AIRPCAP_DECRYPTION_TYPE_STRING_AIRPCAP) == 0)
+    {
+    set_wireshark_decryption(FALSE);
+    if(!set_airpcap_decryption(TRUE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+else if(g_strcasecmp(gtk_entry_get_text(GTK_ENTRY(decryption_en)),AIRPCAP_DECRYPTION_TYPE_STRING_NONE) == 0)
+    {
+    set_wireshark_decryption(FALSE);
+    if(!set_airpcap_decryption(FALSE)) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, CANT_SAVE_ERR_STR);
+    }
+
+/* Save the configuration */
+if( (airpcap_if_selected != NULL) )
+    {
+    airpcap_read_and_save_decryption_keys_from_clist(key_ls,airpcap_if_selected,airpcap_if_list); /* This will save the keys for every adapter */
+    
+    /* Update toolbar (only if airpcap_if_selected is airpcap_if_active)*/
+    if( g_strcasecmp(airpcap_if_selected->description,airpcap_if_active->description) == 0)
+       {
+               update_decryption_mode_cm(toolbar_cm);
                }
+    }
+
+/* Redissect all the packets, and re-evaluate the display filter. */
+cf_redissect_packets(&cfile);
+
+/* Save the preferences to preferences file!!! */
+write_prefs_to_file();
+
+/* If interface active is airpcap, set sensitive TRUE for airpcap toolbar */
+if( get_airpcap_if_by_name(airpcap_if_list,airpcap_if_active->description) != NULL)
+       {
+       airpcap_set_toolbar_start_capture(airpcap_if_active);
+       }
+else
+       {
+       airpcap_set_toolbar_stop_capture(airpcap_if_active);
+       }
 
-       SIGNAL_CONNECT(crc_check,"toggled",crc_check_cb,NULL);
-       gtk_box_pack_start (GTK_BOX (basic_check_box), crc_check, FALSE, FALSE, 0);
-       gtk_widget_show(crc_check);
+gtk_widget_destroy(key_management_w);
+}
 
-       /* CRC Filter label */
-       wrong_lb = gtk_label_new("FCS Filter:");
-       gtk_box_pack_start (GTK_BOX (basic_wrong_box), wrong_lb, FALSE, FALSE, 0);
-       gtk_widget_show(wrong_lb);
+/*
+ * Callback for the CANCEL button 'clicked' in the Decryption Key Management window.
+ */
+void
+on_key_management_cancel_bt_clicked(GtkWidget *button, gpointer data _U_)
+{
+PAirpcapHandle ad = NULL;
 
-       /* CRC Filter combo */
-       wrong_crc_combo = gtk_combo_new();
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_WRONG_CRC_KEY,wrong_crc_combo);
+/* Retrieve object data */
+GtkWidget *key_management_w;
+GtkWidget *cancel_bt;
+GtkWidget *ok_bt;
+GtkWidget *key_ls;
 
-       linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_ALL);
-       linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRECT);
-    linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRUPT);
+/* widgets in the toolbar */
+GtkWidget      *toolbar,
+                       *toolbar_decryption_ck,
+                       *key_management_bt;
+                       
+/* Row selected structure */
+airpcap_key_ls_selected_info_t *selected_item;
 
-       gtk_combo_set_popdown_strings( GTK_COMBO(wrong_crc_combo), linktype_list) ;
+/* Retrieve the GUI object pointers */
+key_management_w       = GTK_WIDGET(data);
+cancel_bt                      = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_CANCEL_KEY));
+ok_bt                          = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_OK_KEY));
+key_ls                         = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_KEYLIST_KEY));
+key_management_bt   = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_KEY));
 
-       wrong_crc_te = GTK_COMBO(wrong_crc_combo)->entry;
+toolbar = GTK_WIDGET(OBJECT_GET_DATA(key_management_w,AIRPCAP_TOOLBAR_KEY));
 
-       if(airpcap_if_selected != NULL)
-               {
-               airpcap_validation_type_combo_set_by_type(wrong_crc_combo,airpcap_if_selected->CrcValidationOn);
-               }
+/* retrieve toolbar info */
+toolbar_decryption_ck  = GTK_WIDGET(OBJECT_GET_DATA(toolbar,AIRPCAP_TOOLBAR_DECRYPTION_KEY));
 
-       gtk_editable_set_editable(GTK_EDITABLE(wrong_crc_te),FALSE);
-       SIGNAL_CONNECT(wrong_crc_te,"changed",wrong_crc_combo_cb,wrong_crc_te);
-       gtk_box_pack_start (GTK_BOX (basic_wrong_box), wrong_crc_combo, FALSE, FALSE, 0);
-       gtk_widget_show(wrong_crc_combo);
+/* Retrieve the selected row item pointer... */
+selected_item                  = (airpcap_key_ls_selected_info_t*)(OBJECT_GET_DATA(key_management_w,AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY));
+/* And free it */
+g_free(selected_item);
 
-       gtk_box_pack_start(GTK_BOX(basic_check_box), basic_wrong_box, FALSE, FALSE, 0);
-       gtk_widget_show(basic_wrong_box);
+gtk_widget_destroy(key_management_w);
+}
 
-       /* Add the vertical inner boxes to the basic_box */
-       gtk_box_pack_start (GTK_BOX (basic_box), basic_label_box, FALSE, FALSE, 10);
-       gtk_box_pack_start (GTK_BOX (basic_box), basic_combo_box, FALSE, FALSE, 10);
-       gtk_box_pack_start (GTK_BOX (basic_box), basic_check_box, FALSE, FALSE, 10);
+/*
+ * Dialog box that appears whenever keys are not consistent between wireshark and AirPcap 
+ */
+void
+airpcap_keys_check_w(GtkWidget *w, gpointer data)
+{
+GtkWidget *keys_check_w;
+GtkWidget *main_v_box;
+GtkWidget *warning_lb;
+GtkWidget *radio_tb;
+GtkWidget *keep_rb;
+GSList *radio_bt_group = NULL;
+GtkWidget *merge_rb;
+GtkWidget *import_rb;
+GtkWidget *ignore_rb;
+GtkWidget *keep_lb;
+GtkWidget *merge_lb;
+GtkWidget *import_lb;
+GtkWidget *ignore_lb;
+GtkWidget *low_h_button_box;
+GtkWidget *ok_bt;
+GtkWidget *cancel_bt;
+
+keys_check_w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+gtk_widget_set_name (keys_check_w, "keys_check_w");
+gtk_window_set_title (GTK_WINDOW (keys_check_w), "Decryption Keys WARNING!");
+#if GTK_MAJOR_VERSION >= 2
+gtk_window_set_resizable (GTK_WINDOW (keys_check_w), FALSE);
+#else
+gtk_window_set_policy(GTK_WINDOW(keys_check_w), FALSE, FALSE, TRUE);
+#endif
 
-       gtk_container_set_border_width (GTK_CONTAINER (basic_box), 10);
+main_v_box = gtk_vbox_new (FALSE, 0);
+gtk_widget_set_name (main_v_box, "main_v_box");
+gtk_widget_show (main_v_box);
+gtk_container_add (GTK_CONTAINER (keys_check_w), main_v_box);
 
-       /* Fill the wep_box */
-       wep_sub_box = gtk_hbox_new(FALSE,1);
-       gtk_widget_show(wep_sub_box);
-       encryption_box = gtk_hbox_new(FALSE,1);
-       gtk_widget_show(encryption_box);
+#if GTK_MAJOR_VERSION >= 2
+warning_lb = gtk_label_new("<b>WARNING!</b> Decryption keys specified in Wireshark's preferences file differ from those specified for the AirPcap adapter(s). You can choose to:");
+gtk_label_set_use_markup (GTK_LABEL (warning_lb), TRUE);
+#else
+warning_lb = gtk_label_new("WARNING! Decryption keys specified in Wireshark's preferences file differ from those specified for the AirPcap adapter(s). You can choose to:");
+#endif
+gtk_widget_set_name (warning_lb, "warning_lb");
+gtk_widget_show (warning_lb);
+gtk_box_pack_start (GTK_BOX (main_v_box), warning_lb, FALSE, FALSE, 0);
+gtk_label_set_justify (GTK_LABEL (warning_lb), GTK_JUSTIFY_CENTER);
+gtk_label_set_line_wrap (GTK_LABEL (warning_lb), TRUE);
+
+radio_tb = gtk_table_new (4, 2, FALSE);
+gtk_widget_set_name (radio_tb, "radio_tb");
+gtk_widget_show (radio_tb);
+gtk_box_pack_start (GTK_BOX (main_v_box), radio_tb, TRUE, FALSE, 0);
+gtk_container_set_border_width (GTK_CONTAINER (radio_tb), 5);
+gtk_table_set_col_spacings (GTK_TABLE (radio_tb), 8);
+
+#if GTK_MAJOR_VERSION >= 2
+keep_rb = gtk_radio_button_new_with_mnemonic (NULL, "Keep");
+#else
+keep_rb = gtk_radio_button_new_with_label (NULL, "Keep");
+#endif
+gtk_widget_set_name (keep_rb, "keep_rb");
+gtk_widget_show (keep_rb);
+gtk_table_attach (GTK_TABLE (radio_tb), keep_rb, 0, 1, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_radio_button_set_group (GTK_RADIO_BUTTON (keep_rb), radio_bt_group);
+#if GTK_MAJOR_VERSION >= 2
+radio_bt_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (keep_rb));
+#else
+radio_bt_group = gtk_radio_button_group (GTK_RADIO_BUTTON (keep_rb));
+#endif
 
-       /* encryption enabled box */
-       encryption_check = gtk_check_button_new_with_label("Enable WEP Decryption");
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_WEP_DECRYPTION_KEY,encryption_check);
+#if GTK_MAJOR_VERSION >= 2
+merge_rb = gtk_radio_button_new_with_mnemonic (NULL, "Merge");
+#else
+merge_rb = gtk_radio_button_new_with_label (NULL, "Merge");
+#endif
+gtk_widget_set_name (merge_rb, "merge_rb");
+gtk_widget_show (merge_rb);
+gtk_table_attach (GTK_TABLE (radio_tb), merge_rb, 0, 1, 1, 2,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_radio_button_set_group (GTK_RADIO_BUTTON (merge_rb), radio_bt_group);
+#if GTK_MAJOR_VERSION >= 2
+radio_bt_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (merge_rb));
+#else
+radio_bt_group = gtk_radio_button_group (GTK_RADIO_BUTTON (merge_rb));
+#endif
 
-       /* Fcs Presence check box */
-       if(airpcap_if_selected != NULL)
-               {
-               if(airpcap_if_selected->DecryptionOn == AIRPCAP_DECRYPTION_ON)
-                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(encryption_check),TRUE);
-               else
-                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(encryption_check),FALSE);
-               }
+#if GTK_MAJOR_VERSION >= 2
+import_rb = gtk_radio_button_new_with_mnemonic (NULL, "Import");
+#else
+import_rb = gtk_radio_button_new_with_label (NULL, "Import");
+#endif
+gtk_widget_set_name (import_rb, "import_rb");
+gtk_widget_show (import_rb);
+gtk_table_attach (GTK_TABLE (radio_tb), import_rb, 0, 1, 2, 3,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_radio_button_set_group (GTK_RADIO_BUTTON (import_rb), radio_bt_group);
+#if GTK_MAJOR_VERSION >= 2
+radio_bt_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (import_rb));
+#else
+radio_bt_group = gtk_radio_button_group (GTK_RADIO_BUTTON (import_rb));
+#endif
 
-       SIGNAL_CONNECT(encryption_check,"toggled",wep_encryption_check_cb,NULL);
-       gtk_box_pack_start (GTK_BOX (encryption_box), encryption_check, FALSE, FALSE, 0);
-       gtk_widget_show(encryption_check);
+#if GTK_MAJOR_VERSION >= 2
+ignore_rb = gtk_radio_button_new_with_mnemonic (NULL, "Ignore");
+#else
+ignore_rb = gtk_radio_button_new_with_label (NULL, "Ignore");
+#endif
+gtk_widget_set_name (ignore_rb, "ignore_rb");
+gtk_widget_show (ignore_rb);
+gtk_table_attach (GTK_TABLE (radio_tb), ignore_rb, 0, 1, 3, 4,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_radio_button_set_group (GTK_RADIO_BUTTON (ignore_rb), radio_bt_group);
+#if GTK_MAJOR_VERSION >= 2
+radio_bt_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (ignore_rb));
+#else
+radio_bt_group = gtk_radio_button_group (GTK_RADIO_BUTTON (ignore_rb));
+#endif
 
-       /* WEP text box */
-       key_text = scrolled_window_new(NULL, NULL);
-    /* never use a scrollbar in x direction, show the complete relation string */
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(key_text),
-                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-    #if GTK_MAJOR_VERSION >= 2
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(key_text),
-                                   GTK_SHADOW_IN);
-    #endif
+keep_lb =
+gtk_label_new
+("Use Wireshark keys, thus overwriting AirPcap adapter(s) ones.");
+gtk_widget_set_name (keep_lb, "keep_lb");
+gtk_widget_show (keep_lb);
+gtk_table_attach (GTK_TABLE (radio_tb), keep_lb, 1, 2, 0, 1,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_misc_set_alignment (GTK_MISC (keep_lb), 0, 0.5);
+
+merge_lb = gtk_label_new ("Merge Wireshark and AirPcap adapter(s) keys.");
+gtk_widget_set_name (merge_lb, "merge_lb");
+gtk_widget_show (merge_lb);
+gtk_table_attach (GTK_TABLE (radio_tb), merge_lb, 1, 2, 1, 2,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_misc_set_alignment (GTK_MISC (merge_lb), 0, 0.5);
+
+import_lb =
+gtk_label_new
+("Use AirPcap adapter(s) keys, thus overwriting Wireshark ones.");
+gtk_widget_set_name (import_lb, "import_lb");
+gtk_widget_show (import_lb);
+gtk_table_attach (GTK_TABLE (radio_tb), import_lb, 1, 2, 2, 3,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_misc_set_alignment (GTK_MISC (import_lb), 0, 0.5);
+
+ignore_lb =
+gtk_label_new
+("Keep using different set of keys. Remember that in this case, this dialog box will appear whenever you will attempt to modify/add/remove decryption keys.");
+gtk_widget_set_name (ignore_lb, "ignore_lb");
+gtk_widget_show (ignore_lb);
+gtk_table_attach (GTK_TABLE (radio_tb), ignore_lb, 1, 2, 3, 4,
+           (GtkAttachOptions) (GTK_FILL),
+           (GtkAttachOptions) (0), 0, 0);
+gtk_label_set_line_wrap (GTK_LABEL (ignore_lb), TRUE);
+gtk_misc_set_alignment (GTK_MISC (ignore_lb), 0, 0.5);
+
+low_h_button_box = gtk_hbutton_box_new ();
+gtk_widget_set_name (low_h_button_box, "low_h_button_box");
+gtk_widget_show (low_h_button_box);
+gtk_box_pack_start (GTK_BOX (main_v_box), low_h_button_box, FALSE, FALSE,
+             0);
+gtk_button_box_set_layout (GTK_BUTTON_BOX (low_h_button_box),
+                    GTK_BUTTONBOX_SPREAD);
+
+#if GTK_MAJOR_VERSION >= 2
+ok_bt = gtk_button_new_with_mnemonic ("Ok");
+#else
+ok_bt = gtk_button_new_with_label ("Ok");
+#endif
+gtk_widget_set_name (ok_bt, "ok_bt");
+gtk_widget_show (ok_bt);
+gtk_container_add (GTK_CONTAINER (low_h_button_box), ok_bt);
+GTK_WIDGET_SET_FLAGS (ok_bt, GTK_CAN_DEFAULT);
+
+#if GTK_MAJOR_VERSION >= 2
+cancel_bt = gtk_button_new_with_mnemonic ("Cancel");
+#else
+cancel_bt = gtk_button_new_with_label ("Cancel");
+#endif
+gtk_widget_set_name (cancel_bt, "cancel_bt");
+gtk_widget_show (cancel_bt);
+gtk_container_add (GTK_CONTAINER (low_h_button_box), cancel_bt);
+GTK_WIDGET_SET_FLAGS (cancel_bt, GTK_CAN_DEFAULT);
+
+/* Store pointers to all widgets, for use by lookup_widget(). */
+SIGNAL_CONNECT (ok_bt, "clicked", on_keys_check_ok_bt_clicked, keys_check_w);
+SIGNAL_CONNECT (cancel_bt, "clicked", on_keys_check_cancel_bt_clicked, keys_check_w);
+SIGNAL_CONNECT (keys_check_w, "destroy", on_keys_check_w_destroy, keys_check_w);
+
+/* Store pointers to all widgets, for use by lookup_widget(). */
+OBJECT_SET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_KEY,w);
+OBJECT_SET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_MERGE_KEY,merge_rb);
+OBJECT_SET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_KEEP_KEY,keep_rb);
+OBJECT_SET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_IMPORT_KEY,import_rb);
+OBJECT_SET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_IGNORE_KEY,ignore_rb);
+OBJECT_SET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_GROUP_KEY,radio_bt_group);
+
+gtk_widget_set_sensitive(top_level,FALSE);
+gtk_widget_show(keys_check_w);
+}
 
-       /* add WEP keys if present... */
-    key_ls = gtk_list_new();
-    gtk_list_set_selection_mode(GTK_LIST(key_ls), GTK_SELECTION_SINGLE);
-       OBJECT_SET_DATA(airpcap_advanced_w,AIRPCAP_ADVANCED_KEYLIST_KEY,key_ls);
+void
+on_keys_check_cancel_bt_clicked (GtkWidget *button, gpointer user_data)
+{
+GtkWidget *key_management_w;
+GtkWidget *keys_check_w;
 
-       airpcap_fill_key_list(key_ls,airpcap_if_selected);
-       gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(key_text),key_ls);
-       gtk_widget_show(key_ls);
-       gtk_box_pack_start (GTK_BOX (wep_sub_box), key_text, TRUE, TRUE, 0);
-       gtk_widget_show(key_text);
-
-       /* WEP buttons */
-       wep_buttons_box = gtk_vbox_new(FALSE,0);
-
-       /* Create and add buttons */
-       add_new_key_bt = gtk_button_new_with_label("Add New Key");
-       SIGNAL_CONNECT(add_new_key_bt, "clicked", airpcap_advanced_add_key_cb, airpcap_advanced_w);
-       gtk_box_pack_start (GTK_BOX (wep_buttons_box), add_new_key_bt, FALSE, FALSE, 0);
-       gtk_widget_show(add_new_key_bt);
-       remove_key_bt = gtk_button_new_with_label("Remove Key");
-       SIGNAL_CONNECT(remove_key_bt, "clicked", airpcap_advanced_remove_key_cb, key_ls);
-       gtk_box_pack_start (GTK_BOX (wep_buttons_box), remove_key_bt, FALSE, FALSE, 0);
-       gtk_widget_show(remove_key_bt);
-       edit_key_bt = gtk_button_new_with_label("Edit Key");
-       SIGNAL_CONNECT(edit_key_bt, "clicked", airpcap_advanced_edit_key_cb, airpcap_advanced_w);
-       gtk_box_pack_start (GTK_BOX (wep_buttons_box), edit_key_bt, FALSE, FALSE, 0);
-       gtk_widget_show(edit_key_bt);
-       move_key_up_bt = gtk_button_new_with_label("Move Key Up");
-       SIGNAL_CONNECT(move_key_up_bt, "clicked", airpcap_advanced_move_key_up_cb, key_ls);
-       gtk_box_pack_start (GTK_BOX (wep_buttons_box), move_key_up_bt, FALSE, FALSE, 0);
-       gtk_widget_show(move_key_up_bt);
-       move_key_down_bt = gtk_button_new_with_label("Move Key Down");
-       SIGNAL_CONNECT(move_key_down_bt, "clicked", airpcap_advanced_move_key_down_cb, key_ls);
-       gtk_box_pack_start (GTK_BOX (wep_buttons_box), move_key_down_bt, FALSE, FALSE, 0);
-       gtk_widget_show(move_key_down_bt);
-
-       gtk_box_pack_end (GTK_BOX (wep_sub_box), wep_buttons_box, FALSE, FALSE, 0);
-
-       gtk_container_set_border_width (GTK_CONTAINER (wep_sub_box), 10);
-
-       gtk_box_pack_start (GTK_BOX (wep_box), encryption_box, FALSE, FALSE,0);
-       gtk_box_pack_start (GTK_BOX (wep_box), wep_sub_box, FALSE, FALSE,0);
-       gtk_widget_show(wep_sub_box);
-
-       /* Add them to the frames */
-       gtk_container_add(GTK_CONTAINER(interface_frame),interface_box);
-       gtk_container_add(GTK_CONTAINER(basic_frame),basic_box);
-       gtk_container_add(GTK_CONTAINER(wep_frame),wep_box);
-
-       /* Add frames to the main box */
-       gtk_box_pack_start (GTK_BOX (main_box), interface_frame, FALSE, FALSE, 1);
-       gtk_box_pack_start (GTK_BOX (main_box), basic_frame, FALSE, FALSE, 1);
-       gtk_box_pack_start (GTK_BOX (main_box), wep_frame, FALSE, FALSE, 1);
-
-       /* Add buttons' boxes to the main box */
-       gtk_box_pack_start (GTK_BOX (main_box), buttons_box_2, FALSE, FALSE, 1);
-
-       /* Add the main box to the main window */
-       gtk_container_add(GTK_CONTAINER(airpcap_advanced_w),main_box);
-
-       /* SHOW EVERYTHING */
-       /* Show the WEP key buttons */
-       gtk_widget_show (wep_buttons_box);
-
-       /* Show the combo and check boxes */
-       gtk_widget_show (basic_label_box);
-       gtk_widget_show (basic_combo_box);
-       gtk_widget_show (basic_check_box);
-
-       /* Show the button boxes */
-       gtk_widget_show (buttons_box_1);
-       gtk_widget_show (buttons_box_2);
-
-       /* Show the frames */
-       gtk_widget_show (interface_frame);
-       gtk_widget_show (basic_frame);
-       gtk_widget_show (wep_frame);
-
-       /* Show the sub main boxes */
-       gtk_widget_show (interface_box);
-       gtk_widget_show (basic_box);
-       gtk_widget_show (wep_box);
-
-       /* Show the main box */
-       gtk_widget_show (main_box);
-
-       /* Show the window */
-       gtk_widget_show (airpcap_advanced_w);
+keys_check_w = GTK_WIDGET(user_data);
+
+key_management_w = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_KEY);
+
+/* w may be NULL if airpcap_keys_check_w() has been called while wireshark was loading, 
+   and is not NULL if it was called when the Key Management widget has been clicked */
+  if(key_management_w != NULL)
+     {
+     /*  ... */
+     gtk_widget_show (key_management_w);
+     }
+
+gtk_widget_destroy(keys_check_w);
 }
 
+void
+on_keys_check_ok_bt_clicked (GtkWidget *button, gpointer user_data)
+{
+GtkWidget *key_management_w;
+GtkWidget *keys_check_w;
+
+GtkWidget *merge_rb,
+          *keep_rb,
+          *import_rb,
+          *ignore_rb;
+
+keys_check_w = GTK_WIDGET(user_data);
+
+key_management_w = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_KEY);
+merge_rb  = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_MERGE_KEY);
+keep_rb   = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_KEEP_KEY);
+import_rb = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_IMPORT_KEY);
+ignore_rb = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_RADIO_IGNORE_KEY);
+
+/* Find out which radio button is selected and call the correct function */
+if(GTK_TOGGLE_BUTTON(merge_rb)->active) on_merge_bt_clicked (merge_rb,keys_check_w);
+else if(GTK_TOGGLE_BUTTON(keep_rb)->active) on_keep_bt_clicked (keep_rb,keys_check_w);
+else if(GTK_TOGGLE_BUTTON(import_rb)->active) on_import_bt_clicked (import_rb,keys_check_w);
+else if(GTK_TOGGLE_BUTTON(ignore_rb)->active) on_ignore_bt_clicked (ignore_rb,keys_check_w);
+else on_keys_check_cancel_bt_clicked(NULL,keys_check_w);
+}
+
+void
+on_keys_check_w_destroy (GtkWidget *w, gpointer user_data)
+{
+gtk_widget_set_sensitive(top_level,TRUE);
+gtk_widget_set_sensitive(GTK_WIDGET(user_data),TRUE);
+}
+
+void
+on_keep_bt_clicked (GtkWidget *button, gpointer user_data)
+{
+GtkWidget *key_management_w;
+GtkWidget *keys_check_w;
+
+keys_check_w = GTK_WIDGET(user_data);
+
+key_management_w = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_KEY);
+
+/* w may be NULL if airpcap_keys_check_w() has been called while wireshark was loading, 
+   and is not NULL if it was called when the Key Management widget has been clicked */
+  if(key_management_w != NULL)
+     {
+     /*  ... */
+     gtk_widget_show (key_management_w);
+     }
+
+gtk_widget_destroy(keys_check_w);
+
+airpcap_load_decryption_keys(airpcap_if_list);
+}
+
+void
+on_merge_bt_clicked (GtkWidget * button, gpointer user_data)
+{
+GtkWidget *key_management_w;
+GtkWidget *keys_check_w;
+
+guint n_adapters = 0;
+guint n_wireshark_keys = 0;
+guint n_curr_adapter_keys = 0;
+guint n_total_keys = 0;
+guint n_merged_keys = 0;
+guint i = 0;
+
+GList* wireshark_keys=NULL;
+GList* current_adapter_keys=NULL;
+GList* merged_list = NULL;
+GList* merged_list_tmp = NULL;
+
+airpcap_if_info_t* curr_adapter;
+
+keys_check_w = GTK_WIDGET(user_data);
+
+key_management_w = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_KEY);
+
+
+/* w may be NULL if airpcap_keys_check_w() has been called while wireshark was loading, 
+   and is not NULL if it was called when the Key Management widget has been clicked */
+if(key_management_w != NULL)
+    {
+    /*  ... */
+    gtk_widget_show (key_management_w);
+    }
+
+n_adapters = g_list_length(airpcap_if_list);
+
+wireshark_keys = get_wireshark_keys();
+n_wireshark_keys = g_list_length(wireshark_keys);
+n_total_keys += n_wireshark_keys;
+
+merged_list = merge_key_list(wireshark_keys,NULL);
+
+/* NOW wireshark_keys IS no more needed... at the end, we will have to free it! */
+for(i = 0; i<n_adapters; i++)
+    {
+    curr_adapter = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
+    current_adapter_keys = get_airpcap_device_keys(curr_adapter);
+    n_curr_adapter_keys = g_list_length(current_adapter_keys);
+
+    merged_list_tmp = merged_list;    
+    merged_list = merge_key_list(merged_list_tmp,current_adapter_keys);    
+    free_key_list(merged_list_tmp);
+    
+    n_total_keys += n_curr_adapter_keys;    
+    }
+
+n_merged_keys = g_list_length(merged_list);
+
+/* Set up this new list as default for Wireshark and Adapters... */
+airpcap_save_decryption_keys(merged_list,airpcap_if_list);
+
+free_key_list(wireshark_keys);
+
+gtk_widget_destroy(keys_check_w);
+}
+
+
+void
+on_import_bt_clicked (GtkWidget * button, gpointer user_data)
+{
+GtkWidget *key_management_w;
+GtkWidget *keys_check_w;
+
+guint n_adapters = 0;
+guint n_wireshark_keys = 0;
+guint n_curr_adapter_keys = 0;
+guint n_total_keys = 0;
+guint n_merged_keys = 0;
+guint i = 0;
+
+GList* wireshark_keys=NULL;
+GList* current_adapter_keys=NULL;
+GList* merged_list = NULL;
+GList* merged_list_tmp = NULL;
+
+airpcap_if_info_t* curr_adapter;
+
+keys_check_w = GTK_WIDGET(user_data);
+
+key_management_w = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_KEY);
+
+
+/* w may be NULL if airpcap_keys_check_w() has been called while wireshark was loading, 
+   and is not NULL if it was called when the Key Management widget has been clicked */
+if(key_management_w != NULL)
+    {
+    /*  ... */
+    gtk_widget_show (key_management_w);
+    }
+
+n_adapters = g_list_length(airpcap_if_list);
+
+wireshark_keys = get_wireshark_keys();
+n_wireshark_keys = g_list_length(wireshark_keys);
+n_total_keys += n_wireshark_keys;
+
+/* NOW wireshark_keys IS no more needed... at the end, we will have to free it! */
+for(i = 0; i<n_adapters; i++)
+    {
+    curr_adapter = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
+    current_adapter_keys = get_airpcap_device_keys(curr_adapter);
+    n_curr_adapter_keys = g_list_length(current_adapter_keys);
+
+    merged_list_tmp = merged_list;    
+    merged_list = merge_key_list(merged_list_tmp,current_adapter_keys);    
+    free_key_list(merged_list_tmp);
+    
+    n_total_keys += n_curr_adapter_keys;    
+    }
+
+n_merged_keys = g_list_length(merged_list);
+
+/* Set up this new list as default for Wireshark and Adapters... */
+airpcap_save_decryption_keys(merged_list,airpcap_if_list);
+
+free_key_list(wireshark_keys);
+
+gtk_widget_destroy(keys_check_w);
+}
+
+
+void
+on_ignore_bt_clicked (GtkWidget * button, gpointer user_data)
+{
+GtkWidget *key_management_w;
+GtkWidget *keys_check_w;
+
+keys_check_w = GTK_WIDGET(user_data);
+
+key_management_w = OBJECT_GET_DATA(keys_check_w,AIRPCAP_CHECK_WINDOW_KEY);
+
+/* w may be NULL if airpcap_keys_check_w() has been called while wireshark was loading, 
+   and is not NULL if it was called when the Key Management widget has been clicked */
+  if(key_management_w != NULL)
+     {
+     /*  ... */
+     gtk_widget_show (key_management_w);
+     }
+
+gtk_widget_destroy(keys_check_w);
+}
+
+
 #endif /* HAVE_AIRPCAP */
index 3e1ff0bf4f0ac4b1624db533f4ddaf4ceccf7c81..870a5617bf1b69b1d494acbac06a106aedcf2c27 100644 (file)
 #define AIRPCAP_ADVANCED_FROM_OPTIONS 1
 
 /*
- * Takes the keys from the GtkList widget, and add them to the interface list
+ * Returns FALSE if a text string has lenght 0, i.e. the first char 
+ * is '\0', TRUE otherwise
  */
-void airpcap_add_keys_from_list(GtkWidget *w, airpcap_if_info_t *if_info);
+gboolean
+string_is_not_empty(gchar *s);
+
+/*
+ * Edit key window destroy callback
+ */
+void
+on_edit_key_w_destroy(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Add key window destroy callback
+ */
+void
+on_add_key_w_destroy(GtkWidget *button, gpointer data _U_);
 
 /*
  * Pop-up window, used to ask the user if he wants to save the selected interface settings
@@ -65,17 +79,105 @@ airpcap_change_if(GtkWidget *entry _U_, gpointer data);
 void
 airpcap_fill_if_combo(GtkWidget *combo, GList* if_list);
 
+/*
+ * Callback for the 'Add Key' button.
+ */
+void
+on_add_new_key_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the 'Remove Key' button.
+ */
+void
+on_remove_key_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the 'Edit Key' button.
+ */
+void
+on_edit_key_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the 'Move Key Down' button.
+ */
+void
+on_move_key_down_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the 'Move Key Up' button.
+ */
+void
+on_move_key_up_bt_clicked(GtkWidget *button, gpointer data _U_);
+
 /*
  * Add key window destroy callback
  */
 static void
 add_key_w_destroy_cb(GtkWidget *button, gpointer data _U_);
 
+/*
+ * Callback for the Wireless Advanced Settings 'Apply' button.
+ */
+void
+on_advanced_apply_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the OK button 'clicked' in the Advanced Wireless Settings window.
+ */
+void
+on_advanced_ok_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the CANCEL button 'clicked' in the Advanced Wireless Settings window.
+ */
+void
+on_advanced_cancel_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the 'Apply' button.
+ */
+void
+on_key_management_apply_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the OK button 'clicked' in the Decryption Key Management window.
+ */
+void
+on_key_management_ok_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the CANCEL button 'clicked' in the Decryption Key Management window.
+ */
+void
+on_key_management_cancel_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/* the window was closed, cleanup things */
+void
+on_key_management_destroy(GtkWidget *w _U_, gpointer data _U_);
+
+/*
+ * Callback for the 'Reset Configuration' button.
+ */
+void
+on_reset_configuration_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/* 
+ * Turns the decryption on or off
+ */
+void
+on_enable_decryption_en_changed(GtkWidget *w, gpointer data);
+
+/*
+ * Will fill the given combo box with the current decryption mode string
+ */
+void
+update_decryption_mode_cm(GtkWidget *w);
+
 /*
  * Changed callback for the channel combobox
  */
 static void
-channel_changed_cb(GtkWidget *w _U_, gpointer data);
+on_channel_en_changed(GtkWidget *w _U_, gpointer data);
 
 /*
  * Activate callback for the link layer combobox
@@ -90,10 +192,44 @@ static void
 link_layer_changed_cb(GtkWidget *w _U_, gpointer data);
 
 /*
- * Callback for the crc chackbox
+ * Callback for the frame check sequence checkbox
  */
 static void
-crc_check_cb(GtkWidget *w, gpointer user_data);
+on_fcs_ck_toggled(GtkWidget *w, gpointer user_data);
+
+/* 
+ * Reset configuration
+ */
+void
+on_reset_configuration_bt_clicked(GtkWidget *button, gpointer data _U_);
+
+/*
+ * Callback for the select row event in the key list widget
+ */
+void
+on_key_ls_select_row(GtkWidget *widget, 
+                     gint row,
+                     gint column,
+                     GdkEventButton *event,
+                     gpointer data);
+
+/*
+ * Callback for the unselect row event in the key list widget
+ */
+void
+on_key_ls_unselect_row(GtkWidget *widget, 
+                     gint row,
+                     gint column,
+                     GdkEventButton *event,
+                     gpointer data);
+
+/*
+ * Callback for the click column event in the key list widget
+ */
+void
+on_key_ls_click_column(GtkWidget *widget,
+                       gint column,
+                       gpointer data);
 
 /*
  * Callback for the wrong crc chackbox
@@ -119,12 +255,6 @@ key_sel_list_button_cb(GtkWidget *widget, GdkEventButton *event,gpointer func_da
 static void
 combo_if_activate_cb(GtkWidget *w _U_, gpointer data);
 
-/*
- * Changed callback for the adapter combobox
- */
-static void
-airpcap_advanced_combo_if_changed_cb(GtkWidget *w _U_, gpointer data);
-
 /*
  * Pop-up window that appears when user confirms the "Save settings..." dialog
  */
@@ -139,7 +269,14 @@ void update_blink(gpointer data _U_);
 /*
  * Blink button callback
  */
-void blink_cb(GtkWidget *blink_bt _U_, gpointer if_data);
+void 
+on_blink_bt_clicked(GtkWidget *blink_bt _U_, gpointer if_data);
+
+/*
+ * Callback for the 'Any' adapter What's This button.
+ */
+void
+on_what_s_this_bt_clicked( GtkWidget *blink_bt _U_, gpointer if_data );
 
 /** Create a "Airpcap" dialog box caused by a button click.
  *
@@ -148,4 +285,36 @@ void blink_cb(GtkWidget *blink_bt _U_, gpointer if_data);
  */
 void display_airpcap_advanced_cb(GtkWidget *widget, gpointer construct_args_ptr);
 
+/* Called to create the key management window */
+void
+display_airpcap_key_management_cb(GtkWidget *w, gpointer data);
+
+/**/
+/*
+ * Dialog box that appears whenever keys are not consistent between wieshark and airpcap 
+ */
+void
+airpcap_keys_check_w(GtkWidget *w, gpointer data);
+
+void
+on_keys_check_w_destroy (GtkWidget *w, gpointer user_data);
+
+void
+on_keys_check_cancel_bt_clicked (GtkWidget *button, gpointer user_data);
+
+void
+on_keys_check_ok_bt_clicked (GtkWidget *button, gpointer user_data);
+
+void
+on_keep_bt_clicked (GtkWidget *button, gpointer user_data);
+
+void
+on_merge_bt_clicked (GtkWidget *button, gpointer user_data);
+
+void
+on_import_bt_clicked (GtkWidget *button, gpointer user_data);
+
+void
+on_ignore_bt_clicked (GtkWidget *button, gpointer user_data);
+
 #endif
index 3c02320ca29cbe98309f3b48c3158512893709f1..82e68fa38a771b626be62d137c6847adac2a90c7 100755 (executable)
 
 #include "keys.h"
 
+/*
+ * Used to retrieve a string containing a list of all the channels
+ * on which at least one adapter is capturing. This is true
+ * if the adapter passed as parameter is "Any" ... if not,
+ * this function returns the only channel number string.
+ */
+gchar*
+airpcap_get_all_channels_list(airpcap_if_info_t* if_info)
+{
+gchar *channels;
+gchar *tmp;
+guint n,i; 
+GList *current_item;
+airpcap_if_info_t* current_adapter;
+
+/* Allocate the string used to store the ASCII representation of the WEP key */
+channels = (gchar*)g_malloc(sizeof(gchar)*128);
+/* Make sure that the first char is '\0' in order to make g_strlcat() work */
+channels[0]='\0';
+
+if(airpcap_if_is_any(if_info))
+    {
+    n = g_list_length(airpcap_if_list);
+        
+    for(i = 0; i < n; i++)
+        {
+        current_item = g_list_nth(airpcap_if_list,i);
+        current_adapter = (airpcap_if_info_t*)current_item->data;
+        if(current_adapter != if_info)
+            {
+            tmp = g_strdup_printf("%d",current_adapter->channel);
+            g_strlcat(channels,tmp,128);
+            g_free(tmp);
+            
+            if(i<(n-1)) g_strlcat(channels,",",128);  
+            }
+        }       
+    }
+    
+return channels;
+}
+
 /*
  * Set up the airpcap toolbar for the new capture interface
  */
@@ -63,14 +105,16 @@ GtkWidget *airpcap_toolbar_label;
 GtkWidget *airpcap_toolbar_channel;
 GtkWidget *airpcap_toolbar_button;
 GtkWidget *airpcap_toolbar_decryption;
+GtkWidget *airpcap_toolbar_keys_button;
 
 gchar *if_label_text;
 
-airpcap_toolbar_crc_filter_combo = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_WRONG_CRC_KEY);
+airpcap_toolbar_crc_filter_combo = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_KEY);
 airpcap_toolbar_label    = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_INTERFACE_KEY);
 airpcap_toolbar_channel  = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_KEY);
 airpcap_toolbar_button   = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_ADVANCED_KEY);
 airpcap_toolbar_decryption = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_KEY);
+airpcap_toolbar_keys_button = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY);
 
 /* The current interface is an airpcap interface */
 if(if_info != NULL)
@@ -81,6 +125,7 @@ if(if_info != NULL)
        gtk_widget_set_sensitive(airpcap_toolbar_crc_filter_combo,FALSE);
        gtk_widget_set_sensitive(airpcap_toolbar_button,FALSE);
        gtk_widget_set_sensitive(airpcap_toolbar_decryption,FALSE);
+       gtk_widget_set_sensitive(airpcap_toolbar_keys_button,FALSE);
        airpcap_validation_type_combo_set_by_type(GTK_WIDGET(airpcap_toolbar_crc_filter_combo),if_info->CrcValidationOn);
     airpcap_update_channel_combo(GTK_WIDGET(airpcap_toolbar_channel),if_info);
 
@@ -126,14 +171,16 @@ GtkWidget *airpcap_toolbar_label;
 GtkWidget *airpcap_toolbar_channel;
 GtkWidget *airpcap_toolbar_button;
 GtkWidget *airpcap_toolbar_decryption;
+GtkWidget *airpcap_toolbar_keys_button;
 
 gchar *if_label_text;
 
-airpcap_toolbar_crc_filter_combo = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_WRONG_CRC_KEY);
+airpcap_toolbar_crc_filter_combo = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_KEY);
 airpcap_toolbar_label    = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_INTERFACE_KEY);
 airpcap_toolbar_channel  = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_KEY);
 airpcap_toolbar_button   = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_ADVANCED_KEY);
 airpcap_toolbar_decryption = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_KEY);
+airpcap_toolbar_keys_button = OBJECT_GET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY);
 
 /* The current interface is an airpcap interface */
 if(if_info != NULL)
@@ -144,6 +191,7 @@ if(if_info != NULL)
        gtk_widget_set_sensitive(airpcap_toolbar_crc_filter_combo,TRUE);
        gtk_widget_set_sensitive(airpcap_toolbar_button,TRUE);
        gtk_widget_set_sensitive(airpcap_toolbar_decryption,TRUE);
+       gtk_widget_set_sensitive(airpcap_toolbar_keys_button,TRUE);
        airpcap_validation_type_combo_set_by_type(GTK_WIDGET(airpcap_toolbar_crc_filter_combo),if_info->CrcValidationOn);
     airpcap_update_channel_combo(GTK_WIDGET(airpcap_toolbar_channel),if_info);
 
@@ -183,18 +231,41 @@ else
  * Add a key (string) to the given list
  */
 void
-airpcap_add_key_to_list(GtkWidget *keylist, gchar* s)
+airpcap_add_key_to_list(GtkWidget *keylist, gchar* type, gchar* key, gchar* ssid)
 {
-GtkWidget      *nl_item,*nl_lb;
 
-nl_lb   = gtk_label_new(s);
-nl_item = gtk_list_item_new();
+gchar*       new_row[3];
 
-gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
-gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
-gtk_widget_show(nl_lb);
-gtk_container_add(GTK_CONTAINER(keylist), nl_item);
-gtk_widget_show(nl_item);
+new_row[0] = g_strdup(type);
+new_row[1] = g_strdup(key);
+new_row[2] = g_strdup(ssid);
+
+gtk_clist_append(GTK_CLIST(keylist),new_row);
+
+g_free(new_row[0]);
+g_free(new_row[1]);
+g_free(new_row[2]);
+}
+
+/*
+ * Modify a key given a list and a row
+ */
+void
+airpcap_modify_key_in_list(GtkWidget *keylist, gint row, gchar* type, gchar* key, gchar* ssid)
+{
+gchar*       new_row[3];
+
+new_row[0] = g_strdup(type);
+new_row[1] = g_strdup(key);
+new_row[2] = g_strdup(ssid);
+
+gtk_clist_set_text(GTK_CLIST(keylist),row,0,new_row[0]);
+gtk_clist_set_text(GTK_CLIST(keylist),row,1,new_row[1]);
+gtk_clist_set_text(GTK_CLIST(keylist),row,2,new_row[2]);
+
+g_free(new_row[0]);
+g_free(new_row[1]);
+g_free(new_row[2]);
 }
 
 /*
@@ -203,9 +274,9 @@ gtk_widget_show(nl_item);
 void
 airpcap_fill_key_list(GtkWidget *keylist,airpcap_if_info_t* if_info)
 {
-GtkWidget       *nl_item,*nl_lb;
 gchar*          s;
 unsigned int i,n;
+gchar*       new_row[3];
 
 n = 0;
 
@@ -214,17 +285,43 @@ n = 0;
         n = if_info->keysCollection->nKeys;
                for(i = 0; i < if_info->keysCollection->nKeys; i++)
                        {
-                       s = airpcap_get_key_string(if_info->keysCollection->Keys[i]); /* g_strdup_printf("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\0"); */
-
-                       nl_lb   = gtk_label_new(s);
+                       s = airpcap_get_key_string(if_info->keysCollection->Keys[i]);
+                       
+                       if(if_info->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_WEP)
+                       {
+            new_row[0] = g_strdup(AIRPCAP_WEP_KEY_STRING);
+                       new_row[1] = g_strdup(s);
+                       new_row[2] = g_strdup("");
+            }
+            else if(if_info->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_TKIP)
+            {
+            new_row[0] = g_strdup(AIRPCAP_WPA_KEY_STRING);
+                       new_row[1] = g_strdup(s);
+                       /* XXX - Put here the SSID */
+                       new_row[2] = g_strdup("");     
+            }
+            else if(if_info->keysCollection->Keys[i].KeyType == AIRPCAP_KEYTYPE_CCMP)
+            {
+            new_row[0] = g_strdup(AIRPCAP_WPA2_KEY_STRING);
+                       new_row[1] = g_strdup(s);
+                       /* XXX - Put here the SSID */
+                       new_row[2] = g_strdup("");
+            }
+            else
+            {
+            /* This should never happen... but just in case... */
+            new_row[0] = g_strdup("");
+                       new_row[1] = g_strdup("");
+                       new_row[2] = g_strdup("");
+            }
+                       
+                       gtk_clist_append(GTK_CLIST(keylist),new_row);
+                       
+                       g_free(new_row[0]);
+                       g_free(new_row[1]);
+                       g_free(new_row[2]);
+                       
                        g_free(s);
-
-                       nl_item = gtk_list_item_new();
-                       gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
-                       gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
-                       gtk_widget_show(nl_lb);
-                       gtk_container_add(GTK_CONTAINER(keylist), nl_item);
-                       gtk_widget_show(nl_item);
                        }
                }
 }
@@ -410,21 +507,25 @@ airpcap_channel_combo_set_by_number(GtkWidget* w,UINT channel)
 int
 airpcap_if_is_any(airpcap_if_info_t* if_info)
 {
-if(g_strcasecmp(if_info->name,AIRPCAP_DEVICE_ANY_EXTRACT_STRING)==0)
+if(g_strcasecmp(if_info->name,AIRPCAP_DEVICE_ANY_EXTRACT_STRING)==0)  
     return 1;
 else
-    return 0;
+    return 0;                                   
 }
 
 /*
  * Update channel combo box. If the airpcap interface is "Any", the combo box will be disabled.
  */
-void
+void 
 airpcap_update_channel_combo(GtkWidget* w, airpcap_if_info_t* if_info)
 {
+gchar* channels_list;
+                                        
 if(airpcap_if_is_any(if_info))
     {
-    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w)->entry)," ");
+    channels_list = airpcap_get_all_channels_list(if_info);
+    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w)->entry),channels_list);
+    g_free(channels_list);
     gtk_widget_set_sensitive(GTK_WIDGET(w),FALSE);
     }
 else
@@ -434,4 +535,249 @@ else
     }
 }
 
+/*
+ * Takes the keys from the GtkList widget, and add them to the interface list
+ */
+void
+airpcap_add_keys_from_list(GtkWidget *key_ls, airpcap_if_info_t *if_info)
+{
+GString                *new_key;
+
+gchar          *text_entered = NULL;
+
+/* airpcap stuff */
+UINT i, j;
+gchar s[3];
+PAirpcapKeysCollection KeysCollection;
+ULONG KeysCollectionSize;
+UCHAR KeyByte;
+
+UINT keys_in_list = 0;
+
+gchar *row_type,
+      *row_key,
+      *row_ssid;
+
+keys_in_list = GTK_CLIST(key_ls)->rows;
+
+/*
+ * Save the encryption keys, if we have any of them
+ */
+KeysCollectionSize = 0;
+
+/*
+ * Calculate the size of the keys collection
+ */
+KeysCollectionSize = sizeof(AirpcapKeysCollection) + keys_in_list * sizeof(AirpcapKey);
+
+/*
+ * Allocate the collection
+ */
+KeysCollection = (PAirpcapKeysCollection)malloc(KeysCollectionSize);
+if(!KeysCollection)
+{
+       /* Simple dialog ERROR */
+       simple_dialog(ESD_TYPE_ERROR,ESD_BTN_OK,"%s","Failed mamory allocation for KeysCollection!");
+       return;
+}
+
+/*
+ * Populate the key collection
+ */
+KeysCollection->nKeys = keys_in_list;
+
+for(i = 0; i < keys_in_list; i++)
+{
+    /* Retrieve the row infos */
+    gtk_clist_get_text(GTK_CLIST(key_ls),i,0,&row_type);  
+    gtk_clist_get_text(GTK_CLIST(key_ls),i,1,&row_key);
+    gtk_clist_get_text(GTK_CLIST(key_ls),i,2,&row_ssid); 
+    
+    if(g_strcasecmp(row_type,AIRPCAP_WEP_KEY_STRING) == 0)
+    KeysCollection->Keys[i].KeyType = AIRPCAP_KEYTYPE_WEP;
+    else if(g_strcasecmp(row_type,AIRPCAP_WPA_KEY_STRING) == 0)
+    KeysCollection->Keys[i].KeyType = AIRPCAP_KEYTYPE_TKIP;
+    else if(g_strcasecmp(row_type,AIRPCAP_WPA2_KEY_STRING) == 0)
+    KeysCollection->Keys[i].KeyType = AIRPCAP_KEYTYPE_CCMP;
+
+       /* Retrieve the Item corresponding to the i-th key */
+       new_key = g_string_new(row_key);
+       
+       KeysCollection->Keys[i].KeyLen = new_key->len / 2;
+       memset(&KeysCollection->Keys[i].KeyData, 0, sizeof(KeysCollection->Keys[i].KeyData));
+
+       for(j = 0 ; j < new_key->len; j += 2)
+       {
+               s[0] = new_key->str[j];
+               s[1] = new_key->str[j+1];
+               s[2] = '\0';
+               KeyByte = (UCHAR)strtol(s, NULL, 16);
+               KeysCollection->Keys[i].KeyData[j / 2] = KeyByte;
+       }
+}
+
+/*
+ * Free the old adapter key collection!
+ */
+if(airpcap_if_selected->keysCollection != NULL)
+       g_free(airpcap_if_selected->keysCollection);
+
+/*
+ * Set this collection ad the new one
+ */
+airpcap_if_selected->keysCollection = KeysCollection;
+airpcap_if_selected->keysCollectionSize = KeysCollectionSize;
+
+return;
+}
+
+/*
+ * This function will take the current keys (widget list), specified for the
+ * current adapter, and save them as default for ALL the others.
+ */
+void
+airpcap_read_and_save_decryption_keys_from_clist(GtkWidget* key_ls, airpcap_if_info_t* info_if, GList* if_list)
+{
+gint if_n = 0;
+gint i = 0;
+airpcap_if_info_t* curr_if = NULL;
+
+if( (if_list == NULL) || (info_if == NULL) ) return;
+
+if_n = g_list_length(if_list);
+
+/* For all the adapters in the list, save those keys as default */
+for(i = 0; i < if_n; i++)
+      {
+      curr_if = (airpcap_if_info_t*)g_list_nth_data(if_list,i);
+      
+      if(curr_if != NULL)
+          {
+          /* If the interface is not the active one, we need to free it's
+             key list and copy in the selected key list... */
+          airpcap_add_keys_from_list(key_ls,curr_if);
+              
+          /* Save to registry */
+          airpcap_save_selected_if_configuration(curr_if);
+          }
+      }      
+      
+/* Save the settings of the given interface as default for Wireshark...
+ * By the way, now all the adapters have the same keys, so it is not
+ * really necessary to use THIS specific one...
+ */
+save_wlan_wep_keys(info_if);                                          
+}
+
+/*
+ * This function will load from the preferences file ALL the
+ * keys (WEP, WPA and WPA2) and will set them as default for 
+ * each adapter. To do this, it will save the keys in the registry...
+ * A check will be performed, to make sure that keys found in
+ * registry and keys found in Wireshark preferences are the same. If not, 
+ * the user will be asked to choose if use all keys (merge them),
+ * or use Wireshark preferences ones. In the last case, registry keys will
+ * be overwritten for all the connected AirPcap adapters.
+ * In the first case, adapters will use their own keys, but those
+ * keys will not be accessible via Wireshark...
+ */
+gboolean
+airpcap_check_decryption_keys(GList* if_list)
+{
+gint if_n = 0;
+gint i = 0;
+gint n_adapters_keys = 0; 
+airpcap_if_info_t* curr_if = NULL;
+
+GList* wireshark_key_list;
+GList* curr_adapter_key_list;
+
+gboolean equals = TRUE;
+
+/* 
+ * If no AirPcap interface is found, return TRUE, so Wireshark
+ * will use HIS OWN keys.
+ */
+if(if_list == NULL) 
+    return TRUE;
+
+if_n = g_list_length(if_list);
+
+/* Get Wireshark preferences keys */
+wireshark_key_list = get_wireshark_keys();
+
+for(i = 0; i < if_n; i++)
+      {
+      curr_if = (airpcap_if_info_t*)g_list_nth_data(if_list,i);
+      curr_adapter_key_list = get_airpcap_device_keys(curr_if);
+      n_adapters_keys += g_list_length(curr_adapter_key_list);
+      equals &= key_lists_are_equal(wireshark_key_list,curr_adapter_key_list);
+      }
+
+if(n_adapters_keys == 0) /* No keys set in any of the AirPcap adapters... */
+    return TRUE; /* Use Wireshark keys and set them ad default for airpcap devices */
+
+return equals;
+}
+
+/*
+ * This function will load from the preferences file ALL the
+ * keys (WEP, WPA and WPA2) and will set them as default for 
+ * each adapter. To do this, it will save the keys in the registry...
+ * A check will be performed, to make sure that keys found in
+ * registry and keys found in Wireshark preferences are the same. If not, 
+ * the user will be asked to choose if use all keys (merge them),
+ * or use Wireshark preferences ones. In the last case, registry keys will
+ * be overwritten for all the connected AirPcap adapters.
+ * In the first case, adapters will use their own keys, but those
+ * keys will not be accessible via Wireshark...
+ */
+void
+airpcap_load_decryption_keys(GList* if_list)
+{
+gint if_n = 0;
+gint i = 0;
+airpcap_if_info_t* curr_if = NULL;
+
+if(if_list == NULL) return;
+
+if_n = g_list_length(if_list);
+
+for(i = 0; i < if_n; i++)
+      {
+      curr_if = (airpcap_if_info_t*)g_list_nth_data(if_list,i);
+      load_wlan_wep_keys(curr_if);
+      }
+}
+
+/*
+ * This function will set the gibven GList of decryption_key_t structures 
+ * as the defoult for both Wireshark and the AirPcap adapters...
+ */
+void
+airpcap_save_decryption_keys(GList* key_list, GList* adapters_list)
+{
+gint if_n = 0;
+gint key_n = 0;
+gint i = 0;
+airpcap_if_info_t* curr_if = NULL;
+
+if( (key_list == NULL) || (adapters_list == NULL)) return;
+
+if_n = g_list_length(adapters_list);
+key_n = g_list_length(key_list);
+
+for(i = 0; i < if_n; i++)
+      {
+      curr_if = (airpcap_if_info_t*)g_list_nth_data(adapters_list,i);
+      write_wlan_wep_keys_to_regitry(curr_if,key_list);
+      }
+
+/*
+ * This will set the keys of the current adapter as Wireshark default...
+ * Now all the adapters have the same keys, so curr_if is ok as any other...
+ */
+save_wlan_wep_keys(curr_if);
+}
+
 #endif /* HAVE_AIRPCAP */
index 0c3048f231d22d0026de27421d6f92871a409c35..2c2f2565402f82c5dba308033da2809a8e30e263 100755 (executable)
 #define AIRPCAP_LINK_TYPE_NAME_802_11_PLUS_RADIO       "802.11 + Radio"
 #define AIRPCAP_LINK_TYPE_NAME_UNKNOWN                                 "Unknown"
 
+#define AIRPCAP_DECRYPTION_TYPE_STRING_WIRESHARK "Wireshark"
+#define AIRPCAP_DECRYPTION_TYPE_STRING_AIRPCAP   "AirPcap"
+#define AIRPCAP_DECRYPTION_TYPE_STRING_NONE      "None"
+
+#define NO_ROW_SELECTED -1
+#define NO_COLUMN_SELECTED -1
+
+/*
+ * This structure is used because we need to store infos about the currently selected 
+ * row in the key list. 
+ */
+typedef struct{
+gint row;
+gint column;
+}airpcap_key_ls_selected_info_t;
+
+/*
+ * Used to retrieve a string containing a list of all the channels
+ * on which at least one adapter is capturing. This is true
+ * if the adapter passed as parameter is "Any" ... if not,
+ * this function returns the only channel number string.
+ */
+gchar*
+airpcap_get_all_channels_list(airpcap_if_info_t* if_info);
+
 /*
  * set up the airpcap toolbar for the new capture interface
  */
@@ -53,7 +78,13 @@ airpcap_set_toolbar_stop_capture(airpcap_if_info_t* if_info);
  * Add a key (string) to the given list
  */
 void
-airpcap_add_key_to_list(GtkWidget *keylist, gchar* s);
+airpcap_add_key_to_list(GtkWidget *keylist, gchar* type, gchar* key, gchar* ssid);
+
+/*
+ * Modify a key given a list and a row
+ */
+void
+airpcap_modify_key_in_list(GtkWidget *keylist, gint row, gchar* type, gchar* key, gchar* ssid);
 
 /*
  * Fill the list with the keys
@@ -133,10 +164,46 @@ airpcap_channel_combo_set_by_number(GtkWidget* w,UINT channel);
 int
 airpcap_if_is_any(airpcap_if_info_t* if_info);
 
+/*
+ * Takes the keys from the GtkList widget, and add them to the interface list
+ */
+void 
+airpcap_add_keys_from_list(GtkWidget *w, airpcap_if_info_t *if_info);
+
 /*
  * Update channel combo box. If the airpcap interface is "Any", the combo box will be disabled.
  */
 void
 airpcap_update_channel_combo(GtkWidget* w, airpcap_if_info_t* if_info);
 
+/*
+ * This function will take the current keys (widget list), specified for the
+ * current adapter, and save them as default for ALL the others.
+ */
+void
+airpcap_read_and_save_decryption_keys_from_clist(GtkWidget* key_ls, airpcap_if_info_t* info_if, GList* if_list);
+
+/*
+ * This function will load from the preferences file ALL the
+ * keys (WEP, WPA and WPA2) and will set them as default for 
+ * each adapter. To do this, it will save the keys in the registry...
+ */
+void
+airpcap_load_decryption_keys(GList* if_list);
+
+/*
+ * This function will load from the preferences file ALL the
+ * keys (WEP, WPA and WPA2) and will set them as default for 
+ * each adapter. To do this, it will save the keys in the registry...
+ */
+gboolean
+airpcap_check_decryption_keys(GList* if_list);
+
+/*
+ * This function will set the gibven GList of decryption_key_t structures 
+ * as the defoult for both Wireshark and the AirPcap adapters...
+ */
+void
+airpcap_save_decryption_keys(GList* key_list, GList* adapters_list);
+
 #endif
index 840b677b212d02aa118b3b490771615d3150b2bd..5a5ca4383378e87765af88a0bacb717c784330b2 100644 (file)
 #define AIRPCAP_TOOLBAR_INTERFACE_KEY  "airpcap_toolbar_if_key"
 #define AIRPCAP_TOOLBAR_LINK_TYPE_KEY  "airpcap_toolbar_lt_key" 
 #define AIRPCAP_TOOLBAR_CHANNEL_KEY            "airpcap_toolbar_ch_key"
-#define AIRPCAP_TOOLBAR_CRC_KEY                        "airpcap_toolbar_crc_key"
-#define AIRPCAP_TOOLBAR_WRONG_CRC_KEY  "airpcap_toolbar_wcrc_key"
+#define AIRPCAP_TOOLBAR_FCS_CHECK_KEY  "airpcap_toolbar_fcs_check_key"
+#define AIRPCAP_TOOLBAR_FCS_FILTER_KEY "airpcap_toolbar_fcs_filter_key"
 #define AIRPCAP_TOOLBAR_ADVANCED_KEY    "airpcap_toolbar_advanced_key"
+#define AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY    "airpcap_toolbar_key_management_key"
 #define AIRPCAP_TOOLBAR_DECRYPTION_KEY  "airpcap_toolbar_decryption_key"
 
 #define AIRPCAP_ADVANCED_KEY                           "airpcap_advanced_key"
 #define AIRPCAP_ADVANCED_INTERFACE_KEY         "airpcap_advanced_if_key"
 #define AIRPCAP_ADVANCED_LINK_TYPE_KEY         "airpcap_advanced_lt_key" 
 #define AIRPCAP_ADVANCED_CHANNEL_KEY           "airpcap_advanced_ch_key"
-#define AIRPCAP_ADVANCED_CRC_KEY                       "airpcap_advanced_crc_key"
-#define AIRPCAP_ADVANCED_WRONG_CRC_KEY         "airpcap_advanced_wcrc_key"
+#define AIRPCAP_ADVANCED_FCS_CHECK_KEY         "airpcap_advanced_fcs_check_key"
+#define AIRPCAP_ADVANCED_FCS_FILTER_KEY                "airpcap_advanced_fcs_filter_key"
 #define AIRPCAP_ADVANCED_BLINK_KEY                     "airpcap_advanced_blink_key"
-#define AIRPCAP_ADVANCED_CANCEL_KEY                    "airpcap_advanced_cancel_key"
-#define AIRPCAP_ADVANCED_OK_KEY                                "airpcap_advanced_ok_key"
-#define AIRPCAP_ADVANCED_KEYLIST_KEY           "airpcap_advanced_keylist_key"
 #define AIRPCAP_ADVANCED_ADD_KEY_TEXT_KEY      "airpcap_advanced_add_key_text_key"
 #define AIRPCAP_ADVANCED_ADD_KEY_OK_KEY                "airpcap_advanced_add_key_ok_key"
-#define AIRPCAP_ADVANCED_EDIT_KEY_TEXT_KEY     "airpcap_advanced_edit_key_text_key"
+#define AIRPCAP_ADVANCED_ADD_KEY_LIST_KEY      "airpcap_advanced_add_key_list_key"
+#define AIRPCAP_ADVANCED_ADD_KEY_TYPE_KEY      "airpcap_advanced_add_key_type_key"
+#define AIRPCAP_ADVANCED_ADD_KEY_KEY_KEY       "airpcap_advanced_add_key_key_key"
+#define AIRPCAP_ADVANCED_ADD_KEY_SSID_KEY      "airpcap_advanced_add_key_ssid_key"
+#define AIRPCAP_ADVANCED_EDIT_KEY_SELECTED_KEY "airpcap_advanced_edit_key_selected_key"
 #define AIRPCAP_ADVANCED_EDIT_KEY_OK_KEY       "airpcap_advanced_edit_key_ok_key"
-#define AIRPCAP_ADVANCED_EDIT_KEY_LABEL_KEY    "airpcap_advanced_edit_key_label_key"
+#define AIRPCAP_ADVANCED_EDIT_KEY_LIST_KEY     "airpcap_advanced_edit_key_list_key"
+#define AIRPCAP_ADVANCED_EDIT_KEY_TYPE_KEY     "airpcap_advanced_edit_key_type_key"
+#define AIRPCAP_ADVANCED_EDIT_KEY_KEY_KEY      "airpcap_advanced_edit_key_key_key"
+#define AIRPCAP_ADVANCED_EDIT_KEY_SSID_KEY     "airpcap_advanced_edit_key_ssid_key"
 #define AIRPCAP_ADVANCED_WEP_DECRYPTION_KEY    "airpcap_advanced_wep_decryption_key"
 #define AIRPCAP_ADVANCED_WPA_DECRYPTION_KEY    "airpcap_advanced_wpa_decryption_key"
 #define AIRPCAP_ADVANCED_NOTEBOOK_KEY          "airpcap_advanced_notebook_key"
+#define AIRPCAP_ADVANCED_CANCEL_KEY            "airpcap_advanced_cancel_key"
+#define AIRPCAP_ADVANCED_OK_KEY                        "airpcap_advanced_ok_key"
+#define AIRPCAP_ADVANCED_KEYLIST_KEY       "airpcap_advanced_keylist_key"
+#define AIRPCAP_CHECK_WINDOW_RADIO_KEEP_KEY "airpcap_check_window_radio_keep_key"
+#define AIRPCAP_CHECK_WINDOW_RADIO_MERGE_KEY "airpcap_check_window_radio_merge_key"
+#define AIRPCAP_CHECK_WINDOW_RADIO_IMPORT_KEY "airpcap_check_window_radio_import_key"
+#define AIRPCAP_CHECK_WINDOW_RADIO_IGNORE_KEY "airpcap_check_window_radio_ignore_key"
+#define AIRPCAP_CHECK_WINDOW_RADIO_GROUP_KEY "airpcap_check_window_radio_group_key"
+
+#define AIRPCAP_CHECK_WINDOW_KEY            "airpcap_check_window_key"
+
+#define AIRPCAP_ADVANCED_SELECTED_KEY_LIST_ITEM_KEY            "airpcap_advanced_selected_key_list_item_key"
 
 #define AIRPCAP_OPTIONS_ADVANCED_KEY    "airpcap_options_advanced_key"
 
-#define AIRPCAP_ADVANCED_FROM_KEY              "airpcap_advanced_name_key"
+#define AIRPCAP_ADVANCED_FROM_KEY              "airpcap_advanced_from_key"
 #endif
 
 #endif
index 92104c13f45cec0c7da98affd36583e903c3b9b6..d6f3aabfd5fcc0b99a494f8e4901490e469dc4d8 100644 (file)
@@ -198,7 +198,7 @@ GtkWidget *airpcap_tb;
 static GtkWidget       *info_bar;
 static GtkWidget    *packets_bar = NULL;
 static GtkWidget    *welcome_pane;
-static guint    main_ctx, file_ctx, help_ctx;
+static guint           main_ctx, file_ctx, help_ctx;
 static guint        packets_ctx;
 static gchar        *packets_str = NULL;
 GString *comp_info_str, *runtime_info_str;
@@ -3670,11 +3670,17 @@ if( !block_toolbar_signals && (airpcap_if_active != NULL))
 void
 airpcap_toolbar_encryption_cb(GtkWidget *entry, gpointer user_data)
 {
+/* We need to directly access the .ddl functions here... */
 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
 PAirpcapHandle ad;
 
-if( !block_toolbar_signals && (airpcap_if_active != NULL))
-{
+gint n = 0;
+gint i = 0;
+airpcap_if_info_t* curr_if = NULL;
+
+/* Apply changes to the current adapter */
+if( (airpcap_if_active != NULL))
+    {
        ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,airpcap_if_active->description), ebuf);
 
        if(ad)
@@ -3703,6 +3709,36 @@ if( !block_toolbar_signals && (airpcap_if_active != NULL))
                        }
                }
        }
+else
+    {
+       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No active AirPcap Adapter selected!");
+       return;
+    }
+
+n = g_list_length(airpcap_if_list);
+
+/* The same kind of settings should be propagated to all the adapters */
+/* Apply this change to all the adapters !!! */
+for(i = 0; i < n; i++)
+    {
+    curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
+
+    if( (curr_if != NULL) && (curr_if != airpcap_if_selected) )
+       {
+       ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,curr_if->description), ebuf);
+               if(ad)
+            {                                                                                     
+            curr_if->DecryptionOn = airpcap_if_selected->DecryptionOn;
+               airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
+               /* Save configuration for the curr_if */
+               if(!airpcap_if_store_cur_config_as_adapter_default(ad))
+                       {
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save 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.");
+                       }
+               airpcap_if_close(ad);
+            }
+        }
+    }
 }
 #endif
 
@@ -3723,6 +3759,23 @@ int *from_widget;
 }
 #endif
 
+#ifdef HAVE_AIRPCAP
+/*
+ * Callback for the Decryption Key Management button
+ */
+static void
+toolbar_display_airpcap_key_management_cb(GtkWidget *w, gpointer data)
+{
+int *from_widget;
+
+    from_widget = (gint*)g_malloc(sizeof(gint));
+    *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
+    OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
+
+       display_airpcap_key_management_cb(w,data);
+}
+#endif
+
 static void
 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
 {
@@ -3738,15 +3791,19 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
     gchar         *title;
 
 #ifdef HAVE_AIRPCAP
-    GtkWidget
-                 *advanced_bt,
-                 *interface_lb,
-                 *channel_lb,
-                 *channel_cm,
-                 *wrong_crc_lb,
-                 *encryption_ck,
-                 *wrong_crc_cm,
-                  *iconw;
+    GtkWidget *advanced_bt,
+                 *key_management_bt,
+                 *interface_lb,
+                 *channel_lb,
+                 *channel_cm,
+                 *wrong_crc_lb,
+                 *wrong_crc_cm;
+                  
+    GtkWidget *enable_decryption_lb;
+    GtkWidget *enable_decryption_cb;
+    GList     *enable_decryption_cb_items = NULL;
+    GtkWidget *enable_decryption_en;
+
     GList        *channel_list = NULL;
     GList        *linktype_list = NULL;
     GList        *link_list = NULL;
@@ -3927,11 +3984,11 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
 
        #if GTK_MAJOR_VERSION < 2
        gtk_widget_set_usize( GTK_WIDGET(channel_cm),
-                                  45,
+                                  90,
                                   28 );
        #else
        gtk_widget_set_size_request( GTK_WIDGET(channel_cm),
-                                  45,
+                                  90,
                                   28 );
     #endif
 
@@ -3958,10 +4015,16 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
        /* Wrong CRC combo */
        wrong_crc_cm = gtk_combo_new();
        gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(wrong_crc_cm)->entry),FALSE);
-       OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_WRONG_CRC_KEY,wrong_crc_cm);
+       OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_KEY,wrong_crc_cm);
        gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_cm,
         "", "Private");
 
+       #if GTK_MAJOR_VERSION >= 2
+    gtk_widget_set_size_request (wrong_crc_cm, 100, -1);
+    #else
+    gtk_widget_set_usize (wrong_crc_cm, 100, -1);
+    #endif
+
        linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_ALL);
        linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRECT);
     linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRUPT);
@@ -3981,37 +4044,40 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
 
        gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
 
-       /* encryption enabled box */
-
-       encryption_ck = gtk_toggle_button_new();
-       iconw = xpm_to_widget (wep_closed_24_xpm);
-    gtk_widget_show(iconw);
-    gtk_container_add(GTK_CONTAINER(encryption_ck),iconw);
-
-       #if GTK_MAJOR_VERSION < 2
-       gtk_widget_set_usize( GTK_WIDGET(encryption_ck),
-                                  28,
-                                  28 );
-       #else
-       gtk_widget_set_size_request( GTK_WIDGET(encryption_ck),
-                                  28,
-                                  28 );
+    /* Decryption mode combo box */
+    enable_decryption_lb = gtk_label_new ("Decryption Mode: ");
+    gtk_widget_set_name (enable_decryption_lb, "enable_decryption_lb");
+    gtk_widget_show (enable_decryption_lb);
+       gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_lb,
+    NULL, "Private");
+        
+    enable_decryption_cb = gtk_combo_new ();
+    gtk_widget_set_name (enable_decryption_cb, "enable_decryption_cb");
+    gtk_widget_show (enable_decryption_cb);
+    #if GTK_MAJOR_VERSION >= 2
+    gtk_widget_set_size_request (enable_decryption_cb, 83, -1);
+    #else
+    gtk_widget_set_usize (enable_decryption_cb, 83, -1);
     #endif
-
-       OBJECT_SET_DATA(GTK_TOOLBAR(airpcap_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY,encryption_ck);
-
-       if(airpcap_if_active != NULL)
-               {
-               if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON)
-               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(encryption_ck),TRUE);
-               else
-               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(encryption_ck),FALSE);
-               }
-
-       SIGNAL_CONNECT(encryption_ck,"toggled",airpcap_toolbar_encryption_cb,airpcap_tb);
-       gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), encryption_ck,
-        "Enable the WEP decryption in the wireless driver", "Private");
-       gtk_widget_show(encryption_ck);
+    enable_decryption_cb_items = g_list_append (enable_decryption_cb_items, AIRPCAP_DECRYPTION_TYPE_STRING_NONE);
+    enable_decryption_cb_items = g_list_append (enable_decryption_cb_items, AIRPCAP_DECRYPTION_TYPE_STRING_WIRESHARK);
+    enable_decryption_cb_items = g_list_append (enable_decryption_cb_items, AIRPCAP_DECRYPTION_TYPE_STRING_AIRPCAP);
+    gtk_combo_set_popdown_strings (GTK_COMBO (enable_decryption_cb), enable_decryption_cb_items);
+    g_list_free (enable_decryption_cb_items);
+    
+    enable_decryption_en = GTK_COMBO (enable_decryption_cb)->entry;
+    gtk_widget_set_name (enable_decryption_en, "enable_decryption_en");
+    gtk_widget_show (enable_decryption_en);
+    gtk_editable_set_editable (GTK_EDITABLE (enable_decryption_en), FALSE);
+    GTK_WIDGET_UNSET_FLAGS (enable_decryption_en, GTK_CAN_FOCUS);
+    
+       gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_cb,
+        "Choose a Decryption Mode", "Private");
+   
+    /* Set current decryption mode!!!! */
+    update_decryption_mode_cm(enable_decryption_cb);
+    SIGNAL_CONNECT (enable_decryption_en, "changed",on_enable_decryption_en_changed, airpcap_tb);
+    OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_KEY,enable_decryption_cb);
 
        gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
 
@@ -4024,6 +4090,15 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
         "Set Advanced Wireless Settings...", "Private");
        gtk_widget_show(advanced_bt);
 
+       /* Key Management button */
+       key_management_bt = gtk_button_new_with_label("Decryption Keys");
+       OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY,key_management_bt);
+
+       SIGNAL_CONNECT(key_management_bt, "clicked", toolbar_display_airpcap_key_management_cb, airpcap_tb);
+       gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), key_management_bt,
+        "Manage Decryption Keys...", "Private");
+       gtk_widget_show(key_management_bt);
+
        /* select the default interface */
        airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
 
@@ -4049,6 +4124,7 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
         airpcap_set_toolbar_stop_capture(airpcap_if_active);
                recent.airpcap_toolbar_show = TRUE;
         }
+        
 #endif
 
     /* filter toolbar */
@@ -4196,7 +4272,7 @@ show_main_window(gboolean doing_work)
 
   /*** we have finished all init things, show the main window ***/
   gtk_widget_show(top_level);
-
+  
   /* the window can be maximized only, if it's visible, so do it after show! */
   main_load_window_geometry(top_level);
 
@@ -4205,4 +4281,20 @@ show_main_window(gboolean doing_work)
 
   /* Pop up any queued-up alert boxes. */
   display_queued_messages();
+
+#ifdef HAVE_AIRPCAP  
+/* 
+ * This will read the decryption keys from the preferences file, and will store 
+ * them into the registry... 
+ */
+if(!airpcap_check_decryption_keys(airpcap_if_list))
+    {
+    /* Ask the user what to do ...*/
+    airpcap_keys_check_w(NULL,NULL);
+    }
+else /* Keys from lists are equals, or wireshark has got no keys */
+    {
+    airpcap_load_decryption_keys(airpcap_if_list);    
+    }
+#endif
 }
index 73e41160056a3ebd0931e46bf5cd40947a0cf973..969781afa32459e51426bb1c4af4ace57915a8f8 100644 (file)
 #endif /* _WIN32 */
 #endif /* HAVE_LIBPCAP */
 
+#ifdef HAVE_AIRPCAP
+#include "airpcap.h"
+#include "airpcap_loader.h"
+#include "airpcap_gui_utils.h"
+#endif
+
 static void     prefs_main_ok_cb(GtkWidget *, gpointer);
 static void     prefs_main_apply_cb(GtkWidget *, gpointer);
 static void     prefs_main_save_cb(GtkWidget *, gpointer);
@@ -1277,6 +1283,14 @@ prefs_main_write(void)
        g_free(pf_path);
     }
   }
+
+#ifdef HAVE_AIRPCAP
+/* 
+ * Load the Wireshark decryption keys (just set) and save 
+ * the changes to the adapters' registry 
+ */ 
+airpcap_load_decryption_keys(airpcap_if_list);
+#endif
 }