Big update with type fix and minor new function.

Complete the IEEE802.11 Station Association with interation of AC in LocalMAC mode.
After the IEEE802.11 Authorization / Association is complete, the AC can now
authorize the WTP to accept data station packets with Station Configuration Message.
This commit is contained in:
vemax78
2014-04-14 22:33:12 +02:00
parent 2ec98ac74d
commit 3569267283
37 changed files with 969 additions and 401 deletions

View File

@ -2,7 +2,7 @@
#include "ieee80211.h"
/* */
static int ieee80211_ie_set_ssid(char* buffer, const char* ssid, int hidessid) {
static int ieee80211_ie_set_ssid(uint8_t* buffer, const char* ssid, int hidessid) {
struct ieee80211_ie_ssid* iessid = (struct ieee80211_ie_ssid*)buffer;
ASSERT(buffer != NULL);
@ -24,7 +24,7 @@ static int ieee80211_ie_set_ssid(char* buffer, const char* ssid, int hidessid) {
}
/* */
static int ieee80211_ie_set_supportedrates(char* buffer, uint8_t* supportedrates, int supportedratescount) {
static int ieee80211_ie_set_supportedrates(uint8_t* buffer, uint8_t* supportedrates, int supportedratescount) {
int i;
int count;
struct ieee80211_ie_supported_rates* iesupportedrates = (struct ieee80211_ie_supported_rates*)buffer;
@ -51,7 +51,7 @@ static int ieee80211_ie_set_supportedrates(char* buffer, uint8_t* supportedrates
}
/* */
static int ieee80211_ie_set_extendedsupportedrates(char* buffer, uint8_t* supportedrates, int supportedratescount) {
static int ieee80211_ie_set_extendedsupportedrates(uint8_t* buffer, uint8_t* supportedrates, int supportedratescount) {
int i, j;
struct ieee80211_ie_extended_supported_rates* ieextendedsupportedrates = (struct ieee80211_ie_extended_supported_rates*)buffer;
@ -75,7 +75,7 @@ static int ieee80211_ie_set_extendedsupportedrates(char* buffer, uint8_t* suppor
}
/* */
static int ieee80211_ie_set_dsss(char* buffer, uint8_t channel) {
static int ieee80211_ie_set_dsss(uint8_t* buffer, uint8_t channel) {
struct ieee80211_ie_dsss* iedsss = (struct ieee80211_ie_dsss*)buffer;
ASSERT(buffer != NULL);
@ -88,7 +88,7 @@ static int ieee80211_ie_set_dsss(char* buffer, uint8_t channel) {
}
/* */
static int ieee80211_ie_set_erp(char* buffer, uint32_t mode, uint8_t erpinfo) {
static int ieee80211_ie_set_erp(uint8_t* buffer, uint32_t mode, uint8_t erpinfo) {
struct ieee80211_ie_erp* ieerp = (struct ieee80211_ie_erp*)buffer;
ASSERT(buffer != NULL);
@ -349,9 +349,9 @@ uint8_t ieee80211_get_erpinfo(uint32_t mode, int olbc, unsigned long stationnone
/* */
int ieee80211_create_beacon(char* buffer, int length, struct ieee80211_beacon_params* params) {
int ieee80211_create_beacon(uint8_t* buffer, int length, struct ieee80211_beacon_params* params) {
int result;
char* pos;
uint8_t* pos;
struct ieee80211_header_mgmt* header;
ASSERT(buffer != NULL);
@ -458,9 +458,9 @@ int ieee80211_create_beacon(char* buffer, int length, struct ieee80211_beacon_pa
}
/* */
int ieee80211_create_probe_response(char* buffer, int length, struct ieee80211_probe_response_params* params) {
int ieee80211_create_probe_response(uint8_t* buffer, int length, struct ieee80211_probe_response_params* params) {
int result;
char* pos;
uint8_t* pos;
int responselength;
struct ieee80211_header_mgmt* header;
@ -536,7 +536,7 @@ int ieee80211_create_probe_response(char* buffer, int length, struct ieee80211_p
}
/* */
int ieee80211_create_authentication_response(char* buffer, int length, struct ieee80211_authentication_params* params) {
int ieee80211_create_authentication_response(uint8_t* buffer, int length, struct ieee80211_authentication_params* params) {
int responselength;
struct ieee80211_header_mgmt* header;
@ -565,8 +565,8 @@ int ieee80211_create_authentication_response(char* buffer, int length, struct ie
}
/* */
int ieee80211_create_associationresponse_response(char* buffer, int length, struct ieee80211_associationresponse_params* params) {
char* pos;
int ieee80211_create_associationresponse_response(uint8_t* buffer, int length, struct ieee80211_associationresponse_params* params) {
uint8_t* pos;
int result;
int responselength;
struct ieee80211_header_mgmt* header;
@ -613,7 +613,7 @@ int ieee80211_create_associationresponse_response(char* buffer, int length, stru
}
/* */
int ieee80211_create_deauthentication(char* buffer, int length, struct ieee80211_deauthentication_params* params) {
int ieee80211_create_deauthentication(uint8_t* buffer, int length, struct ieee80211_deauthentication_params* params) {
struct ieee80211_header_mgmt* header;
ASSERT(buffer != NULL);

View File

@ -483,9 +483,9 @@ uint8_t ieee80211_get_erpinfo(uint32_t mode, int olbc, unsigned long stationnone
struct ieee80211_beacon_params {
unsigned long flags;
char* headbeacon;
uint8_t* headbeacon;
int headbeaconlength;
char* tailbeacon;
uint8_t* tailbeacon;
int tailbeaconlength;
uint8_t bssid[ETH_ALEN];
@ -504,11 +504,11 @@ struct ieee80211_beacon_params {
uint32_t mode;
uint8_t erpinfo;
char* proberesponseoffload;
uint8_t* proberesponseoffload;
int proberesponseoffloadlength;
};
int ieee80211_create_beacon(char* buffer, int length, struct ieee80211_beacon_params* params);
int ieee80211_create_beacon(uint8_t* buffer, int length, struct ieee80211_beacon_params* params);
/* Management Probe Response */
struct ieee80211_probe_response_params {
@ -529,7 +529,7 @@ struct ieee80211_probe_response_params {
uint8_t erpinfo;
};
int ieee80211_create_probe_response(char* buffer, int length, struct ieee80211_probe_response_params* params);
int ieee80211_create_probe_response(uint8_t* buffer, int length, struct ieee80211_probe_response_params* params);
/* Management Authentication */
struct ieee80211_authentication_params {
@ -541,7 +541,7 @@ struct ieee80211_authentication_params {
uint16_t statuscode;
};
int ieee80211_create_authentication_response(char* buffer, int length, struct ieee80211_authentication_params* params);
int ieee80211_create_authentication_response(uint8_t* buffer, int length, struct ieee80211_authentication_params* params);
/* Management Association Response */
struct ieee80211_associationresponse_params {
@ -556,7 +556,7 @@ struct ieee80211_associationresponse_params {
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
};
int ieee80211_create_associationresponse_response(char* buffer, int length, struct ieee80211_associationresponse_params* params);
int ieee80211_create_associationresponse_response(uint8_t* buffer, int length, struct ieee80211_associationresponse_params* params);
/* Management Deauthentication */
struct ieee80211_deauthentication_params {
@ -566,7 +566,7 @@ struct ieee80211_deauthentication_params {
uint16_t reasoncode;
};
int ieee80211_create_deauthentication(char* buffer, int length, struct ieee80211_deauthentication_params* params);
int ieee80211_create_deauthentication(uint8_t* buffer, int length, struct ieee80211_deauthentication_params* params);
/* Utils */
int ieee80211_retrieve_information_elements_position(struct ieee80211_ie_items* items, const uint8_t* data, int length);

View File

@ -481,6 +481,33 @@ void wifi_wlan_destroy(struct wifi_wlan* wlan) {
}
}
/* */
int wifi_station_add(struct wifi_wlan* wlan, struct station_add_params* params) {
ASSERT(wlan != NULL);
ASSERT(wlan->device != NULL);
ASSERT(params != NULL);
/* Check */
if (!wlan->device->instance->ops->station_add) {
return -1;
}
return wlan->device->instance->ops->station_add(wlan->handle, params);
}
/* */
int wifi_station_delete(struct wifi_device* device, struct station_delete_params* params) {
ASSERT(device != NULL);
ASSERT(params != NULL);
/* Check */
if (!device->instance->ops->station_delete) {
return -1;
}
return device->instance->ops->station_delete(device->handle, params);
}
/* */
uint32_t wifi_iface_index(const char* ifname) {
if (!ifname || !*ifname) {

View File

@ -116,7 +116,7 @@ struct wlan_startap_params {
/* */
struct wlan_send_frame_params {
char* packet;
uint8_t* packet;
int length;
uint32_t frequency;
@ -128,6 +128,16 @@ struct wlan_send_frame_params {
uint64_t cookie;
};
/* */
struct station_add_params {
uint8_t* address;
};
/* */
struct station_delete_params {
uint8_t* address;
};
/* Interface capability */
struct wifi_freq_capability {
unsigned long flags;
@ -241,6 +251,10 @@ struct wifi_driver_ops {
void (*wlan_stopap)(wifi_wlan_handle handle);
int (*wlan_getmacaddress)(wifi_wlan_handle handle, uint8_t* address);
void (*wlan_delete)(wifi_wlan_handle handle);
/* Stations functions */
int (*station_add)(wifi_wlan_handle handle, struct station_add_params* params);
int (*station_delete)(wifi_device_handle handle, struct station_delete_params* params);
};
/* */
@ -287,6 +301,10 @@ void wifi_wlan_stopap(struct wifi_wlan* wlan);
int wifi_wlan_getbssid(struct wifi_wlan* wlan, uint8_t* bssid);
void wifi_wlan_destroy(struct wifi_wlan* wlan);
/* */
int wifi_station_add(struct wifi_wlan* wlan, struct station_add_params* params);
int wifi_station_delete(struct wifi_device* device, struct station_delete_params* params);
/* Util functions */
uint32_t wifi_iface_index(const char* ifname);
int wifi_iface_hwaddr(int sock, const char* ifname, uint8_t* hwaddr);

View File

@ -15,7 +15,7 @@
#include "wifi_nl80211.h"
/* */
static char g_bufferIEEE80211[IEEE80211_MTU];
static uint8_t g_bufferIEEE80211[IEEE80211_MTU];
/* */
static void nl80211_station_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
@ -539,12 +539,10 @@ static int nl80211_wlan_new_station(struct nl80211_wlan_handle* wlanhandle, stru
if (result == -EEXIST) {
result = 0;
} else {
capwap_logging_error("Unable create station, error code: %d", result);
capwap_logging_error("Unable add station into wireless driver, error code: %d", result);
}
}
capwap_logging_info("Create station, error code: %d", result);
/* */
nlmsg_free(msg);
return result;
@ -614,6 +612,11 @@ static void nl80211_station_clean(struct nl80211_station* station) {
ASSERT(station != NULL);
if (station->wlanhandle) {
/* Delete station into wireless driver */
if (station->flags & NL80211_STATION_FLAGS_AUTHORIZED) {
nl80211_wlan_delete_station(station->wlanhandle, station->address);
}
if (station->aid) {
ieee80211_aid_free(station->wlanhandle->aidbitfield, station->aid);
station->aid = 0;
@ -889,13 +892,11 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla
int ielength;
struct ieee80211_ie_items ieitems;
int responselength;
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t responsestatuscode;
struct ieee80211_authentication_params ieee80211_params;
struct wlan_send_frame_params wlan_params;
struct nl80211_station* station;
char stationaddress[CAPWAP_MACADDRESS_EUI48_BUFFER];
uint16_t responsestatuscode;
/* Information Elements packet length */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
@ -911,7 +912,7 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla
}
/* */
capwap_printf_macaddress(stationaddress, (unsigned char*)mgmt->sa, MACADDRESS_EUI48_LENGTH);
capwap_printf_macaddress(stationaddress, mgmt->sa, MACADDRESS_EUI48_LENGTH);
/* Get ACL Station */
acl = wtp_radio_acl_station(mgmt->sa);
@ -932,27 +933,34 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla
/* Create station reference */
station = nl80211_station_create(wlanhandle, mgmt->sa);
if (station) {
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* Check authentication algorithm */
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM;
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlanhandle->authenticationtype == CAPWAP_ADD_WLAN_AUTHTYPE_OPEN)) {
if (transactionseqnumber == 1) {
responsestatuscode = IEEE80211_STATUS_SUCCESS;
station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN;
} else {
responsestatuscode = IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION;
}
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (wlanhandle->authenticationtype == CAPWAP_ADD_WLAN_AUTHTYPE_WEP)) {
/* TODO */
}
/* A station is removed if the association does not complete within a given period of time */
station->timeoutaction = NL80211_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
station->idtimeout = capwap_timeout_set(station->globalhandle->timeout, station->idtimeout, NL80211_STATION_TIMEOUT_ASSOCIATION_COMPLETE, nl80211_station_timeout, station, wlanhandle);
responsestatuscode = IEEE80211_STATUS_SUCCESS;
} else {
responsestatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
}
/* */
if (wlanhandle->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
if ((responsestatuscode != IEEE80211_STATUS_SUCCESS) || (wlanhandle->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
uint16_t algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
uint16_t transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* Check authentication algorithm */
if (responsestatuscode == IEEE80211_STATUS_SUCCESS) {
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM;
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlanhandle->authenticationtype == CAPWAP_ADD_WLAN_AUTHTYPE_OPEN)) {
if (transactionseqnumber == 1) {
responsestatuscode = IEEE80211_STATUS_SUCCESS;
station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN;
} else {
responsestatuscode = IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION;
}
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (wlanhandle->authenticationtype == CAPWAP_ADD_WLAN_AUTHTYPE_WEP)) {
/* TODO */
}
}
/* Create authentication packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
memcpy(ieee80211_params.bssid, wlanhandle->address, ETH_ALEN);
@ -970,33 +978,25 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla
wlan_params.frequency = wlanhandle->devicehandle->currentfrequency.frequency;
if (!nl80211_wlan_send_frame((wifi_wlan_handle)wlanhandle, &wlan_params)) {
capwap_logging_info("Sent IEEE802.11 Authentication Response to %s station with %d response status code", stationaddress, (int)responsestatuscode);
capwap_logging_info("Sent IEEE802.11 Authentication Response to %s station with %d status code", stationaddress, (int)responsestatuscode);
wlanhandle->last_cookie = wlan_params.cookie;
/* A station is removed if the association does not complete within a given period of time */
station->timeoutaction = NL80211_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
station->idtimeout = capwap_timeout_set(station->globalhandle->timeout, station->idtimeout, NL80211_STATION_TIMEOUT_ASSOCIATION_COMPLETE, nl80211_station_timeout, station, wlanhandle);
/* Notify authentication request message also to AC */
wlanhandle->send_mgmtframe(wlanhandle->send_mgmtframe_to_ac_cbparam, mgmt, mgmtlength);
/* Forwards the authentication response message also to AC */
wlanhandle->send_mgmtframe(wlanhandle->send_mgmtframe_to_ac_cbparam, (struct ieee80211_header_mgmt*)g_bufferIEEE80211, responselength);
} else {
} else if (station) {
capwap_logging_warning("Unable to send IEEE802.11 Authentication Response to %s station", stationaddress);
nl80211_station_delete(station);
}
} else {
} else if (station) {
capwap_logging_warning("Unable to create IEEE802.11 Authentication Response to %s station", stationaddress);
nl80211_station_delete(station);
}
} else if ((wlanhandle->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) && (responsestatuscode == IEEE80211_STATUS_SUCCESS)) {
} else if (wlanhandle->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
wlanhandle->send_mgmtframe(wlanhandle->send_mgmtframe_to_ac_cbparam, mgmt, mgmtlength);
/* A station is removed if the association does not complete within a given period of time */
station->timeoutaction = NL80211_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
station->idtimeout = capwap_timeout_set(station->globalhandle->timeout, station->idtimeout, NL80211_STATION_TIMEOUT_ASSOCIATION_COMPLETE, nl80211_station_timeout, station, wlanhandle);
}
}
@ -1129,7 +1129,7 @@ static void nl80211_do_mgmt_association_request_event(struct nl80211_wlan_handle
}
/* */
capwap_printf_macaddress(stationaddress, (unsigned char*)mgmt->sa, MACADDRESS_EUI48_LENGTH);
capwap_printf_macaddress(stationaddress, mgmt->sa, MACADDRESS_EUI48_LENGTH);
/* Get station reference */
station = nl80211_station_get(wlanhandle->devicehandle->globalhandle, wlanhandle, mgmt->sa);
@ -1207,12 +1207,11 @@ static void nl80211_do_mgmt_deauthentication_event(struct nl80211_wlan_handle* w
return;
}
/* */
nl80211_wlan_delete_station(wlanhandle, mgmt->sa);
/* Delete station */
station = nl80211_station_get(wlanhandle->devicehandle->globalhandle, wlanhandle, mgmt->sa);
if (station) {
if (!station) {
nl80211_wlan_delete_station(wlanhandle, mgmt->sa); /* Delete station into wireless driver */
} else {
nl80211_station_delete(station);
}
@ -1360,12 +1359,6 @@ static void nl80211_do_mgmt_frame_tx_status_association_response_event(struct nl
statuscode = __le16_to_cpu(mgmt->associationresponse.statuscode);
if (statuscode == IEEE80211_STATUS_SUCCESS) {
station->flags |= NL80211_STATION_FLAGS_ASSOCIATE;
/* TODO: remove when CAPWAP Add Station is ready */
capwap_timeout_deletetimer(station->globalhandle->timeout, station->idtimeout);
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
station->flags |= NL80211_STATION_FLAGS_AUTHORIZED;
nl80211_wlan_new_station(wlanhandle, station);
}
}
@ -2669,15 +2662,14 @@ static void nl80211_wlan_deauthentication_station(struct nl80211_wlan_handle* wl
ASSERT(wlanhandle != NULL);
ASSERT(stationaddress != NULL);
/* Blocks the station */
nl80211_wlan_delete_station(wlanhandle, stationaddress);
/* Send deauthentication message */
nl80211_wlan_send_deauthentication(wlanhandle, stationaddress, reasoncode);
/* Clean station */
station = nl80211_station_get(wlanhandle->devicehandle->globalhandle, wlanhandle, stationaddress);
if (station) {
if (!station) {
nl80211_wlan_delete_station(wlanhandle, stationaddress); /* Delete station into wireless driver */
} else {
if (reusestation) {
nl80211_station_clean(station);
} else {
@ -2686,6 +2678,66 @@ static void nl80211_wlan_deauthentication_station(struct nl80211_wlan_handle* wl
}
}
/* */
int nl80211_station_authorize(wifi_wlan_handle handle, struct station_add_params* params) {
struct nl80211_station* station;
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)handle;
ASSERT(handle != NULL);
ASSERT(params != NULL);
/* Get station */
station = nl80211_station_get(wlanhandle->devicehandle->globalhandle, wlanhandle, params->address);
if (!station) {
return -1;
} else if (!(station->flags & NL80211_STATION_FLAGS_AUTHENTICATED) || !(station->flags & NL80211_STATION_FLAGS_ASSOCIATE)) {
return -1;
} else if (station->flags & NL80211_STATION_FLAGS_AUTHORIZED) {
return 0;
}
/* */
capwap_logging_info("Authorize station: %s", capwap_printf_macaddress(buffer, params->address, MACADDRESS_EUI48_LENGTH));
/* */
capwap_timeout_deletetimer(station->globalhandle->timeout, station->idtimeout);
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
/* Station authorized */
station->flags |= NL80211_STATION_FLAGS_AUTHORIZED;
nl80211_wlan_new_station(wlanhandle, station);
return 0;
}
/* */
int nl80211_station_deauthorize(wifi_device_handle handle, struct station_delete_params* params) {
struct nl80211_station* station;
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
struct nl80211_device_handle* devicehandle = (struct nl80211_device_handle*)handle;
ASSERT(handle != NULL);
ASSERT(params != NULL);
/* Get station */
station = nl80211_station_get(devicehandle->globalhandle, NULL, params->address);
if (!station || !station->wlanhandle) {
return -1;
} else if (!(station->flags & NL80211_STATION_FLAGS_AUTHORIZED)) {
return 0;
}
/* */
capwap_logging_info("Deauthorize station: %s", capwap_printf_macaddress(buffer, params->address, MACADDRESS_EUI48_LENGTH));
/* Station deauthorized */
station->flags |= NL80211_STATION_FLAGS_AUTHORIZED;
nl80211_wlan_delete_station(station->wlanhandle, station->address);
return 0;
}
/* */
static void nl80211_global_deinit(wifi_global_handle handle) {
struct nl80211_global_handle* globalhandle = (struct nl80211_global_handle*)handle;
@ -2875,5 +2927,7 @@ const struct wifi_driver_ops wifi_driver_nl80211_ops = {
.wlan_startap = nl80211_wlan_startap,
.wlan_stopap = nl80211_wlan_stopap,
.wlan_getmacaddress = nl80211_wlan_getmacaddress,
.wlan_delete = nl80211_wlan_delete
.wlan_delete = nl80211_wlan_delete,
.station_add = nl80211_station_authorize,
.station_delete = nl80211_station_deauthorize
};