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:
parent
2ec98ac74d
commit
3569267283
@ -112,7 +112,7 @@ static void ac_json_80211_wtpradioconf_createjson(struct json_object* jsonparent
|
||||
json_object_object_add(jsonitem, "ShortPreamble", json_object_new_int((int)wtpradioconf->shortpreamble));
|
||||
json_object_object_add(jsonitem, "NumBSSIDs", json_object_new_int((int)wtpradioconf->maxbssid));
|
||||
json_object_object_add(jsonitem, "DTIMPeriod", json_object_new_int((int)wtpradioconf->dtimperiod));
|
||||
json_object_object_add(jsonitem, "BSSID", json_object_new_string(capwap_printf_macaddress(buffer, (unsigned char*)wtpradioconf->bssid, MACADDRESS_EUI48_LENGTH)));
|
||||
json_object_object_add(jsonitem, "BSSID", json_object_new_string(capwap_printf_macaddress(buffer, wtpradioconf->bssid, MACADDRESS_EUI48_LENGTH)));
|
||||
json_object_object_add(jsonitem, "BeaconPeriod", json_object_new_int((int)wtpradioconf->beaconperiod));
|
||||
json_object_object_add(jsonitem, "CountryString", json_object_new_string((char*)wtpradioconf->country));
|
||||
json_object_object_add(jsonparent, "IEEE80211WTPRadioConfiguration", jsonitem);
|
||||
|
@ -10,38 +10,6 @@
|
||||
#define SOAP_EVENT_STATUS_RUNNING 0
|
||||
#define SOAP_EVENT_STATUS_COMPLETE 1
|
||||
|
||||
/* Reset notification */
|
||||
struct ac_notify_reset_t {
|
||||
uint32_t vendor;
|
||||
uint8_t name[0];
|
||||
};
|
||||
|
||||
/* Add WLAN notification */
|
||||
struct ac_notify_addwlan_t {
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
uint16_t capability;
|
||||
uint8_t qos;
|
||||
uint8_t authmode;
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
uint8_t suppressssid;
|
||||
char ssid[CAPWAP_ADD_WLAN_SSID_LENGTH + 1];
|
||||
};
|
||||
|
||||
/* Station Configuration IEEE802.11 add station notification */
|
||||
struct ac_notify_station_configuration_ieee8011_add_station {
|
||||
uint8_t radioid;
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t vlan[CAPWAP_ADDSTATION_VLAN_MAX_LENGTH];
|
||||
|
||||
uint8_t wlanid;
|
||||
uint16_t associationid;
|
||||
uint16_t capabilities;
|
||||
uint8_t supportedratescount;
|
||||
uint8_t supportedrates[CAPWAP_STATION_RATES_MAXLENGTH];
|
||||
};
|
||||
|
||||
/* */
|
||||
int ac_backend_start(void);
|
||||
void ac_backend_stop(void);
|
||||
|
@ -65,24 +65,16 @@ static int receive_echo_request(struct ac_session_t* session, struct capwap_pars
|
||||
|
||||
/* */
|
||||
static void execute_ieee80211_wlan_configuration_addwlan(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct capwap_80211_addwlan_element* addwlan, struct capwap_parsed_packet* requestpacket) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_80211_assignbssid_element* assignbssid;
|
||||
|
||||
/* Get BSSID */
|
||||
assignbssid = (struct capwap_80211_assignbssid_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_ASSIGN_BSSID);
|
||||
if (assignbssid && (assignbssid->radioid == addwlan->radioid) && (assignbssid->wlanid == addwlan->wlanid)) {
|
||||
if (!ac_wlans_get_bssid(session, assignbssid->radioid, assignbssid->bssid)) {
|
||||
wlan = ac_wlans_create_bssid(session, assignbssid->radioid, assignbssid->wlanid, assignbssid->bssid);
|
||||
wlan->session = session;
|
||||
wlan->sessiondata = session->sessiondata;
|
||||
wlan = ac_wlans_create_bssid(assignbssid->radioid, assignbssid->wlanid, assignbssid->bssid, addwlan);
|
||||
|
||||
/* Set capability */
|
||||
ac_wlans_set_bssid_capability(wlan, addwlan);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)assignbssid->radioid, (int)assignbssid->wlanid, capwap_printf_macaddress(buffer, assignbssid->bssid, MACADDRESS_EUI48_LENGTH));
|
||||
}
|
||||
/* Assign BSSID to session */
|
||||
ac_session_data_send_action(session->sessiondata, AC_SESSION_DATA_ACTION_ASSIGN_BSSID, 0, &wlan, sizeof(struct ac_wlan*));
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,6 +130,64 @@ static void receive_ieee80211_wlan_configuration_response(struct ac_session_t* s
|
||||
ac_free_reference_last_request(session);
|
||||
}
|
||||
|
||||
/* */
|
||||
static void execute_ieee80211_wlan_configuration_response_addstation(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct capwap_addstation_element* addstation, struct capwap_parsed_packet* requestpacket) {
|
||||
struct ac_notify_add_station_status notify;
|
||||
struct capwap_80211_station_element* station80211;
|
||||
unsigned short binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
struct capwap_resultcode_element* resultcode;
|
||||
|
||||
/* */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
|
||||
/* */
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
station80211 = (struct capwap_80211_station_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_STATION);
|
||||
if (station80211) {
|
||||
memset(¬ify, 0, sizeof(struct ac_notify_add_station_status));
|
||||
|
||||
notify.radioid = station80211->radioid;
|
||||
notify.wlanid = station80211->wlanid;
|
||||
memcpy(notify.address, addstation->address, MACADDRESS_EUI48_LENGTH);
|
||||
notify.statuscode = resultcode->code;
|
||||
|
||||
ac_session_data_send_action(session->sessiondata, AC_SESSION_DATA_ACTION_ADD_STATION_STATUS, 0, (void*)¬ify, sizeof(struct ac_notify_add_station_status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void execute_ieee80211_wlan_configuration_response_deletestation(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct capwap_deletestation_element* deletestation, struct capwap_parsed_packet* requestpacket) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void receive_ieee80211_station_configuration_response(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
struct capwap_packet_rxmng* rxmngrequestpacket;
|
||||
struct capwap_parsed_packet requestpacket;
|
||||
struct capwap_addstation_element* addstation;
|
||||
struct capwap_deletestation_element* deletestation;
|
||||
|
||||
/* Parsing request message */
|
||||
rxmngrequestpacket = capwap_packet_rxmng_create_from_requestfragmentpacket(session->requestfragmentpacket);
|
||||
if (capwap_parsing_packet(rxmngrequestpacket, NULL, &requestpacket) == PARSING_COMPLETE) {
|
||||
addstation = (struct capwap_addstation_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_ADDSTATION);
|
||||
if (addstation) {
|
||||
execute_ieee80211_wlan_configuration_response_addstation(session, packet, addstation, &requestpacket);
|
||||
} else {
|
||||
deletestation = (struct capwap_deletestation_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_DELETESTATION);
|
||||
if (deletestation) {
|
||||
execute_ieee80211_wlan_configuration_response_deletestation(session, packet, deletestation, &requestpacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_free_parsed_packet(&requestpacket);
|
||||
capwap_packet_rxmng_free(rxmngrequestpacket);
|
||||
ac_free_reference_last_request(session);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_dfa_state_run(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
ASSERT(session != NULL);
|
||||
@ -198,9 +248,7 @@ void ac_dfa_state_run(struct ac_session_t* session, struct capwap_parsed_packet*
|
||||
}
|
||||
|
||||
case CAPWAP_STATION_CONFIGURATION_RESPONSE: {
|
||||
/* TODO */
|
||||
|
||||
/* */
|
||||
receive_ieee80211_station_configuration_response(session, packet);
|
||||
capwap_timeout_set(session->timeout, session->idtimercontrol, AC_MAX_ECHO_INTERVAL, ac_dfa_teardown_timeout, session, NULL);
|
||||
break;
|
||||
}
|
||||
|
@ -536,9 +536,6 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
|
||||
session->count = 2;
|
||||
capwap_event_init(&session->changereference);
|
||||
|
||||
/* */
|
||||
ac_wlans_init(session);
|
||||
|
||||
/* */
|
||||
session->timeout = capwap_timeout_init();
|
||||
session->idtimercontrol = capwap_timeout_createtimer(session->timeout);
|
||||
@ -621,6 +618,9 @@ static struct ac_session_data_t* ac_create_session_data(struct sockaddr_storage*
|
||||
sessiondata->count = 2;
|
||||
capwap_event_init(&sessiondata->changereference);
|
||||
|
||||
/* */
|
||||
ac_wlans_init(sessiondata);
|
||||
|
||||
/* */
|
||||
sessiondata->timeout = capwap_timeout_init();
|
||||
sessiondata->idtimercontrol = capwap_timeout_createtimer(sessiondata->timeout);
|
||||
|
@ -26,6 +26,7 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_data_t* se
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
|
||||
@ -33,9 +34,13 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_data_t* se
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create station if sent by station */
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_create_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa);
|
||||
/* */
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_create_station(sessiondata, radioid, mgmt->bssid, mgmt->sa);
|
||||
|
||||
/* */
|
||||
capwap_printf_macaddress(buffer, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_logging_info("Receive IEEE802.11 Authentication Request from %s station", buffer);
|
||||
|
||||
/* */
|
||||
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
@ -43,13 +48,30 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_data_t* se
|
||||
} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
/* TODO */
|
||||
}
|
||||
} else {
|
||||
station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station) {
|
||||
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
/* TODO */
|
||||
} else if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(sessiondata, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
|
||||
uint16_t algorithm;
|
||||
uint16_t transactionseqnumber;
|
||||
uint16_t statuscode;
|
||||
|
||||
/* */
|
||||
statuscode = __le16_to_cpu(mgmt->authetication.statuscode);
|
||||
|
||||
/* */
|
||||
capwap_printf_macaddress(buffer, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_logging_info("Receive IEEE802.11 Authentication Response to %s station with %d status code", buffer, (int)statuscode);
|
||||
|
||||
if (statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
|
||||
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
|
||||
|
||||
/* Check if authenticate */
|
||||
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
|
||||
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
|
||||
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,6 +82,7 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_data_
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest));
|
||||
@ -68,22 +91,34 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_data_
|
||||
}
|
||||
|
||||
/* Get station */
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa);
|
||||
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(sessiondata, radioid, mgmt->bssid, mgmt->sa);
|
||||
|
||||
/* */
|
||||
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
/* TODO */
|
||||
}
|
||||
} else {
|
||||
station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station) {
|
||||
capwap_printf_macaddress(buffer, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_logging_info("Receive IEEE802.11 Association Request from %s station", buffer);
|
||||
|
||||
/* Get Station Info */
|
||||
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
|
||||
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
|
||||
|
||||
/* Get supported rates */
|
||||
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* */
|
||||
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
/* TODO */
|
||||
|
||||
/* Active Station */
|
||||
ac_stations_authorize_station(sessiondata, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,6 +129,7 @@ static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_data
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ac_station* station;
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse));
|
||||
@ -102,13 +138,32 @@ static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_data
|
||||
}
|
||||
|
||||
/* Get station */
|
||||
station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa);
|
||||
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(sessiondata, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
|
||||
capwap_printf_macaddress(buffer, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_logging_info("Receive IEEE802.11 Association Response to %s station with %d status code", buffer, (int)mgmt->associationresponse.statuscode);
|
||||
|
||||
/* */
|
||||
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
|
||||
/* TODO */
|
||||
} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
|
||||
/* TODO */
|
||||
if (mgmt->associationresponse.statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
/* Get Station Info */
|
||||
station->capability = __le16_to_cpu(mgmt->associationresponse.capability);
|
||||
station->aid = __le16_to_cpu(mgmt->associationresponse.aid);
|
||||
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
|
||||
|
||||
/* Get supported rates */
|
||||
if (ieitems.supported_rates && ((ieitems.supported_rates->len + (ieitems.extended_supported_rates ? ieitems.extended_supported_rates->len : 0)) <= sizeof(station->supportedrates))) {
|
||||
station->supportedratescount = ieitems.supported_rates->len;
|
||||
memcpy(station->supportedrates, ieitems.supported_rates->rates, ieitems.supported_rates->len);
|
||||
if (ieitems.extended_supported_rates) {
|
||||
station->supportedratescount += ieitems.extended_supported_rates->len;
|
||||
memcpy(&station->supportedrates[ieitems.supported_rates->len], ieitems.extended_supported_rates->rates, ieitems.extended_supported_rates->len);
|
||||
}
|
||||
|
||||
/* Active Station */
|
||||
ac_stations_authorize_station(sessiondata, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +213,7 @@ static void ac_ieee80211_mgmt_disassociation_packet(struct ac_session_data_t* se
|
||||
static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
const uint8_t* stationaddress;
|
||||
struct ac_station* station;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
@ -170,7 +226,11 @@ static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_data_t*
|
||||
stationaddress = (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) ? mgmt->sa : mgmt->da);
|
||||
|
||||
/* Delete station */
|
||||
ac_stations_delete_station(sessiondata->session, stationaddress);
|
||||
station = ac_stations_get_station(sessiondata, radioid, NULL, stationaddress);
|
||||
if (station) {
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHORIZED | AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
|
||||
ac_stations_delete_station(sessiondata, station);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "capwap_dfa.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_backend.h"
|
||||
#include "ac_wlans.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define AC_ERROR_TIMEOUT -1000
|
||||
@ -44,7 +43,7 @@ static int ac_session_action_resetwtp(struct ac_session_t* session, struct ac_no
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_STATE);
|
||||
capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send reset request packet");
|
||||
capwap_logging_debug("Warning: error to send Reset Request packet");
|
||||
ac_free_reference_last_request(session);
|
||||
ac_session_teardown(session);
|
||||
}
|
||||
@ -63,8 +62,10 @@ static int ac_session_action_addwlan(struct ac_session_t* session, struct ac_not
|
||||
/* Check if WLAN id is valid and not used */
|
||||
if (!IS_VALID_RADIOID(notify->radioid) || !IS_VALID_WLANID(notify->wlanid)) {
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
#if 0
|
||||
} else if (ac_wlans_get_bssid_with_wlanid(session, notify->radioid, notify->wlanid)) {
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -104,7 +105,7 @@ static int ac_session_action_addwlan(struct ac_session_t* session, struct ac_not
|
||||
session->retransmitcount = 0;
|
||||
capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send reset request packet");
|
||||
capwap_logging_debug("Warning: error to send WLAN Configuration Request packet");
|
||||
ac_free_reference_last_request(session);
|
||||
ac_session_teardown(session);
|
||||
}
|
||||
@ -114,8 +115,115 @@ static int ac_session_action_addwlan(struct ac_session_t* session, struct ac_not
|
||||
|
||||
/* */
|
||||
static int ac_session_action_station_configuration_ieee8011_add_station(struct ac_session_t* session, struct ac_notify_station_configuration_ieee8011_add_station* notify) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct capwap_addstation_element addstation;
|
||||
struct capwap_80211_station_element station;
|
||||
|
||||
ASSERT(session->requestfragmentpacket->count == 0);
|
||||
|
||||
/* Check if RADIO id and WLAN id is valid */
|
||||
if (!IS_VALID_RADIOID(notify->radioid) || !IS_VALID_WLANID(notify->wlanid)) {
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
}
|
||||
|
||||
/* */
|
||||
memset(&addstation, 0, sizeof(struct capwap_addstation_element));
|
||||
addstation.radioid = notify->radioid;
|
||||
addstation.length = MACADDRESS_EUI48_LENGTH;
|
||||
addstation.address = notify->address;
|
||||
if (notify->vlan[0]) {
|
||||
addstation.vlan = notify->vlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
memset(&station, 0, sizeof(struct capwap_80211_station_element));
|
||||
station.radioid = notify->radioid;
|
||||
station.associationid = notify->associationid;
|
||||
memcpy(station.address, notify->address, MACADDRESS_EUI48_LENGTH);
|
||||
station.capabilities = notify->capabilities;
|
||||
station.wlanid = notify->wlanid;
|
||||
station.supportedratescount = notify->supportedratescount;
|
||||
memcpy(station.supportedrates, notify->supportedrates, station.supportedratescount);
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_STATION_CONFIGURATION_REQUEST, session->localseqnumber++, session->mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ADDSTATION, &addstation);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_STATION, &station);
|
||||
|
||||
/* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */
|
||||
|
||||
/* Station Configuration Request complete, get fragment packets */
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
|
||||
if (session->requestfragmentpacket->count > 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send Station Configuration Request to WTP */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->connection.socket.socket[session->connection.socket.type], session->requestfragmentpacket, &session->connection.localaddr, &session->connection.remoteaddr)) {
|
||||
session->retransmitcount = 0;
|
||||
capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send Station Configuration Request packet");
|
||||
ac_free_reference_last_request(session);
|
||||
ac_session_teardown(session);
|
||||
}
|
||||
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_session_action_station_configuration_ieee8011_delete_station(struct ac_session_t* session, struct ac_notify_station_configuration_ieee8011_delete_station* notify) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct capwap_deletestation_element deletestation;
|
||||
|
||||
ASSERT(session->requestfragmentpacket->count == 0);
|
||||
|
||||
/* Check if RADIO id is valid */
|
||||
if (!IS_VALID_RADIOID(notify->radioid)) {
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
}
|
||||
|
||||
/* */
|
||||
memset(&deletestation, 0, sizeof(struct capwap_deletestation_element));
|
||||
deletestation.radioid = notify->radioid;
|
||||
deletestation.length = MACADDRESS_EUI48_LENGTH;
|
||||
deletestation.address = notify->address;
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_STATION_CONFIGURATION_REQUEST, session->localseqnumber++, session->mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_DELETESTATION, &deletestation);
|
||||
/* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */
|
||||
|
||||
/* Station Configuration Request complete, get fragment packets */
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
|
||||
if (session->requestfragmentpacket->count > 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send Station Configuration Request to WTP */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&session->dtls, session->connection.socket.socket[session->connection.socket.type], session->requestfragmentpacket, &session->connection.localaddr, &session->connection.remoteaddr)) {
|
||||
session->retransmitcount = 0;
|
||||
capwap_timeout_set(session->timeout, session->idtimercontrol, AC_RETRANSMIT_INTERVAL, ac_dfa_retransmition_timeout, session, NULL);
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send Station Configuration Request packet");
|
||||
ac_free_reference_last_request(session);
|
||||
ac_session_teardown(session);
|
||||
}
|
||||
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
}
|
||||
|
||||
@ -177,12 +285,7 @@ static int ac_session_action_execute(struct ac_session_t* session, struct ac_ses
|
||||
}
|
||||
|
||||
case AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION: {
|
||||
break;
|
||||
}
|
||||
|
||||
case AC_SESSION_ACTION_ROAMING_STATION: {
|
||||
/* Delete station */
|
||||
ac_stations_delete_station(session, (uint8_t*)action->data);
|
||||
result = ac_session_action_station_configuration_ieee8011_delete_station(session, (struct ac_notify_station_configuration_ieee8011_delete_station*)action->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -427,9 +530,6 @@ static void ac_session_destroy(struct ac_session_t* session) {
|
||||
capwap_itemlist_free(capwap_itemlist_remove_head(session->packets));
|
||||
}
|
||||
|
||||
/* Free WLANS */
|
||||
ac_wlans_destroy(session);
|
||||
|
||||
/* */
|
||||
capwap_event_destroy(&session->changereference);
|
||||
capwap_event_destroy(&session->waitpacket);
|
||||
|
@ -27,7 +27,9 @@ struct ac_session_control {
|
||||
#define AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION 5
|
||||
#define AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION 6
|
||||
|
||||
#define AC_SESSION_ACTION_ROAMING_STATION 10
|
||||
#define AC_SESSION_DATA_ACTION_ROAMING_STATION 1
|
||||
#define AC_SESSION_DATA_ACTION_ASSIGN_BSSID 2
|
||||
#define AC_SESSION_DATA_ACTION_ADD_STATION_STATUS 3
|
||||
|
||||
/* */
|
||||
struct ac_session_action {
|
||||
@ -52,6 +54,52 @@ struct ac_session_notify_event_t {
|
||||
};
|
||||
};
|
||||
|
||||
/* Reset notification */
|
||||
struct ac_notify_reset_t {
|
||||
uint32_t vendor;
|
||||
uint8_t name[0];
|
||||
};
|
||||
|
||||
/* Add WLAN notification */
|
||||
struct ac_notify_addwlan_t {
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
uint16_t capability;
|
||||
uint8_t qos;
|
||||
uint8_t authmode;
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
uint8_t suppressssid;
|
||||
char ssid[CAPWAP_ADD_WLAN_SSID_LENGTH + 1];
|
||||
};
|
||||
|
||||
/* Station Configuration IEEE802.11 add station notification */
|
||||
struct ac_notify_station_configuration_ieee8011_add_station {
|
||||
uint8_t radioid;
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t vlan[CAPWAP_ADDSTATION_VLAN_MAX_LENGTH];
|
||||
|
||||
uint8_t wlanid;
|
||||
uint16_t associationid;
|
||||
uint16_t capabilities;
|
||||
uint8_t supportedratescount;
|
||||
uint8_t supportedrates[CAPWAP_STATION_RATES_MAXLENGTH];
|
||||
};
|
||||
|
||||
/* Station Configuration IEEE802.11 delete station notification */
|
||||
struct ac_notify_station_configuration_ieee8011_delete_station {
|
||||
uint8_t radioid;
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_notify_add_station_status {
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint16_t statuscode;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_session_t;
|
||||
struct ac_session_data_t;
|
||||
@ -66,8 +114,13 @@ struct ac_session_data_t {
|
||||
long count;
|
||||
capwap_event_t changereference;
|
||||
|
||||
/* WLAN Reference */
|
||||
struct ac_wlans* wlans;
|
||||
|
||||
/* */
|
||||
int enabledtls;
|
||||
unsigned short mtu;
|
||||
unsigned short fragmentid;
|
||||
struct capwap_connection connection;
|
||||
struct capwap_dtls dtls;
|
||||
|
||||
@ -96,9 +149,6 @@ struct ac_session_t {
|
||||
long count;
|
||||
capwap_event_t changereference;
|
||||
|
||||
/* WLAN Reference */
|
||||
struct ac_wlans* wlans;
|
||||
|
||||
/* Soap */
|
||||
struct ac_http_soap_request* soaprequest;
|
||||
|
||||
@ -149,6 +199,8 @@ void ac_session_data_close(struct ac_session_data_t* sessiondata);
|
||||
void ac_session_data_send_action(struct ac_session_data_t* sessiondata, long action, long param, void* data, long length);
|
||||
void ac_session_data_release_reference(struct ac_session_data_t* sessiondata);
|
||||
|
||||
void ac_session_data_send_data_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe);
|
||||
|
||||
/* IEEE802.11 Packet */
|
||||
void ac_ieee80211_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* buffer, int length);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "ac.h"
|
||||
#include "capwap_dfa.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
#include "ieee80211.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
@ -9,11 +10,53 @@
|
||||
|
||||
#define AC_BODY_PACKET_MAX_SIZE 8192
|
||||
|
||||
/* */
|
||||
static int ac_session_data_action_add_station_status(struct ac_session_data_t* sessiondata, struct ac_notify_add_station_status* notify) {
|
||||
struct ac_wlan* wlan;
|
||||
struct ac_station* station;
|
||||
|
||||
wlan = ac_wlans_get_bssid_with_wlanid(sessiondata, notify->radioid, notify->wlanid);
|
||||
if (wlan) {
|
||||
station = ac_stations_get_station(sessiondata, notify->radioid, wlan->bssid, notify->address);
|
||||
if (station) {
|
||||
if (CAPWAP_RESULTCODE_OK(notify->statuscode)) {
|
||||
station->flags |= AC_STATION_FLAGS_AUTHORIZED;
|
||||
} else {
|
||||
ac_stations_delete_station(sessiondata, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_session_data_action_execute(struct ac_session_data_t* sessiondata, struct ac_session_action* action) {
|
||||
int result = AC_ERROR_ACTION_SESSION;
|
||||
|
||||
/* TODO */
|
||||
switch (action->action) {
|
||||
case AC_SESSION_DATA_ACTION_ROAMING_STATION: {
|
||||
struct ac_station* station;
|
||||
|
||||
/* Delete station */
|
||||
station = ac_stations_get_station(sessiondata, RADIOID_ANY, NULL, (uint8_t*)action->data);
|
||||
if (station) {
|
||||
ac_stations_delete_station(sessiondata, station);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AC_SESSION_DATA_ACTION_ASSIGN_BSSID: {
|
||||
ac_wlans_assign_bssid(sessiondata, *(struct ac_wlan**)action->data);
|
||||
break;
|
||||
}
|
||||
|
||||
case AC_SESSION_DATA_ACTION_ADD_STATION_STATUS: {
|
||||
result = ac_session_data_action_add_station_status(sessiondata, (struct ac_notify_add_station_status*)action->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -178,7 +221,7 @@ static int ac_session_data_keepalive(struct ac_session_data_t* sessiondata, stru
|
||||
|
||||
/* Data keepalive complete, get fragment packets into local list */
|
||||
txfragpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, sessiondata->fragmentid);
|
||||
if (txfragpacket->count == 1) {
|
||||
/* Send Data keepalive to WTP */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&sessiondata->dtls, sessiondata->connection.socket.socket[sessiondata->connection.socket.type], txfragpacket, &sessiondata->connection.localaddr, &sessiondata->connection.remoteaddr)) {
|
||||
@ -244,6 +287,9 @@ static void ac_session_data_destroy(struct ac_session_data_t* sessiondata) {
|
||||
/* Free DTLS */
|
||||
capwap_crypt_freesession(&sessiondata->dtls);
|
||||
|
||||
/* Free WLANS */
|
||||
ac_wlans_destroy(sessiondata);
|
||||
|
||||
/* Free resource */
|
||||
while (sessiondata->packets->count > 0) {
|
||||
capwap_itemlist_free(capwap_itemlist_remove_head(sessiondata->packets));
|
||||
@ -421,3 +467,38 @@ void* ac_session_data_thread(void* param) {
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_session_data_send_data_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe) {
|
||||
struct capwap_list* txfragpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, radioid, sessiondata->session->binding);
|
||||
capwap_header_set_nativeframe_flag(&capwapheader, (leavenativeframe ? 1: 0));
|
||||
txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, sessiondata->mtu);
|
||||
|
||||
/* */
|
||||
if (leavenativeframe) {
|
||||
capwap_packet_txmng_add_data(txmngpacket, data, length);
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Data message complete, get fragment packets into local list */
|
||||
txfragpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, sessiondata->fragmentid);
|
||||
if (txfragpacket->count > 1) {
|
||||
sessiondata->fragmentid++;
|
||||
}
|
||||
|
||||
/* */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&sessiondata->dtls, sessiondata->connection.socket.socket[sessiondata->connection.socket.type], txfragpacket, &sessiondata->connection.localaddr, &sessiondata->connection.remoteaddr)) {
|
||||
capwap_logging_debug("Warning: error to send data packet");
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_list_free(txfragpacket);
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
}
|
||||
|
@ -1,20 +1,21 @@
|
||||
#include "ac.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
#include "ac_backend.h"
|
||||
|
||||
/* */
|
||||
static void ac_stations_delete_station_from_global_cache(struct ac_session_t* session, uint8_t* address) {
|
||||
struct ac_session_t* ownersession;
|
||||
static void ac_stations_delete_station_from_global_cache(struct ac_session_data_t* sessiondata, uint8_t* address) {
|
||||
struct ac_session_data_t* ownersession;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(address != NULL);
|
||||
|
||||
/* */
|
||||
capwap_rwlock_wrlock(&g_ac.stationslock);
|
||||
|
||||
/* Can delete global reference only if match session handler */
|
||||
ownersession = (struct ac_session_t*)capwap_hash_search(g_ac.stations, address);
|
||||
if (ownersession == session) {
|
||||
ownersession = (struct ac_session_data_t*)capwap_hash_search(g_ac.stations, address);
|
||||
if (ownersession == sessiondata) {
|
||||
capwap_hash_delete(g_ac.stations, address);
|
||||
}
|
||||
|
||||
@ -22,17 +23,17 @@ static void ac_stations_delete_station_from_global_cache(struct ac_session_t* se
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_station* station) {
|
||||
static void ac_stations_destroy_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Destroy station: %s", capwap_printf_macaddress(buffer, station->address, MACADDRESS_EUI48_LENGTH));
|
||||
|
||||
/* Remove reference from Global Cache Stations List */
|
||||
ac_stations_delete_station_from_global_cache(session, station->address);
|
||||
ac_stations_delete_station_from_global_cache(sessiondata, station->address);
|
||||
|
||||
/* Remove reference from WLAN */
|
||||
if (station->wlan) {
|
||||
@ -40,7 +41,7 @@ static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_hash_delete(session->wlans->stations, station->address);
|
||||
capwap_hash_delete(sessiondata->wlans->stations, station->address);
|
||||
|
||||
/* Free station reference with itemlist */
|
||||
capwap_itemlist_free(station->wlanitem);
|
||||
@ -65,39 +66,42 @@ static void ac_stations_reset_station(struct ac_station* station, struct ac_wlan
|
||||
capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
station->flags = 0;
|
||||
|
||||
/* Set WLAN */
|
||||
station->wlan = wlan;
|
||||
capwap_itemlist_insert_after(wlan->stations, NULL, station->wlanitem);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_init(struct ac_session_t* session) {
|
||||
ASSERT(session != NULL);
|
||||
void ac_wlans_init(struct ac_session_data_t* sessiondata) {
|
||||
ASSERT(sessiondata != NULL);
|
||||
|
||||
/* */
|
||||
session->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
|
||||
memset(session->wlans, 0, sizeof(struct ac_wlans));
|
||||
sessiondata->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
|
||||
memset(sessiondata->wlans, 0, sizeof(struct ac_wlans));
|
||||
|
||||
/* */
|
||||
session->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE, AC_WLANS_STATIONS_KEY_SIZE, ac_wlans_item_gethash, NULL, NULL);
|
||||
sessiondata->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE, AC_WLANS_STATIONS_KEY_SIZE, ac_wlans_item_gethash, NULL, NULL);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_destroy(struct ac_session_t* session) {
|
||||
void ac_wlans_destroy(struct ac_session_data_t* sessiondata) {
|
||||
int i;
|
||||
struct capwap_list* items;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
|
||||
/* */
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
if (session->wlans->wlans[i]) {
|
||||
items = session->wlans->wlans[i];
|
||||
if (sessiondata->wlans->wlans[i]) {
|
||||
items = sessiondata->wlans->wlans[i];
|
||||
|
||||
/* Delete WLANS */
|
||||
while (items->first) {
|
||||
ac_wlans_delete_bssid(session, i + 1, ((struct ac_wlan*)items->first->item)->bssid);
|
||||
ac_wlans_delete_bssid(sessiondata, i + 1, ((struct ac_wlan*)items->first->item)->bssid);
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -106,20 +110,50 @@ void ac_wlans_destroy(struct ac_session_t* session) {
|
||||
}
|
||||
|
||||
/* */
|
||||
ASSERT(session->wlans->stations->count == 0);
|
||||
ASSERT(sessiondata->wlans->stations->count == 0);
|
||||
|
||||
/* */
|
||||
capwap_hash_free(session->wlans->stations);
|
||||
capwap_free(session->wlans);
|
||||
capwap_hash_free(sessiondata->wlans->stations);
|
||||
capwap_free(sessiondata->wlans);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid) {
|
||||
int ac_wlans_assign_bssid(struct ac_session_data_t* sessiondata, struct ac_wlan* wlan) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(wlan != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(wlan->radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlan->wlanid));
|
||||
|
||||
/* */
|
||||
if (ac_wlans_get_bssid(sessiondata, wlan->radioid, wlan->bssid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
wlan->session = sessiondata->session;
|
||||
wlan->sessiondata = sessiondata;
|
||||
|
||||
/* Create WLAN list */
|
||||
if (!sessiondata->wlans->wlans[wlan->radioid - 1]) {
|
||||
sessiondata->wlans->wlans[wlan->radioid - 1] = capwap_list_create();
|
||||
}
|
||||
|
||||
/* Append WLAN to list */
|
||||
capwap_itemlist_insert_after(sessiondata->wlans->wlans[wlan->radioid - 1], NULL, wlan->wlanitem);
|
||||
|
||||
/* */
|
||||
capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->bssid, MACADDRESS_EUI48_LENGTH));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan) {
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
ASSERT(bssid != NULL);
|
||||
@ -130,132 +164,13 @@ struct ac_wlan* ac_wlans_create_bssid(struct ac_session_t* session, uint8_t radi
|
||||
memset(wlan, 0, sizeof(struct ac_wlan));
|
||||
|
||||
/* Init WLAN */
|
||||
wlan->wlanitem = wlanitem;
|
||||
memcpy(wlan->bssid, bssid, MACADDRESS_EUI48_LENGTH);
|
||||
wlan->radioid = radioid;
|
||||
wlan->wlanid = wlanid;
|
||||
wlan->stations = capwap_list_create();
|
||||
|
||||
/* Create WLAN list */
|
||||
if (!session->wlans->wlans[radioid - 1]) {
|
||||
session->wlans->wlans[radioid - 1] = capwap_list_create();
|
||||
}
|
||||
|
||||
/* Append WLAN to list */
|
||||
capwap_itemlist_insert_after(session->wlans->wlans[radioid - 1], NULL, wlanitem);
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (session->wlans->wlans[radioid - 1]) {
|
||||
search = session->wlans->wlans[radioid - 1]->first;
|
||||
while (search) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, item->bssid, MACADDRESS_EUI48_LENGTH)) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
search = search->next;
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
|
||||
/* */
|
||||
if (session->wlans->wlans[radioid - 1]) {
|
||||
search = session->wlans->wlans[radioid - 1]->first;
|
||||
while (search) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (wlanid == item->wlanid) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
search = search->next;
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_wlans_destroy_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
|
||||
/* Free capability */
|
||||
if (wlan->key) {
|
||||
capwap_free(wlan->key);
|
||||
}
|
||||
|
||||
if (wlan->ssid) {
|
||||
capwap_free(wlan->ssid);
|
||||
}
|
||||
|
||||
/* Remove stations */
|
||||
while (wlan->stations->first) {
|
||||
ac_stations_destroy_station(session, (struct ac_station*)wlan->stations->first->item);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_list_free(wlan->stations);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (session->wlans->wlans[radioid - 1]) {
|
||||
search = session->wlans->wlans[radioid - 1]->first;
|
||||
while (search) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, item->bssid, MACADDRESS_EUI48_LENGTH)) {
|
||||
ac_wlans_destroy_bssid(session, item);
|
||||
capwap_itemlist_free(capwap_itemlist_remove(session->wlans->wlans[radioid - 1], search));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
search = search->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_set_bssid_capability(struct ac_wlan* wlan, struct capwap_80211_addwlan_element* addwlan) {
|
||||
ASSERT(wlan != NULL);
|
||||
ASSERT(addwlan != NULL);
|
||||
|
||||
/* Set capability */
|
||||
wlan->capability = addwlan->capability;
|
||||
|
||||
wlan->keyindex = addwlan->keyindex;
|
||||
@ -274,21 +189,126 @@ void ac_wlans_set_bssid_capability(struct ac_wlan* wlan, struct capwap_80211_add
|
||||
|
||||
wlan->suppressssid = addwlan->suppressssid;
|
||||
wlan->ssid = (uint8_t*)capwap_duplicate_string((const char*)addwlan->ssid);
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
struct ac_station* station;
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (sessiondata->wlans->wlans[radioid - 1]) {
|
||||
search = sessiondata->wlans->wlans[radioid - 1]->first;
|
||||
while (search) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, item->bssid, MACADDRESS_EUI48_LENGTH)) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
search = search->next;
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
|
||||
/* */
|
||||
if (sessiondata->wlans->wlans[radioid - 1]) {
|
||||
search = sessiondata->wlans->wlans[radioid - 1]->first;
|
||||
while (search) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (wlanid == item->wlanid) {
|
||||
wlan = item;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
search = search->next;
|
||||
}
|
||||
}
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_wlans_destroy_bssid(struct ac_session_data_t* sessiondata, struct ac_wlan* wlan) {
|
||||
/* Free capability */
|
||||
if (wlan->key) {
|
||||
capwap_free(wlan->key);
|
||||
}
|
||||
|
||||
if (wlan->ssid) {
|
||||
capwap_free(wlan->ssid);
|
||||
}
|
||||
|
||||
/* Remove stations */
|
||||
while (wlan->stations->first) {
|
||||
ac_stations_destroy_station(sessiondata, (struct ac_station*)wlan->stations->first->item);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_list_free(wlan->stations);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_delete_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (sessiondata->wlans->wlans[radioid - 1]) {
|
||||
search = sessiondata->wlans->wlans[radioid - 1]->first;
|
||||
while (search) {
|
||||
struct ac_wlan* item = (struct ac_wlan*)search->item;
|
||||
|
||||
if (!memcmp(bssid, item->bssid, MACADDRESS_EUI48_LENGTH)) {
|
||||
ac_wlans_destroy_bssid(sessiondata, item);
|
||||
capwap_itemlist_free(capwap_itemlist_remove(sessiondata->wlans->wlans[radioid - 1], search));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
search = search->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
struct ac_station* station;
|
||||
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(address != NULL);
|
||||
|
||||
/* Get station */
|
||||
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
|
||||
if (station && (radioid == station->wlan->radioid) && !memcmp(bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = (struct ac_station*)capwap_hash_search(sessiondata->wlans->stations, address);
|
||||
if (station && ((radioid == RADIOID_ANY) || (radioid == station->wlan->radioid)) && (!bssid || !memcmp(bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH))) {
|
||||
return station;
|
||||
}
|
||||
|
||||
@ -296,16 +316,16 @@ struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
char buffer1[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
char buffer2[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
struct ac_wlan* wlan;
|
||||
struct ac_session_t* ownersession;
|
||||
struct ac_session_data_t* ownersession;
|
||||
struct ac_station* station;
|
||||
struct capwap_list_item* stationitem;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
ASSERT(address != NULL);
|
||||
@ -317,25 +337,25 @@ struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint
|
||||
|
||||
/* Get session that owns the station */
|
||||
capwap_rwlock_rdlock(&g_ac.stationslock);
|
||||
ownersession = (struct ac_session_t*)capwap_hash_search(g_ac.stations, address);
|
||||
ownersession = (struct ac_session_data_t*)capwap_hash_search(g_ac.stations, address);
|
||||
capwap_rwlock_exit(&g_ac.stationslock);
|
||||
|
||||
/* If request change owner of station */
|
||||
if (ownersession != session) {
|
||||
if (ownersession != sessiondata) {
|
||||
/* Release station from old owner */
|
||||
if (ownersession) {
|
||||
ac_session_send_action(ownersession, AC_SESSION_ACTION_ROAMING_STATION, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
|
||||
ac_session_data_send_action(ownersession, AC_SESSION_DATA_ACTION_ROAMING_STATION, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
|
||||
}
|
||||
|
||||
/* Set station into Global Cache Stations List */
|
||||
capwap_rwlock_wrlock(&g_ac.stationslock);
|
||||
capwap_hash_add(g_ac.stations, address, session);
|
||||
capwap_hash_add(g_ac.stations, address, sessiondata);
|
||||
capwap_rwlock_exit(&g_ac.stationslock);
|
||||
}
|
||||
|
||||
/* */
|
||||
wlan = ac_wlans_get_bssid(session, radioid, bssid);
|
||||
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
|
||||
wlan = ac_wlans_get_bssid(sessiondata, radioid, bssid);
|
||||
station = ac_stations_get_station(sessiondata, RADIOID_ANY, NULL, address);
|
||||
if (!station) {
|
||||
stationitem = capwap_itemlist_create(sizeof(struct ac_station));
|
||||
station = (struct ac_station*)stationitem->item;
|
||||
@ -346,7 +366,7 @@ struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint
|
||||
station->wlanitem = stationitem;
|
||||
|
||||
/* */
|
||||
capwap_hash_add(session->wlans->stations, address, station);
|
||||
capwap_hash_add(sessiondata->wlans->stations, address, station);
|
||||
}
|
||||
|
||||
/* Set station to WLAN */
|
||||
@ -356,16 +376,73 @@ struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_delete_station(struct ac_session_t* session, const uint8_t* address) {
|
||||
struct ac_station* station;
|
||||
void ac_stations_delete_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(address != NULL);
|
||||
/* Deauthorize station */
|
||||
ac_stations_deauthorize_station(sessiondata, station);
|
||||
|
||||
/* Delete station */
|
||||
station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
|
||||
if (station) {
|
||||
ac_stations_destroy_station(session, station);
|
||||
/* Destroy station reference */
|
||||
ac_stations_destroy_station(sessiondata, station);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_authorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
|
||||
struct ac_notify_station_configuration_ieee8011_add_station notify;
|
||||
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* Active Station only if Authenticated, Associated and not Authrizated */
|
||||
if ((station->flags & AC_STATION_FLAGS_AUTHENTICATED) && (station->flags & AC_STATION_FLAGS_ASSOCIATE) && !(station->flags & AC_STATION_FLAGS_AUTHORIZED)) {
|
||||
memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
|
||||
notify.radioid = station->wlan->radioid;
|
||||
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
notify.wlanid = station->wlan->wlanid;
|
||||
notify.associationid = station->aid;
|
||||
notify.capabilities = station->capability;
|
||||
notify.supportedratescount = station->supportedratescount;
|
||||
memcpy(notify.supportedrates, station->supportedrates, station->supportedratescount);
|
||||
|
||||
ac_session_send_action(sessiondata->session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_stations_deauthorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
|
||||
int responselength;
|
||||
uint8_t buffer[IEEE80211_MTU];
|
||||
struct ieee80211_deauthentication_params ieee80211_params;
|
||||
struct ac_notify_station_configuration_ieee8011_delete_station notify;
|
||||
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(sessiondata->wlans != NULL);
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* Delete Station only if Authrizated */
|
||||
if (station->flags & AC_STATION_FLAGS_AUTHORIZED) {
|
||||
memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
|
||||
notify.radioid = station->wlan->radioid;
|
||||
memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
|
||||
/* Request recall ac_stations_deauthorize_station for deauthentication the station */
|
||||
station->flags &= ~AC_STATION_FLAGS_AUTHORIZED;
|
||||
ac_session_send_action(sessiondata->session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
|
||||
} else if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
|
||||
/* Create deauthentication packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_deauthentication_params));
|
||||
memcpy(ieee80211_params.bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH);
|
||||
memcpy(ieee80211_params.station, station->address, MACADDRESS_EUI48_LENGTH);
|
||||
ieee80211_params.reasoncode = IEEE80211_REASON_PREV_AUTH_NOT_VALID;
|
||||
|
||||
/* */
|
||||
responselength = ieee80211_create_deauthentication(buffer, IEEE80211_MTU, &ieee80211_params);
|
||||
if (responselength > 0) {
|
||||
station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
|
||||
ac_session_data_send_data_packet(sessiondata, station->wlan->radioid, station->wlan->wlanid, buffer, responselength, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,17 @@
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
/* */
|
||||
#define RADIOID_ANY 0
|
||||
|
||||
/* */
|
||||
#define AC_WLANS_STATIONS_HASH_SIZE 256
|
||||
#define AC_WLANS_STATIONS_KEY_SIZE MACADDRESS_EUI48_LENGTH
|
||||
|
||||
/* AC WLAN */
|
||||
struct ac_wlan {
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
@ -35,13 +40,31 @@ struct ac_wlan {
|
||||
uint8_t* ssid;
|
||||
};
|
||||
|
||||
/* */
|
||||
#define AC_STATION_FLAGS_AUTHENTICATED 0x00000001
|
||||
#define AC_STATION_FLAGS_ASSOCIATE 0x00000002
|
||||
#define AC_STATION_FLAGS_AUTHORIZED 0x00000004
|
||||
|
||||
/* AC Station */
|
||||
struct ac_station {
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
unsigned long flags;
|
||||
|
||||
/* Reference of WLAN */
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
/* */
|
||||
uint16_t capability;
|
||||
uint16_t listeninterval;
|
||||
uint16_t aid;
|
||||
|
||||
/* */
|
||||
int supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
|
||||
/* Authentication */
|
||||
uint16_t authalgorithm;
|
||||
};
|
||||
|
||||
/* */
|
||||
@ -53,21 +76,21 @@ struct ac_wlans {
|
||||
};
|
||||
|
||||
/* Management WLANS */
|
||||
void ac_wlans_init(struct ac_session_t* session);
|
||||
void ac_wlans_destroy(struct ac_session_t* session);
|
||||
void ac_wlans_init(struct ac_session_data_t* sessiondata);
|
||||
void ac_wlans_destroy(struct ac_session_data_t* sessiondata);
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid, const uint8_t* bssid);
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid);
|
||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
|
||||
|
||||
/* */
|
||||
void ac_wlans_set_bssid_capability(struct ac_wlan* wlan, struct capwap_80211_addwlan_element* addwlan);
|
||||
struct ac_wlan* ac_wlans_create_bssid(uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan);
|
||||
int ac_wlans_assign_bssid(struct ac_session_data_t* sessiondata, struct ac_wlan* wlan);
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid);
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid);
|
||||
void ac_wlans_delete_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid);
|
||||
|
||||
/* Management Stations */
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
void ac_stations_delete_station(struct ac_session_t* session, const uint8_t* address);
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
struct ac_station* ac_stations_get_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
|
||||
void ac_stations_delete_station(struct ac_session_data_t* sessiondata, struct ac_station* station);
|
||||
void ac_stations_authorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station);
|
||||
void ac_stations_deauthorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station);
|
||||
|
||||
#endif /* __AC_WLANS_HEADER__ */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -662,7 +662,16 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
|
||||
}
|
||||
|
||||
case CAPWAP_STATION_CONFIGURATION_REQUEST: {
|
||||
/* TODO */
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ADDSTATION)) {
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_STATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ struct capwap_write_message_elements_ops {
|
||||
int (*write_u8)(capwap_message_elements_handle handle, uint8_t data);
|
||||
int (*write_u16)(capwap_message_elements_handle handle, uint16_t data);
|
||||
int (*write_u32)(capwap_message_elements_handle handle, uint32_t data);
|
||||
int (*write_block)(capwap_message_elements_handle handle, uint8_t* data, unsigned short length);
|
||||
int (*write_block)(capwap_message_elements_handle handle, const uint8_t* data, unsigned short length);
|
||||
};
|
||||
|
||||
struct capwap_read_message_elements_ops {
|
||||
|
@ -25,7 +25,7 @@ static void capwap_80211_miccountermeasures_element_create(void* data, capwap_me
|
||||
|
||||
func->write_u8(handle, element->radioid);
|
||||
func->write_u8(handle, element->wlanid);
|
||||
func->write_block(handle, element->address, CAPWAP_MIC_COUNTERMEASURES_MACADDRESS_LENGTH);
|
||||
func->write_block(handle, element->address, MACADDRESS_EUI48_LENGTH);
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -47,7 +47,7 @@ static void* capwap_80211_miccountermeasures_element_parsing(capwap_message_elem
|
||||
/* Retrieve data */
|
||||
func->read_u8(handle, &data->radioid);
|
||||
func->read_u8(handle, &data->wlanid);
|
||||
func->read_block(handle, data->address, CAPWAP_MIC_COUNTERMEASURES_MACADDRESS_LENGTH);
|
||||
func->read_block(handle, data->address, MACADDRESS_EUI48_LENGTH);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -3,12 +3,10 @@
|
||||
|
||||
#define CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES 1031
|
||||
|
||||
#define CAPWAP_MIC_COUNTERMEASURES_MACADDRESS_LENGTH 6
|
||||
|
||||
struct capwap_80211_miccountermeasures_element {
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
uint8_t address[CAPWAP_MIC_COUNTERMEASURES_MACADDRESS_LENGTH];
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
};
|
||||
|
||||
extern struct capwap_message_elements_ops capwap_element_80211_miccountermeasures_ops;
|
||||
|
@ -40,8 +40,8 @@ static void capwap_80211_rsnaerrorreport_element_create(void* data, capwap_messa
|
||||
|
||||
ASSERT(data != NULL);
|
||||
|
||||
func->write_block(handle, element->client, CAPWAP_RSNA_ERROR_REPORT_CLIENT_LENGTH);
|
||||
func->write_block(handle, element->bssid, CAPWAP_RSNA_ERROR_REPORT_BSSID_LENGTH);
|
||||
func->write_block(handle, element->client, MACADDRESS_EUI48_LENGTH);
|
||||
func->write_block(handle, element->bssid, MACADDRESS_EUI48_LENGTH);
|
||||
func->write_u8(handle, element->radioid);
|
||||
func->write_u8(handle, element->wlanid);
|
||||
func->write_u16(handle, 0);
|
||||
@ -70,8 +70,8 @@ static void* capwap_80211_rsnaerrorreport_element_parsing(capwap_message_element
|
||||
memset(data, 0, sizeof(struct capwap_80211_rsnaerrorreport_element));
|
||||
|
||||
/* Retrieve data */
|
||||
func->read_block(handle, data->client, CAPWAP_RSNA_ERROR_REPORT_CLIENT_LENGTH);
|
||||
func->read_block(handle, data->bssid, CAPWAP_RSNA_ERROR_REPORT_BSSID_LENGTH);
|
||||
func->read_block(handle, data->client, MACADDRESS_EUI48_LENGTH);
|
||||
func->read_block(handle, data->bssid, MACADDRESS_EUI48_LENGTH);
|
||||
func->read_u8(handle, &data->radioid);
|
||||
func->read_u8(handle, &data->wlanid);
|
||||
func->read_u16(handle, NULL);
|
||||
|
@ -3,12 +3,9 @@
|
||||
|
||||
#define CAPWAP_ELEMENT_80211_RSNA_ERROR_REPORT 1035
|
||||
|
||||
#define CAPWAP_RSNA_ERROR_REPORT_CLIENT_LENGTH 6
|
||||
#define CAPWAP_RSNA_ERROR_REPORT_BSSID_LENGTH 6
|
||||
|
||||
struct capwap_80211_rsnaerrorreport_element {
|
||||
uint8_t client[CAPWAP_RSNA_ERROR_REPORT_CLIENT_LENGTH];
|
||||
uint8_t bssid[CAPWAP_RSNA_ERROR_REPORT_BSSID_LENGTH];
|
||||
uint8_t client[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
uint32_t tkipicverrors;
|
||||
|
@ -30,7 +30,7 @@ static void capwap_80211_station_element_create(void* data, capwap_message_eleme
|
||||
func->write_u8(handle, element->radioid);
|
||||
func->write_u16(handle, element->associationid);
|
||||
func->write_u8(handle, element->flags);
|
||||
func->write_block(handle, element->address, CAPWAP_STATION_ADDRESS_LENGTH);
|
||||
func->write_block(handle, element->address, MACADDRESS_EUI48_LENGTH);
|
||||
func->write_u16(handle, element->capabilities);
|
||||
func->write_u8(handle, element->wlanid);
|
||||
func->write_block(handle, element->supportedrates, element->supportedratescount);
|
||||
@ -64,7 +64,7 @@ static void* capwap_80211_station_element_parsing(capwap_message_elements_handle
|
||||
func->read_u8(handle, &data->radioid);
|
||||
func->read_u16(handle, &data->associationid);
|
||||
func->read_u8(handle, &data->flags);
|
||||
func->read_block(handle, data->address, CAPWAP_STATION_ADDRESS_LENGTH);
|
||||
func->read_block(handle, data->address, MACADDRESS_EUI48_LENGTH);
|
||||
func->read_u16(handle, &data->capabilities);
|
||||
func->read_u8(handle, &data->wlanid);
|
||||
data->supportedratescount = length;
|
||||
|
@ -3,14 +3,13 @@
|
||||
|
||||
#define CAPWAP_ELEMENT_80211_STATION 1036
|
||||
|
||||
#define CAPWAP_STATION_ADDRESS_LENGTH 6
|
||||
#define CAPWAP_STATION_RATES_MAXLENGTH 128
|
||||
|
||||
struct capwap_80211_station_element {
|
||||
uint8_t radioid;
|
||||
uint16_t associationid;
|
||||
uint8_t flags;
|
||||
uint8_t address[CAPWAP_STATION_ADDRESS_LENGTH];
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint16_t capabilities;
|
||||
uint8_t wlanid;
|
||||
uint8_t supportedratescount;
|
||||
|
@ -31,7 +31,7 @@ static void capwap_80211_stationkey_element_create(void* data, capwap_message_el
|
||||
|
||||
ASSERT(data != NULL);
|
||||
|
||||
func->write_block(handle, element->address, CAPWAP_STATION_SESSION_KEY_ADDRESS_LENGTH);
|
||||
func->write_block(handle, element->address, MACADDRESS_EUI48_LENGTH);
|
||||
func->write_u16(handle, element->flags);
|
||||
func->write_block(handle, element->pairwisetsc, CAPWAP_STATION_SESSION_KEY_PAIRWISE_TSC_LENGTH);
|
||||
func->write_block(handle, element->pairwisersc, CAPWAP_STATION_SESSION_KEY_PAIRWISE_RSC_LENGTH);
|
||||
@ -59,7 +59,7 @@ static void* capwap_80211_stationkey_element_parsing(capwap_message_elements_han
|
||||
memset(data, 0, sizeof(struct capwap_80211_stationkey_element));
|
||||
|
||||
/* Retrieve data */
|
||||
func->read_block(handle, data->address, CAPWAP_STATION_SESSION_KEY_ADDRESS_LENGTH);
|
||||
func->read_block(handle, data->address, MACADDRESS_EUI48_LENGTH);
|
||||
func->read_u16(handle, &data->flags);
|
||||
func->read_block(handle, data->pairwisetsc, CAPWAP_STATION_SESSION_KEY_PAIRWISE_TSC_LENGTH);
|
||||
func->read_block(handle, data->pairwisersc, CAPWAP_STATION_SESSION_KEY_PAIRWISE_RSC_LENGTH);
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#define CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE 1038
|
||||
|
||||
#define CAPWAP_STATION_SESSION_KEY_ADDRESS_LENGTH 6
|
||||
#define CAPWAP_STATION_SESSION_KEY_PAIRWISE_TSC_LENGTH 6
|
||||
#define CAPWAP_STATION_SESSION_KEY_PAIRWISE_RSC_LENGTH 6
|
||||
|
||||
@ -11,7 +10,7 @@
|
||||
#define CAPWAP_STATION_SESSION_KEY_AC_ENCRYPT 0x4000
|
||||
|
||||
struct capwap_80211_stationkey_element {
|
||||
uint8_t address[CAPWAP_STATION_SESSION_KEY_ADDRESS_LENGTH];
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint16_t flags;
|
||||
uint8_t pairwisetsc[CAPWAP_STATION_SESSION_KEY_PAIRWISE_TSC_LENGTH];
|
||||
uint8_t pairwisersc[CAPWAP_STATION_SESSION_KEY_PAIRWISE_RSC_LENGTH];
|
||||
|
@ -23,7 +23,7 @@ static void capwap_80211_stationqos_element_create(void* data, capwap_message_el
|
||||
|
||||
ASSERT(data != NULL);
|
||||
|
||||
func->write_block(handle, element->address, CAPWAP_STATION_QOS_ADDRESS_LENGTH);
|
||||
func->write_block(handle, element->address, MACADDRESS_EUI48_LENGTH);
|
||||
func->write_u8(handle, 0);
|
||||
func->write_u8(handle, element->priority);
|
||||
}
|
||||
@ -45,7 +45,7 @@ static void* capwap_80211_stationqos_element_parsing(capwap_message_elements_han
|
||||
memset(data, 0, sizeof(struct capwap_80211_stationqos_element));
|
||||
|
||||
/* Retrieve data */
|
||||
func->read_block(handle, data->address, CAPWAP_STATION_QOS_ADDRESS_LENGTH);
|
||||
func->read_block(handle, data->address, MACADDRESS_EUI48_LENGTH);
|
||||
func->read_u8(handle, NULL);
|
||||
func->read_u8(handle, &data->priority);
|
||||
|
||||
|
@ -3,10 +3,8 @@
|
||||
|
||||
#define CAPWAP_ELEMENT_80211_STATION_QOS_PROFILE 1037
|
||||
|
||||
#define CAPWAP_STATION_QOS_ADDRESS_LENGTH 6
|
||||
|
||||
struct capwap_80211_stationqos_element {
|
||||
uint8_t address[CAPWAP_STATION_QOS_ADDRESS_LENGTH];
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t priority;
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ static void capwap_80211_updatestationqos_element_create(void* data, capwap_mess
|
||||
ASSERT(data != NULL);
|
||||
|
||||
func->write_u8(handle, element->radioid);
|
||||
func->write_block(handle, element->address, CAPWAP_UPDATE_STATION_QOS_ADDRESS_LENGTH);
|
||||
func->write_block(handle, element->address, MACADDRESS_EUI48_LENGTH);
|
||||
for (i = 0; i < CAPWAP_UPDATE_STATION_QOS_SUBELEMENTS; i++) {
|
||||
func->write_u8(handle, element->qos[i].priority8021p & CAPWAP_UPDATE_STATION_QOS_PRIORIY_MASK);
|
||||
func->write_u8(handle, element->qos[i].dscp & CAPWAP_UPDATE_STATION_QOS_DSCP_MASK);
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#define CAPWAP_ELEMENT_80211_UPDATE_STATION_QOS 1043
|
||||
|
||||
#define CAPWAP_UPDATE_STATION_QOS_ADDRESS_LENGTH 6
|
||||
#define CAPWAP_UPDATE_STATION_QOS_SUBELEMENTS 4
|
||||
|
||||
#define CAPWAP_UPDATE_STATION_QOS_PRIORIY_MASK 0x07
|
||||
@ -16,7 +15,7 @@ struct capwap_80211_updatestationqos_subelement {
|
||||
|
||||
struct capwap_80211_updatestationqos_element {
|
||||
uint8_t radioid;
|
||||
uint8_t address[CAPWAP_UPDATE_STATION_QOS_ADDRESS_LENGTH];
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
struct capwap_80211_updatestationqos_subelement qos[CAPWAP_UPDATE_STATION_QOS_SUBELEMENTS];
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ static void capwap_80211_wtpradioconf_element_create(void* data, capwap_message_
|
||||
func->write_u8(handle, element->shortpreamble);
|
||||
func->write_u8(handle, element->maxbssid);
|
||||
func->write_u8(handle, element->dtimperiod);
|
||||
func->write_block(handle, element->bssid, CAPWAP_WTP_RADIO_CONF_BSSID_LENGTH);
|
||||
func->write_block(handle, element->bssid, MACADDRESS_EUI48_LENGTH);
|
||||
func->write_u16(handle, element->beaconperiod);
|
||||
func->write_block(handle, element->country, CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH);
|
||||
}
|
||||
@ -57,7 +57,7 @@ static void* capwap_80211_wtpradioconf_element_parsing(capwap_message_elements_h
|
||||
func->read_u8(handle, &data->shortpreamble);
|
||||
func->read_u8(handle, &data->maxbssid);
|
||||
func->read_u8(handle, &data->dtimperiod);
|
||||
func->read_block(handle, data->bssid, CAPWAP_WTP_RADIO_CONF_BSSID_LENGTH);
|
||||
func->read_block(handle, data->bssid, MACADDRESS_EUI48_LENGTH);
|
||||
func->read_u16(handle, &data->beaconperiod);
|
||||
func->read_block(handle, data->country, CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH);
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#define CAPWAP_ELEMENT_80211_WTP_RADIO_CONF 1046
|
||||
|
||||
#define CAPWAP_WTP_RADIO_CONF_BSSID_LENGTH 6
|
||||
#define CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH 4
|
||||
|
||||
#define CAPWAP_WTP_RADIO_CONF_SHORTPREAMBLE_DISABLE 0
|
||||
@ -14,7 +13,7 @@ struct capwap_80211_wtpradioconf_element {
|
||||
uint8_t shortpreamble;
|
||||
uint8_t maxbssid;
|
||||
uint8_t dtimperiod;
|
||||
uint8_t bssid[CAPWAP_WTP_RADIO_CONF_BSSID_LENGTH];
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint16_t beaconperiod;
|
||||
uint8_t country[CAPWAP_WTP_RADIO_CONF_COUNTRY_LENGTH];
|
||||
};
|
||||
|
@ -352,7 +352,7 @@ static struct capwap_list_item* capwap_packet_txmng_create_fragment_item(struct
|
||||
}
|
||||
|
||||
/* */
|
||||
static int capwap_fragment_write_block_from_pos(struct capwap_packet_txmng* txmngpacket, uint8_t* data, unsigned short length, struct write_block_from_pos* writepos) {
|
||||
static int capwap_fragment_write_block_from_pos(struct capwap_packet_txmng* txmngpacket, const uint8_t* data, unsigned short length, struct write_block_from_pos* writepos) {
|
||||
unsigned short packetpos;
|
||||
struct capwap_list_item* item;
|
||||
struct capwap_fragment_packet_item* fragmentpacket;
|
||||
@ -430,7 +430,7 @@ static int capwap_fragment_write_block_from_pos(struct capwap_packet_txmng* txmn
|
||||
}
|
||||
|
||||
/* */
|
||||
static int capwap_fragment_write_block(capwap_message_elements_handle handle, uint8_t* data, unsigned short length) {
|
||||
static int capwap_fragment_write_block(capwap_message_elements_handle handle, const uint8_t* data, unsigned short length) {
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct write_block_from_pos writepos;
|
||||
|
||||
@ -611,7 +611,7 @@ struct capwap_packet_txmng* capwap_packet_txmng_create_data_message(struct capwa
|
||||
}
|
||||
|
||||
/* */
|
||||
void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, uint8_t* data, unsigned short length) {
|
||||
void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, const uint8_t* data, unsigned short length) {
|
||||
ASSERT(txmngpacket != NULL);
|
||||
ASSERT(txmngpacket->isctrlpacket == 0);
|
||||
|
||||
|
@ -65,7 +65,7 @@ struct capwap_packet_txmng {
|
||||
/* */
|
||||
struct capwap_packet_txmng* capwap_packet_txmng_create_ctrl_message(struct capwap_header_data* data, unsigned long type, unsigned char seq, unsigned short mtu);
|
||||
struct capwap_packet_txmng* capwap_packet_txmng_create_data_message(struct capwap_header_data* data, unsigned short mtu);
|
||||
void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, uint8_t* data, unsigned short length);
|
||||
void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, const uint8_t* data, unsigned short length);
|
||||
void capwap_packet_txmng_add_message_element(struct capwap_packet_txmng* txmngpacket, unsigned short type, void* data);
|
||||
void capwap_packet_txmng_get_fragment_packets(struct capwap_packet_txmng* txmngpacket, struct capwap_list* fragmentlist, unsigned short fragmentid);
|
||||
void capwap_packet_txmng_free(struct capwap_packet_txmng* txmngpacket);
|
||||
|
@ -65,6 +65,6 @@ void wtp_dfa_state_run_keepalivedead_timeout(struct capwap_timeout* timeout, uns
|
||||
void wtp_dfa_state_reset(void);
|
||||
|
||||
/* */
|
||||
void wtp_send_data_wireless_packet(uint8_t radioid, uint8_t wlanid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, int leavenativeframe);
|
||||
void wtp_send_data_packet(uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe);
|
||||
|
||||
#endif /* __WTP_DFA_HEADER__ */
|
||||
|
@ -110,14 +110,22 @@ static void receive_station_configuration_request(struct capwap_parsed_packet* p
|
||||
if ((binding == g_wtp.binding) && IS_SEQUENCE_SMALLER(g_wtp.remoteseqnumber, packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE };
|
||||
|
||||
/* TODO */
|
||||
/* Parsing request message */
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ADDSTATION)) {
|
||||
resultcode.code = wtp_radio_add_station(packet);
|
||||
} else if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETESTATION)) {
|
||||
resultcode.code = wtp_radio_delete_station(packet);
|
||||
}
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_STATION_CONFIGURATION_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, g_wtp.mtu);
|
||||
|
||||
/* TODO */
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
|
||||
/* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */
|
||||
|
||||
/* Station Configuration response complete, get fragment packets */
|
||||
wtp_free_reference_last_response();
|
||||
@ -238,7 +246,7 @@ static void send_data_keepalive_request() {
|
||||
}
|
||||
|
||||
/* */
|
||||
void wtp_send_data_wireless_packet(uint8_t radioid, uint8_t wlanid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, int leavenativeframe) {
|
||||
void wtp_send_data_packet(uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe) {
|
||||
struct capwap_list* txfragpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
@ -250,14 +258,18 @@ void wtp_send_data_wireless_packet(uint8_t radioid, uint8_t wlanid, const struct
|
||||
|
||||
/* */
|
||||
if (leavenativeframe) {
|
||||
capwap_packet_txmng_add_data(txmngpacket, (uint8_t*)mgmt, (unsigned short)mgmtlength);
|
||||
capwap_packet_txmng_add_data(txmngpacket, data, (unsigned short)length);
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Data message complete, get fragment packets into local list */
|
||||
txfragpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, g_wtp.fragmentid);
|
||||
if (txfragpacket->count > 1) {
|
||||
g_wtp.fragmentid++;
|
||||
}
|
||||
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.datadtls, g_wtp.acdatasock.socket[g_wtp.acdatasock.type], txfragpacket, &g_wtp.wtpdataaddress, &g_wtp.acdataaddress)) {
|
||||
capwap_logging_debug("Warning: error to send data packet");
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ static void wtp_radio_send_mgmtframe_to_ac(void* param, const struct ieee80211_h
|
||||
ASSERT(mgmtlength >= sizeof(struct ieee80211_header));
|
||||
|
||||
/* Send packet */
|
||||
wtp_send_data_wireless_packet(wlan->radio->radioid, wlan->wlanid, mgmt, mgmtlength, 1);
|
||||
wtp_send_data_packet(wlan->radio->radioid, wlan->wlanid, (const uint8_t*)mgmt, mgmtlength, 1);
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -589,6 +589,8 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa
|
||||
struct wlan_startap_params params;
|
||||
struct capwap_80211_addwlan_element* addwlan;
|
||||
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
/* Get message elements */
|
||||
addwlan = (struct capwap_80211_addwlan_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_ADD_WLAN);
|
||||
if (!addwlan) {
|
||||
@ -678,6 +680,50 @@ uint32_t wtp_radio_delete_wlan(struct capwap_parsed_packet* packet) {
|
||||
return CAPWAP_RESULTCODE_SUCCESS;
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32_t wtp_radio_add_station(struct capwap_parsed_packet* packet) {
|
||||
struct capwap_addstation_element* addstation;
|
||||
struct capwap_80211_station_element* station80211;
|
||||
struct wtp_radio* radio;
|
||||
struct wtp_radio_wlan* wlan;
|
||||
struct station_add_params stationparams;
|
||||
|
||||
/* Get message elements */
|
||||
addstation = (struct capwap_addstation_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_ADDSTATION);
|
||||
station80211 = (struct capwap_80211_station_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_STATION);
|
||||
if (!station80211 || (addstation->radioid != station80211->radioid)) {
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Get physical radio */
|
||||
radio = wtp_radio_get_phy(addstation->radioid);
|
||||
if (!radio) {
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Get virtual interface */
|
||||
wlan = wtp_radio_get_wlan(radio, station80211->wlanid);
|
||||
if (!wlan) {
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Authorize station */
|
||||
memset(&stationparams, 0, sizeof(struct station_add_params));
|
||||
stationparams.address = station80211->address;
|
||||
|
||||
if (wifi_station_add(wlan->wlanhandle, &stationparams)) {
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
return CAPWAP_RESULTCODE_SUCCESS;
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32_t wtp_radio_delete_station(struct capwap_parsed_packet* packet) {
|
||||
/* TODO */
|
||||
return CAPWAP_RESULTCODE_SUCCESS;
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_radio_acl_station(const uint8_t* macaddress) {
|
||||
ASSERT(macaddress != NULL);
|
||||
|
@ -76,6 +76,10 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet, struct capwa
|
||||
uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet);
|
||||
uint32_t wtp_radio_delete_wlan(struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
uint32_t wtp_radio_add_station(struct capwap_parsed_packet* packet);
|
||||
uint32_t wtp_radio_delete_station(struct capwap_parsed_packet* packet);
|
||||
|
||||
/* Station ACL */
|
||||
int wtp_radio_acl_station(const uint8_t* macaddress);
|
||||
void wtp_radio_acl_addstation(const uint8_t* macaddress);
|
||||
|
Loading…
Reference in New Issue
Block a user