Started implementing the packet management of IEEE802.11 by AC side.
Made it clear some constants.
This commit is contained in:
@ -26,11 +26,6 @@ static unsigned long ac_stations_item_gethash(const void* key, unsigned long key
|
||||
return ((((unsigned long)macaddress[4] << 8) | (unsigned long)macaddress[5]) ^ ((unsigned long)macaddress[3] << 4));
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_stations_item_free(const void* key, unsigned long keysize, void* data) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Alloc AC */
|
||||
static int ac_init(void) {
|
||||
g_ac.standalone = 1;
|
||||
@ -79,7 +74,8 @@ static int ac_init(void) {
|
||||
capwap_rwlock_init(&g_ac.sessionslock);
|
||||
|
||||
/* Stations */
|
||||
g_ac.stations = capwap_hash_create(AC_STATIONS_HASH_SIZE, AC_STATIONS_KEY_SIZE, ac_stations_item_gethash, NULL, ac_stations_item_free);
|
||||
g_ac.stations = capwap_hash_create(AC_STATIONS_HASH_SIZE, AC_STATIONS_KEY_SIZE, ac_stations_item_gethash, NULL, NULL);
|
||||
capwap_rwlock_init(&g_ac.stationslock);
|
||||
|
||||
/* Backend */
|
||||
g_ac.availablebackends = capwap_array_create(sizeof(struct ac_http_soap_server*), 0, 0);
|
||||
@ -121,6 +117,7 @@ static void ac_destroy(void) {
|
||||
|
||||
/* Stations */
|
||||
capwap_hash_free(g_ac.stations);
|
||||
capwap_rwlock_destroy(&g_ac.stationslock);
|
||||
|
||||
/* Backend */
|
||||
if (g_ac.backendacid) {
|
||||
|
@ -57,7 +57,7 @@
|
||||
|
||||
/* */
|
||||
#define AC_STATIONS_HASH_SIZE 65536
|
||||
#define AC_STATIONS_KEY_SIZE ETH_ALEN
|
||||
#define AC_STATIONS_KEY_SIZE MACADDRESS_EUI48_LENGTH
|
||||
|
||||
/* */
|
||||
struct ac_state {
|
||||
@ -99,6 +99,7 @@ struct ac_t {
|
||||
|
||||
/* Stations */
|
||||
struct capwap_hash* stations;
|
||||
capwap_rwlock_t stationslock;
|
||||
|
||||
/* Dtls */
|
||||
int enabledtls;
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include "ac.h"
|
||||
#include "capwap_dfa.h"
|
||||
#include "capwap_array.h"
|
||||
#include "capwap_array.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
|
||||
/* */
|
||||
static int receive_echo_request(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
@ -61,13 +63,74 @@ static int receive_echo_request(struct ac_session_t* session, struct capwap_pars
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
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[18];
|
||||
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->wlans, assignbssid->radioid, assignbssid->bssid)) {
|
||||
wlan = ac_wlans_create_bssid(session->wlans, assignbssid->radioid, assignbssid->wlanid, assignbssid->bssid);
|
||||
wlan->session = session;
|
||||
wlan->sessiondata = session->sessiondata;
|
||||
|
||||
/* 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void execute_ieee80211_wlan_configuration_updatewlan(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct capwap_80211_updatewlan_element* updatewlan, struct capwap_parsed_packet* requestpacket) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static void execute_ieee80211_wlan_configuration_deletewlan(struct ac_session_t* session, struct capwap_parsed_packet* packet, struct capwap_80211_deletewlan_element* deletewlan, struct capwap_parsed_packet* requestpacket) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static void receive_ieee80211_wlan_configuration_response(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
struct capwap_80211_addwlan_element* addwlan;
|
||||
struct capwap_80211_updatewlan_element* updatewlan;
|
||||
struct capwap_80211_deletewlan_element* deletewlan;
|
||||
struct capwap_parsed_packet requestpacket;
|
||||
struct capwap_packet_rxmng* rxmngrequestpacket;
|
||||
struct capwap_resultcode_element* resultcode;
|
||||
|
||||
/* Check the success of the Request */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
if (CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
rxmngrequestpacket = capwap_packet_rxmng_create_from_requestfragmentpacket(session->requestfragmentpacket);
|
||||
if (rxmngrequestpacket) {
|
||||
if (capwap_parsing_packet(rxmngrequestpacket, NULL, &requestpacket) == PARSING_COMPLETE) {
|
||||
/* Detect type of IEEE802.11 WLAN Configuration Request */
|
||||
addwlan = (struct capwap_80211_addwlan_element*)capwap_get_message_element_data(&requestpacket, CAPWAP_ELEMENT_80211_ADD_WLAN);
|
||||
if (addwlan) {
|
||||
execute_ieee80211_wlan_configuration_addwlan(session, packet, addwlan, &requestpacket);
|
||||
} else {
|
||||
updatewlan = (struct capwap_80211_updatewlan_element*)capwap_get_message_element_data(&requestpacket, CAPWAP_ELEMENT_80211_UPDATE_WLAN);
|
||||
if (updatewlan) {
|
||||
execute_ieee80211_wlan_configuration_updatewlan(session, packet, updatewlan, &requestpacket);
|
||||
} else {
|
||||
deletewlan = (struct capwap_80211_deletewlan_element*)capwap_get_message_element_data(&requestpacket, CAPWAP_ELEMENT_80211_DELETE_WLAN);
|
||||
if (deletewlan) {
|
||||
execute_ieee80211_wlan_configuration_deletewlan(session, packet, deletewlan, &requestpacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_free_parsed_packet(&requestpacket);
|
||||
capwap_packet_rxmng_free(rxmngrequestpacket);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_warning("Receive IEEE802.11 WLAN Configuration Response with error: %d", (int)resultcode->code);
|
||||
}
|
||||
|
||||
|
@ -156,12 +156,12 @@ static void ac_discovery_run(void) {
|
||||
sizedata = itempacket->itemsize - sizeof(struct ac_discovery_packet);
|
||||
|
||||
/* Accept only discovery request don't fragment */
|
||||
rxmngpacket = capwap_packet_rxmng_create_message(1);
|
||||
rxmngpacket = capwap_packet_rxmng_create_message(CAPWAP_CONTROL_PACKET);
|
||||
if (capwap_packet_rxmng_add_recv_packet(rxmngpacket, acpacket->data, sizedata) == CAPWAP_RECEIVE_COMPLETE_PACKET) {
|
||||
/* Validate message */
|
||||
if (capwap_check_message_type(rxmngpacket) == VALID_MESSAGE_TYPE) {
|
||||
/* Parsing packet */
|
||||
if (!capwap_parsing_packet(rxmngpacket, NULL, &packet)) {
|
||||
if (capwap_parsing_packet(rxmngpacket, NULL, &packet) == PARSING_COMPLETE) {
|
||||
/* Validate packet */
|
||||
if (!capwap_validate_parsed_packet(&packet, NULL)) {
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "ac_session.h"
|
||||
#include "ac_discovery.h"
|
||||
#include "ac_backend.h"
|
||||
#include "ac_wlans.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
@ -501,6 +502,9 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
|
||||
session->count = 2;
|
||||
capwap_event_init(&session->changereference);
|
||||
|
||||
/* */
|
||||
session->wlans = ac_wlans_init();
|
||||
|
||||
/* */
|
||||
session->timeout = capwap_timeout_init();
|
||||
session->idtimercontrol = capwap_timeout_createtimer(session->timeout);
|
||||
|
@ -3,8 +3,165 @@
|
||||
#include "ieee80211.h"
|
||||
|
||||
/* */
|
||||
void ac_ieee80211_data(struct ac_session_data_t* sessiondata, uint8_t* buffer, int length) {
|
||||
static void ac_ieee80211_mgmt_probe_request_packet(struct ac_session_data_t* sessiondata, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_data_t* sessiondata, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_data_t* sessiondata, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_reassociation_request_packet(struct ac_session_data_t* sessiondata, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_disassociation_packet(struct ac_session_data_t* sessiondata, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_data_t* sessiondata, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
struct ieee80211_ie_items ieitems;
|
||||
|
||||
/* Parsing Information Elements */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest));
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_ieee80211_mgmt_packet(struct ac_session_data_t* sessiondata, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint16_t framecontrol_subtype) {
|
||||
switch (framecontrol_subtype) {
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest))) {
|
||||
ac_ieee80211_mgmt_probe_request_packet(sessiondata, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication))) {
|
||||
ac_ieee80211_mgmt_authentication_packet(sessiondata, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest))) {
|
||||
ac_ieee80211_mgmt_association_request_packet(sessiondata, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest))) {
|
||||
ac_ieee80211_mgmt_reassociation_request_packet(sessiondata, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation))) {
|
||||
ac_ieee80211_mgmt_disassociation_packet(sessiondata, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION: {
|
||||
if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->deauthetication))) {
|
||||
ac_ieee80211_mgmt_deauthentication_packet(sessiondata, mgmt, mgmtlength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_ieee80211_packet(struct ac_session_data_t* sessiondata, const uint8_t* buffer, int length) {
|
||||
const struct ieee80211_header* header;
|
||||
uint16_t framecontrol;
|
||||
uint16_t framecontrol_type;
|
||||
uint16_t framecontrol_subtype;
|
||||
|
||||
ASSERT(sessiondata != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(length > 0);
|
||||
ASSERT(length >= sizeof(struct ieee80211_header));
|
||||
|
||||
/* Get type frame */
|
||||
header = (const struct ieee80211_header*)buffer;
|
||||
framecontrol = __le16_to_cpu(header->framecontrol);
|
||||
framecontrol_type = IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol);
|
||||
framecontrol_subtype = IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol);
|
||||
|
||||
/* Parsing frame */
|
||||
if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
|
||||
ac_ieee80211_mgmt_packet(sessiondata, (const struct ieee80211_header_mgmt*)buffer, length, framecontrol_subtype);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#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
|
||||
@ -59,6 +60,13 @@ static int ac_session_action_addwlan(struct ac_session_t* session, struct ac_not
|
||||
|
||||
ASSERT(session->requestfragmentpacket->count == 0);
|
||||
|
||||
/* 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;
|
||||
} else if (ac_wlans_get_bssid_with_wlanid(session->wlans, notify->radioid, notify->wlanid)) {
|
||||
return AC_ERROR_ACTION_SESSION;
|
||||
}
|
||||
|
||||
/* */
|
||||
memset(&addwlan, 0, sizeof(struct capwap_80211_addwlan_element));
|
||||
addwlan.radioid = notify->radioid;
|
||||
@ -397,6 +405,9 @@ 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->wlans);
|
||||
|
||||
/* */
|
||||
capwap_event_destroy(&session->changereference);
|
||||
capwap_event_destroy(&session->waitpacket);
|
||||
@ -497,7 +508,7 @@ static void ac_session_run(struct ac_session_t* session) {
|
||||
|
||||
/* Defragment management */
|
||||
if (!session->rxmngpacket) {
|
||||
session->rxmngpacket = capwap_packet_rxmng_create_message(1);
|
||||
session->rxmngpacket = capwap_packet_rxmng_create_message(CAPWAP_CONTROL_PACKET);
|
||||
}
|
||||
|
||||
/* If request, defragmentation packet */
|
||||
|
@ -92,6 +92,9 @@ struct ac_session_t {
|
||||
long count;
|
||||
capwap_event_t changereference;
|
||||
|
||||
/* WLAN Reference */
|
||||
struct ac_wlans* wlans;
|
||||
|
||||
/* Soap */
|
||||
struct ac_http_soap_request* soaprequest;
|
||||
|
||||
@ -142,8 +145,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);
|
||||
|
||||
/* IEEE802.11 Data Packet */
|
||||
void ac_ieee80211_data(struct ac_session_data_t* sessiondata, uint8_t* buffer, int length);
|
||||
/* IEEE802.11 Packet */
|
||||
void ac_ieee80211_packet(struct ac_session_data_t* sessiondata, const uint8_t* buffer, int length);
|
||||
|
||||
/* */
|
||||
int ac_has_sessionid(struct capwap_sessionid_element* sessionid);
|
||||
|
@ -344,7 +344,7 @@ static void ac_session_data_run(struct ac_session_data_t* sessiondata) {
|
||||
|
||||
/* Defragment management */
|
||||
if (!sessiondata->rxmngpacket) {
|
||||
sessiondata->rxmngpacket = capwap_packet_rxmng_create_message(0);
|
||||
sessiondata->rxmngpacket = capwap_packet_rxmng_create_message(CAPWAP_DATA_PACKET);
|
||||
}
|
||||
|
||||
/* If request, defragmentation packet */
|
||||
@ -368,8 +368,8 @@ static void ac_session_data_run(struct ac_session_data_t* sessiondata) {
|
||||
/* Parsing body packet */
|
||||
if (bodypacketlength > 0) {
|
||||
binding = GET_WBID_HEADER(sessiondata->rxmngpacket->header);
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
ac_ieee80211_data(sessiondata, bodypacket, bodypacketlength);
|
||||
if ((binding == CAPWAP_WIRELESS_BINDING_IEEE80211) && (bodypacketlength >= sizeof(struct ieee80211_header))) {
|
||||
ac_ieee80211_packet(sessiondata, bodypacket, bodypacketlength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
191
src/ac/ac_wlans.c
Normal file
191
src/ac/ac_wlans.c
Normal file
@ -0,0 +1,191 @@
|
||||
#include "ac.h"
|
||||
#include "ac_session.h"
|
||||
#include "ac_wlans.h"
|
||||
|
||||
/* */
|
||||
struct ac_wlans* ac_wlans_init(void) {
|
||||
struct ac_wlans* wlans;
|
||||
|
||||
/* */
|
||||
wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
|
||||
memset(wlans, 0, sizeof(struct ac_wlans));
|
||||
|
||||
return wlans;
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_destroy(struct ac_wlans* wlans) {
|
||||
int i;
|
||||
|
||||
ASSERT(wlans != NULL);
|
||||
|
||||
/* */
|
||||
for (i = 0; i < RADIOID_MAX_COUNT; i++) {
|
||||
if (wlans->wlans[i]) {
|
||||
while (wlans->wlans[i]->first) {
|
||||
struct ac_wlan* wlan = (struct ac_wlan*)wlans->wlans[i]->first->item;
|
||||
|
||||
/* Delete WLAN */
|
||||
ac_wlans_delete_bssid(wlans, i + 1, wlan->bssid);
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
capwap_list_free(wlans->wlans[i]);
|
||||
}
|
||||
}
|
||||
|
||||
capwap_free(wlans);
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_wlans* wlans, uint8_t radioid, uint8_t wlanid, uint8_t* bssid) {
|
||||
struct ac_wlan* wlan;
|
||||
struct capwap_list_item* wlanitem;
|
||||
|
||||
ASSERT(wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
wlanitem = capwap_itemlist_create(sizeof(struct ac_wlan));
|
||||
wlan = (struct ac_wlan*)wlanitem->item;
|
||||
memset(wlan, 0, sizeof(struct ac_wlan));
|
||||
|
||||
/* Init WLAN */
|
||||
memcpy(wlan->bssid, bssid, MACADDRESS_EUI48_LENGTH);
|
||||
wlan->wlanid = wlanid;
|
||||
wlan->stations = capwap_list_create();
|
||||
|
||||
/* Create WLAN list */
|
||||
if (!wlans->wlans[radioid - 1]) {
|
||||
wlans->wlans[radioid - 1] = capwap_list_create();
|
||||
}
|
||||
|
||||
/* Append WLAN to list */
|
||||
capwap_itemlist_insert_after(wlans->wlans[radioid - 1], NULL, wlanitem);
|
||||
|
||||
return wlan;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_wlans* wlans, uint8_t radioid, uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (wlans->wlans[radioid - 1]) {
|
||||
search = 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_wlans* wlans, uint8_t radioid, uint8_t wlanid) {
|
||||
struct capwap_list_item* search;
|
||||
struct ac_wlan* wlan = NULL;
|
||||
|
||||
ASSERT(wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(IS_VALID_WLANID(wlanid));
|
||||
|
||||
/* */
|
||||
if (wlans->wlans[radioid - 1]) {
|
||||
search = 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_wlan* wlan) {
|
||||
/* Free capability */
|
||||
if (wlan->key) {
|
||||
capwap_free(wlan->key);
|
||||
}
|
||||
|
||||
if (wlan->ssid) {
|
||||
capwap_free(wlan->ssid);
|
||||
}
|
||||
|
||||
/* Remove stations */
|
||||
capwap_list_free(wlan->stations);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_wlans_delete_bssid(struct ac_wlans* wlans, uint8_t radioid, uint8_t* bssid) {
|
||||
struct capwap_list_item* search;
|
||||
|
||||
ASSERT(wlans != NULL);
|
||||
ASSERT(IS_VALID_RADIOID(radioid));
|
||||
ASSERT(bssid != NULL);
|
||||
|
||||
/* */
|
||||
if (wlans->wlans[radioid - 1]) {
|
||||
search = 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(item);
|
||||
capwap_itemlist_free(capwap_itemlist_remove(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);
|
||||
|
||||
wlan->capability = addwlan->capability;
|
||||
|
||||
wlan->keyindex = addwlan->keyindex;
|
||||
wlan->keystatus = addwlan->keystatus;
|
||||
wlan->keylength = addwlan->keylength;
|
||||
if (addwlan->key && (addwlan->keylength > 0)) {
|
||||
wlan->key = (uint8_t*)capwap_clone(addwlan->key, wlan->keylength);
|
||||
}
|
||||
|
||||
memcpy(wlan->grouptsc, addwlan->grouptsc, CAPWAP_ADD_WLAN_GROUPTSC_LENGTH);
|
||||
|
||||
wlan->qos = addwlan->qos;
|
||||
wlan->authmode = addwlan->authmode;
|
||||
wlan->macmode = addwlan->macmode;
|
||||
wlan->tunnelmode = addwlan->tunnelmode;
|
||||
|
||||
wlan->suppressssid = addwlan->suppressssid;
|
||||
wlan->ssid = (uint8_t*)capwap_duplicate_string((const char*)addwlan->ssid);
|
||||
}
|
58
src/ac/ac_wlans.h
Normal file
58
src/ac/ac_wlans.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef __AC_WLANS_HEADER__
|
||||
#define __AC_WLANS_HEADER__
|
||||
|
||||
/* AC WLAN */
|
||||
struct ac_wlan {
|
||||
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
|
||||
uint8_t wlanid;
|
||||
|
||||
/* CAPWAP Session */
|
||||
struct ac_session_t* session;
|
||||
struct ac_session_data_t* sessiondata;
|
||||
|
||||
/* Capability */
|
||||
uint16_t capability;
|
||||
uint8_t keyindex;
|
||||
uint8_t keystatus;
|
||||
uint16_t keylength;
|
||||
uint8_t* key;
|
||||
uint8_t grouptsc[CAPWAP_ADD_WLAN_GROUPTSC_LENGTH];
|
||||
uint8_t qos;
|
||||
uint8_t authmode;
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
uint8_t suppressssid;
|
||||
uint8_t* ssid;
|
||||
|
||||
/* Local cache stations */
|
||||
struct capwap_list* stations;
|
||||
};
|
||||
|
||||
/* AC Station */
|
||||
struct ac_station {
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
|
||||
/* Reference of WLAN */
|
||||
struct ac_wlan_device* wlan;
|
||||
struct capwap_list_item* itemlist;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_wlans {
|
||||
struct capwap_list* wlans[RADIOID_MAX_COUNT];
|
||||
};
|
||||
|
||||
/* */
|
||||
struct ac_wlans* ac_wlans_init(void);
|
||||
void ac_wlans_destroy(struct ac_wlans* wlans);
|
||||
|
||||
/* */
|
||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_wlans* wlans, uint8_t radioid, uint8_t wlanid, uint8_t* bssid);
|
||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_wlans* wlans, uint8_t radioid, uint8_t* bssid);
|
||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_wlans* wlans, uint8_t radioid, uint8_t wlanid);
|
||||
void ac_wlans_delete_bssid(struct ac_wlans* wlans, uint8_t radioid, uint8_t* bssid);
|
||||
|
||||
/* */
|
||||
void ac_wlans_set_bssid_capability(struct ac_wlan* wlan, struct capwap_80211_addwlan_element* addwlan);
|
||||
|
||||
#endif /* __AC_WLANS_HEADER__ */
|
Reference in New Issue
Block a user