Big update with type fix and minor new function.

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

View File

@ -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);

View File

@ -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);

View File

@ -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(&notify, 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*)&notify, 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;
}

View File

@ -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);

View File

@ -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);
}
}
/* */

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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(&notify, 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, &notify, 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(&notify, 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, &notify, 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);
}
}
}

View File

@ -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__ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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];

View File

@ -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);

View File

@ -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;
};

View File

@ -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);

View File

@ -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];
};

View File

@ -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);

View File

@ -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];
};

View File

@ -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);

View File

@ -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);

View File

@ -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__ */

View File

@ -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");
}

View File

@ -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);

View File

@ -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);