# HG changeset patch # User Joseph Jezak # Node ID a9f9efe67a39791e45daef9608e4248e3a523340 # Parent ccbe44dc5eef40ea3ad96afba9527c9f127b8667 Implemented open authentication. diff -r ccbe44dc5eef -r a9f9efe67a39 Makefile --- a/Makefile Mon Nov 28 16:36:12 2005 +++ b/Makefile Tue Nov 29 06:27:16 2005 @@ -28,6 +28,7 @@ obj-m := ieee80211softmac.o ieee80211softmac-objs := \ ieee80211softmac_io.o \ + ieee80211softmac_auth.o \ ieee80211softmac_module.o \ ieee80211softmac_scan.o \ ieee80211softmac_wx.o diff -r ccbe44dc5eef -r a9f9efe67a39 ieee80211softmac_auth.c --- a/ieee80211softmac_auth.c Mon Nov 28 16:36:12 2005 +++ b/ieee80211softmac_auth.c Tue Nov 29 06:27:16 2005 @@ -1,76 +1,149 @@ #include "ieee80211softmac_priv.h" +static void ieee80211softmac_auth_queue(void *data); -/* Sends an auth request to the desired AP */ -int ieee80211softmac_auth_req( ) +/* Queues an auth request to the desired AP */ +int +ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, + struct ieee80211_network *net) { - int ret; - /* Send the auth packet */ - if(ret = ieee80211softmac_send_mgt_frame(IEEE80211_STYPE_AUTH)) - return ret; + struct ieee80211softmac_auth_queue_item *auth; + unsigned long flags; + int empty; - /* Set the state to Authenticating (LOCK?) */ - sm->ieee->state = IEEE80211_AUTHENTICATING; + dprintk(PFX "Queueing Authorization Request to %X:%X:%X:%X:%X:%X\n", + net->bssid[0], net->bssid[1], net->bssid[2], + net->bssid[3], net->bssid[4], net->bssid[5]); + /* Queue the auth request */ + auth = (struct ieee80211softmac_auth_queue_item *) + kmalloc(sizeof(struct ieee80211softmac_auth_queue_item), GFP_KERNEL); + if(auth == NULL) + return -ENOMEM; - /* Workqueue for timeout */ - queue_delayed_work( ); + auth->net = net; + auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT; + auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST; + + /* See if list is empty */ + empty = list_empty(&mac->auth_queue); + + /* Lock and add it */ + spin_lock_irqsave(&mac->lock, flags); + list_add_tail(&mac->auth_queue, &auth->list); + /* Init work if there isn't a workqueue already started */ + if(empty) + { + INIT_WORK(auth->work, &ieee80211softmac_auth_queue, (void *)mac); + queue_work(mac->workqueue, auth->work); + } + spin_unlock_irqrestore(&mac->lock, flags); + + return 0; } -/* - * Retry if we haven't gotten a response from the AP (?) - * Workqueue task for auth timeout - */ -void ieee80211softmac_auth_retry( ) + +/* Sends an auth request to the desired AP and handles timeouts */ +static void +ieee80211softmac_auth_queue(void *data) { - int ret; - /* Test the retry counter to see if we need to do an AUTH again */ - - /* Decrement the retry counter (?) */ - /* Send the auth packet */ - if(ret = ieee80211softmac_auth_req( )) - - /* Add a new workqueue */ + struct ieee80211softmac_device *mac; + struct ieee80211softmac_auth_queue_item *auth; + mac = (struct ieee80211softmac_device *)data; + auth = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); + if(auth->retry > 0) { + dprintk(PFX "Sending Authorization Request to %X:%X:%X:%X:%X:%X\n", + auth->net->bssid[0], auth->net->bssid[1], auth->net->bssid[2], + auth->net->bssid[3], auth->net->bssid[4], auth->net->bssid[5]); + if(!ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state)) + { + /* Queue the next timeout (Since it's so long, should we move it to the back?) */ + queue_delayed_work(mac->workqueue, auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT); + auth->retry--; + } + } + /* Remove this item from the queue */ + list_del(mac->auth_queue.next); + /* Free it */ + kfree(auth); + /* Restart the workqueue if there is a next item */ + if(!list_empty(&mac->auth_queue)){ + auth = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); + queue_work(mac->workqueue, auth->work); + } } /* Handle the auth response from the AP * This should be registered with ieee80211 as handle_auth */ -int ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) +int +ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) { - struct ieee80211softmac_device *sm = ieee80211_priv(dev); - if(auth->algorithm == WLAN_AUTH_OPEN) { + struct ieee80211softmac_device *mac = ieee80211_priv(dev); + struct ieee80211softmac_auth_queue_item *aq = + list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); + switch(auth->algorithm) { + case WLAN_AUTH_OPEN: /* Check the status code of the response */ - if (auth->staus == WLAN_STATUS_SUCCESS) { + switch(auth->status) { + case WLAN_STATUS_SUCCESS: /* Update the status to Authenticated (LOCK?) */ - sm->ieee->state = IEEE80211_AUTHENTICATED; - - /* Cancel the timeout if required */ - cancel_delayed_work( ); - - /* FIXME Do we fire off an associate req now? */ + aq->net->flags |= IEEE80211_AUTHENTICATED; + break; + default: + /* ERROR */ + /* FIXME deal with not authenticated reasons */ + break; } - /* FIXME deal with not authenticated reasons */ + goto free_aq; + break; + case WLAN_AUTH_SHARED_KEY: + /* FIXME TODO */ + goto free_aq; + break; + default: + /* ERROR */ + goto free_aq; + break; } + return 0; +free_aq: + /* Cancel the timeout */ + cancel_delayed_work(aq->work); + /* Remove this item from the queue */ + list_del(mac->auth_queue.next); + /* Free it */ + kfree(aq); + /* Restart the workqueue if there is a next item */ + if(!list_empty(&mac->auth_queue)){ + aq = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); + queue_work(mac->workqueue, aq->work); + } + return 0; } /* * Sends a deauth request to the desired AP */ -int ieee80211softmac_deauth_req(int reason) { +int +ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac, + struct ieee80211_network *net, int reason) +{ int ret; /* Send the de-auth packet */ - if(ret = ieee80211softmac_send_mgt_frame(IEEE80211_STYPE_DEAUTH)) + if((ret = ieee80211softmac_send_mgt_frame(mac, net, IEEE80211_STYPE_DEAUTH, reason))) return ret; /* Put the softmac into which state(?) */ + return 0; } /* * This should be registered with ieee80211 as handle_deauth */ -int ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_auth *auth){ +int +ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_auth *auth) { - /* Update the state (?) */ + return 0; } diff -r ccbe44dc5eef -r a9f9efe67a39 ieee80211softmac_module.c --- a/ieee80211softmac_module.c Mon Nov 28 16:36:12 2005 +++ b/ieee80211softmac_module.c Tue Nov 29 06:27:16 2005 @@ -18,6 +18,8 @@ softmac->workqueue = create_workqueue("ieee80211softmac_%s"); if (!softmac->workqueue) goto err_free_ieee80211; + + INIT_LIST_HEAD(&softmac->auth_queue); INIT_WORK(&softmac->scaninfo.softmac_scan, ieee80211softmac_scan, softmac); softmac->start_scan = ieee80211softmac_start_scan; diff -r ccbe44dc5eef -r a9f9efe67a39 ieee80211softmac_priv.h --- a/ieee80211softmac_priv.h Mon Nov 28 16:36:12 2005 +++ b/ieee80211softmac_priv.h Tue Nov 29 06:27:16 2005 @@ -50,9 +50,13 @@ /* private definitions and prototypes */ +#define IEEE80211SOFTMAC_AUTH_REQ_TIMEOUT + #define IEEE80211SOFTMAC_PROBE_DELAY 5 #define IEEE80211SOFTMAC_WORKQUEUE_NAME_LEN (17 + IFNAMSIZ) void ieee80211softmac_scan(void *sm); +int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac, + struct ieee80211_network *net, u32 type, u32 arg); #endif /* IEEE80211SOFTMAC_PRIV_H_ */ diff -r ccbe44dc5eef -r a9f9efe67a39 net/ieee80211softmac.h --- a/net/ieee80211softmac.h Mon Nov 28 16:36:12 2005 +++ b/net/ieee80211softmac.h Tue Nov 29 06:27:16 2005 @@ -4,6 +4,7 @@ #include #include #include +#include #include /* Once the API is considered more or less stable, @@ -21,6 +22,31 @@ struct completion finished; struct work_struct softmac_scan; }; + +struct ieee80211softmac_auth_queue_item { + struct list_head list; /* List head */ + struct ieee80211_network *net; /* Network to auth */ + u8 retry; /* Retry limit */ + u8 state; /* Auth State */ + struct work_struct *work; /* Work queue */ +}; + +enum { + IEEE80211SOFTMAC_AUTH_OPEN_REQUEST = 1, + IEEE80211SOFTMAC_AUTH_OPEN_RESPONSE = 2, +}; + +enum { + IEEE80211SOFTMAC_AUTH_SHARED_REQUEST = 1, + IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE = 2, + IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE = 3, + IEEE80211SOFTMAC_AUTH_SHARED_PASS = 4, +}; + +/* We should make these tunable + * AUTH_TIMEOUT seems really long, but that's what it is in BSD */ +#define IEEE80211SOFTMAC_AUTH_TIMEOUT (12 * HZ) +#define IEEE80211SOFTMAC_AUTH_RETRY_LIMIT 5 struct ieee80211softmac_device { /* 802.11 structure for data stuff */ @@ -72,11 +98,19 @@ struct ieee80211softmac_scaninfo scaninfo; + struct list_head auth_queue; /* This must be the last item so that it points to the data * allocated beyond this structure by alloc_ieee80211 */ u8 priv[0]; }; + +/* NOTE: + * These apply to the ieee80211_network->flags field + * If additional flags are added to ieee80211, we'll have a problem + */ +#define NETWORK_IS_AUTHORIZING (1<<6) +#define NETWORK_IS_AUTHORIZED (1<<7) extern void ieee80211softmac_start_scan(struct net_device *dev); extern void ieee80211softmac_stop_scan(struct net_device *dev); # HG changeset patch # User Joseph Jezak # Node ID d3f95c7f93e085558249cf68c6fe698c1a20bfc9 # Parent a9f9efe67a39791e45daef9608e4248e3a523340 Fixed some locking. diff -r a9f9efe67a39 -r d3f95c7f93e0 ieee80211softmac_auth.c --- a/ieee80211softmac_auth.c Tue Nov 29 06:27:16 2005 +++ b/ieee80211softmac_auth.c Tue Nov 29 06:31:08 2005 @@ -48,6 +48,7 @@ { struct ieee80211softmac_device *mac; struct ieee80211softmac_auth_queue_item *auth; + unsigned long flags; mac = (struct ieee80211softmac_device *)data; auth = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); @@ -58,11 +59,14 @@ if(!ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state)) { /* Queue the next timeout (Since it's so long, should we move it to the back?) */ + spin_lock_irqsave(&mac->lock, flags); queue_delayed_work(mac->workqueue, auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT); auth->retry--; + spin_unlock_irqrestore(&mac->lock, flags); } } /* Remove this item from the queue */ + spin_lock_irqsave(&mac->lock, flags); list_del(mac->auth_queue.next); /* Free it */ kfree(auth); @@ -71,6 +75,7 @@ auth = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); queue_work(mac->workqueue, auth->work); } + spin_unlock_irqrestore(&mac->lock, flags); } /* Handle the auth response from the AP @@ -79,6 +84,7 @@ int ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) { + unsigned long flags; struct ieee80211softmac_device *mac = ieee80211_priv(dev); struct ieee80211softmac_auth_queue_item *aq = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); @@ -109,6 +115,7 @@ return 0; free_aq: /* Cancel the timeout */ + spin_lock_irqsave(&mac->lock, flags); cancel_delayed_work(aq->work); /* Remove this item from the queue */ list_del(mac->auth_queue.next); @@ -119,6 +126,7 @@ aq = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); queue_work(mac->workqueue, aq->work); } + spin_unlock_irqrestore(&mac->lock, flags); return 0; } # HG changeset patch # User Joseph Jezak # Node ID 819dd45bef5b89f0107c4eced427ab949e0bd17d # Parent d3f95c7f93e085558249cf68c6fe698c1a20bfc9 Fixed workqueues. diff -r d3f95c7f93e0 -r 819dd45bef5b ieee80211softmac_auth.c --- a/ieee80211softmac_auth.c Tue Nov 29 06:31:08 2005 +++ b/ieee80211softmac_auth.c Tue Nov 29 06:37:46 2005 @@ -73,6 +73,7 @@ /* Restart the workqueue if there is a next item */ if(!list_empty(&mac->auth_queue)){ auth = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); + INIT_WORK(auth->work, &ieee80211softmac_auth_queue, (void *)mac); queue_work(mac->workqueue, auth->work); } spin_unlock_irqrestore(&mac->lock, flags); @@ -124,6 +125,7 @@ /* Restart the workqueue if there is a next item */ if(!list_empty(&mac->auth_queue)){ aq = list_entry(mac->auth_queue.next, struct ieee80211softmac_auth_queue_item, list); + INIT_WORK(aq->work, &ieee80211softmac_auth_queue, (void *)mac); queue_work(mac->workqueue, aq->work); } spin_unlock_irqrestore(&mac->lock, flags);