Started implementing the packet management of IEEE802.11 by AC side.

Made it clear some constants.
This commit is contained in:
vemax78 2014-04-02 22:40:04 +02:00
parent 7fd2d4357a
commit ae97e96f57
24 changed files with 609 additions and 44 deletions

View File

@ -52,6 +52,7 @@ ac_SOURCES = \
$(top_srcdir)/src/ac/ac_execute.c \
$(top_srcdir)/src/ac/ac_session.c \
$(top_srcdir)/src/ac/ac_session_data.c \
$(top_srcdir)/src/ac/ac_wlans.c \
$(top_srcdir)/src/ac/ac_ieee80211_data.c \
$(top_srcdir)/src/ac/ac_discovery.c \
$(top_srcdir)/src/ac/ac_80211_json.c \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2586,7 +2586,7 @@ static int nl80211_wlan_startap(wifi_wlan_handle handle, struct wlan_startap_par
/* Configuration complete */
wlanhandle->devicehandle->wlanactive++;
capwap_logging_info("Configured interface %s with '%s' SSID", wlanhandle->virtname, wlanhandle->ssid);
capwap_logging_info("Configured interface: %s, SSID: '%s'", wlanhandle->virtname, wlanhandle->ssid);
return 0;
}

View File

@ -25,7 +25,7 @@ static void capwap_80211_assignbssid_element_create(void* data, capwap_message_e
func->write_u8(handle, element->radioid);
func->write_u8(handle, element->wlanid);
func->write_block(handle, element->bssid, CAPWAP_ASSIGN_BSSID_LENGTH);
func->write_block(handle, element->bssid, MACADDRESS_EUI48_LENGTH);
}
/* */
@ -47,7 +47,7 @@ static void* capwap_80211_assignbssid_element_parsing(capwap_message_elements_ha
/* Retrieve data */
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->wlanid);
func->read_block(handle, data->bssid, CAPWAP_ASSIGN_BSSID_LENGTH);
func->read_block(handle, data->bssid, MACADDRESS_EUI48_LENGTH);
return data;
}

View File

@ -3,12 +3,10 @@
#define CAPWAP_ELEMENT_80211_ASSIGN_BSSID 1026
#define CAPWAP_ASSIGN_BSSID_LENGTH 6
struct capwap_80211_assignbssid_element {
uint8_t radioid;
uint8_t wlanid;
uint8_t bssid[CAPWAP_ASSIGN_BSSID_LENGTH];
uint8_t bssid[MACADDRESS_EUI48_LENGTH];
};
extern struct capwap_message_elements_ops capwap_element_80211_assignbssid_ops;

View File

@ -57,7 +57,7 @@ static void* capwap_80211_updatestationqos_element_parsing(capwap_message_elemen
/* Retrieve data */
func->read_u8(handle, &data->radioid);
func->read_block(handle, data->address, CAPWAP_ASSIGN_BSSID_LENGTH);
func->read_block(handle, data->address, MACADDRESS_EUI48_LENGTH);
for (i = 0; i < CAPWAP_UPDATE_STATION_QOS_SUBELEMENTS; i++) {
func->read_u8(handle, &data->qos[i].priority8021p);
data->qos[i].priority8021p &= CAPWAP_UPDATE_STATION_QOS_PRIORIY_MASK;

View File

@ -59,8 +59,6 @@ static struct capwap_hash_item* capwap_hash_search_items(struct capwap_hash* has
/* */
static int capwap_hash_foreach_items(struct capwap_hash* hash, struct capwap_hash_item* item, capwap_hash_item_foreach item_foreach, void* param) {
int result;
ASSERT(hash != NULL);
ASSERT(item_foreach != NULL);
ASSERT(item != NULL);
@ -73,8 +71,7 @@ static int capwap_hash_foreach_items(struct capwap_hash* hash, struct capwap_has
}
/* */
result = item_foreach(item->key, hash->keysize, item->data, param);
if (!result) {
if (!item_foreach(item->key, hash->keysize, item->data, param)) {
return 0;
}

View File

@ -1300,7 +1300,7 @@ void capwap_interface_list(struct capwap_network* net, struct capwap_list* list)
/* */
char* capwap_printf_macaddress(char* buffer, const unsigned char* macaddress, int type) {
char* capwap_printf_macaddress(char* buffer, const uint8_t* macaddress, int type) {
if (type == MACADDRESS_EUI48_LENGTH) {
sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", macaddress[0], macaddress[1], macaddress[2], macaddress[3], macaddress[4], macaddress[5]);
} else if (type == MACADDRESS_EUI64_LENGTH) {
@ -1313,7 +1313,7 @@ char* capwap_printf_macaddress(char* buffer, const unsigned char* macaddress, in
}
/* */
int capwap_scanf_macaddress(unsigned char* macaddress, const char* buffer, int type) {
int capwap_scanf_macaddress(uint8_t* macaddress, const char* buffer, int type) {
if (type == MACADDRESS_EUI48_LENGTH) {
if (sscanf(buffer, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddress[0], &macaddress[1], &macaddress[2], &macaddress[3], &macaddress[4], &macaddress[5]) != 6) {
return 0;

View File

@ -8,11 +8,6 @@
#define CAPWAP_CONTROL_PORT 5246
#define CAPWAP_MAX_PACKET_SIZE 65535
#define CAPWAP_MACADDRESS_NONE 0
#define CAPWAP_MACADDRESS_EUI48 6
#define CAPWAP_MACADDRESS_EUI64 8
#define CAPWAP_MACADDRESS_MAX_SIZE CAPWAP_MACADDRESS_EUI64
/* Helper */
#define CAPWAP_GET_NETWORK_PORT(address) ntohs((((address)->ss_family == AF_INET) ? ((struct sockaddr_in*)(address))->sin_port : ((struct sockaddr_in6*)(address))->sin6_port))
#define CAPWAP_SET_NETWORK_PORT(address, port) if ((address)->ss_family == AF_INET) { \
@ -95,7 +90,7 @@ int capwap_address_from_string(const char* ip, struct sockaddr_storage* address)
int capwap_get_localaddress_by_remoteaddress(struct sockaddr_storage* local, struct sockaddr_storage* remote, char* oif, int ipv6dualstack);
char* capwap_printf_macaddress(char* buffer, const unsigned char* macaddress, int type);
int capwap_scanf_macaddress(unsigned char* macaddress, const char* buffer, int type);
char* capwap_printf_macaddress(char* buffer, const uint8_t* macaddress, int type);
int capwap_scanf_macaddress(uint8_t* macaddress, const char* buffer, int type);
#endif /* __CAPWAP_NETWORK_HEADER__ */

View File

@ -208,7 +208,7 @@ void capwap_header_set_radio_macaddress(struct capwap_header_data* data, int rad
ASSERT(data != NULL);
header = (struct capwap_header*)&data->headerbuffer[0];
if (radiotype == CAPWAP_MACADDRESS_NONE) {
if (radiotype == MACADDRESS_NONE_LENGTH) {
if (IS_FLAG_M_HEADER(header)) {
if (!IS_FLAG_W_HEADER(header)) {
SET_HLEN_HEADER(header, sizeof(struct capwap_header) / 4);
@ -230,7 +230,7 @@ void capwap_header_set_radio_macaddress(struct capwap_header_data* data, int rad
int size = sizeof(struct capwap_header) / 4;
ASSERT(macaddress != NULL);
ASSERT((radiotype == CAPWAP_MACADDRESS_EUI48) || (radiotype == CAPWAP_MACADDRESS_EUI64));
ASSERT((radiotype == MACADDRESS_EUI48_LENGTH) || (radiotype == MACADDRESS_EUI64_LENGTH));
if (IS_FLAG_M_HEADER(header)) {
radio = GET_RADIO_MAC_ADDRESS_STRUCT(header);
@ -242,7 +242,7 @@ void capwap_header_set_radio_macaddress(struct capwap_header_data* data, int rad
}
/* Remove old radio mac address */
capwap_header_set_radio_macaddress(data, CAPWAP_MACADDRESS_NONE, NULL);
capwap_header_set_radio_macaddress(data, MACADDRESS_NONE_LENGTH, NULL);
}
/* Radio mac address size*/
@ -1001,6 +1001,45 @@ int capwap_packet_rxmng_add_recv_packet(struct capwap_packet_rxmng* rxmngpacket,
return CAPWAP_WRONG_FRAGMENT;
}
/* */
struct capwap_packet_rxmng* capwap_packet_rxmng_create_from_requestfragmentpacket(struct capwap_list* requestfragmentpacket) {
struct capwap_packet_rxmng* rxmngpacket;
struct capwap_list_item* fragment;
int result = CAPWAP_WRONG_FRAGMENT;
ASSERT(requestfragmentpacket != NULL);
if (!requestfragmentpacket->count) {
return NULL;
}
/* */
rxmngpacket = capwap_packet_rxmng_create_message(CAPWAP_CONTROL_PACKET);
/* */
fragment = requestfragmentpacket->first;
while (fragment != NULL) {
struct capwap_fragment_packet_item* fragmentpacket = (struct capwap_fragment_packet_item*)fragment->item;
/* Append fragment */
result = capwap_packet_rxmng_add_recv_packet(rxmngpacket, fragmentpacket->buffer, fragmentpacket->offset);
if (result == CAPWAP_WRONG_FRAGMENT) {
break;
}
/* Next fragment */
fragment = fragment->next;
}
/* */
if (result != CAPWAP_RECEIVE_COMPLETE_PACKET) {
capwap_packet_rxmng_free(rxmngpacket);
rxmngpacket = NULL;
}
return rxmngpacket;
}
/* */
void capwap_packet_rxmng_free(struct capwap_packet_rxmng* rxmngpacket) {
if (rxmngpacket) {

View File

@ -107,10 +107,16 @@ struct capwap_packet_rxmng {
#define CAPWAP_REQUEST_MORE_FRAGMENT 0
#define CAPWAP_RECEIVE_COMPLETE_PACKET 1
#define CAPWAP_CONTROL_PACKET 1
#define CAPWAP_DATA_PACKET 0
struct capwap_packet_rxmng* capwap_packet_rxmng_create_message(int isctrlpacket);
int capwap_packet_rxmng_add_recv_packet(struct capwap_packet_rxmng* rxmngpacket, void* data, int length);
void capwap_packet_rxmng_free(struct capwap_packet_rxmng* rxmngpacket);
/* Parsing a packet sent */
struct capwap_packet_rxmng* capwap_packet_rxmng_create_from_requestfragmentpacket(struct capwap_list* requestfragmentpacket);
/* */
int capwap_is_request_type(unsigned long type);

View File

@ -188,6 +188,9 @@ struct capwap_data_message {
#define IS_SEQUENCE_SMALLER(s1, s2) (((((s1) < (s2)) && (((s2) - (s1)) < 128)) || (((s1) > (s2)) && (((s1) - (s2)) > 128))) ? 1 : 0)
/* */
#define MACADDRESS_NONE_LENGTH 0
/* */
#define MACADDRESS_EUI48_LENGTH 6
struct capwap_macaddress_eui48 {

View File

@ -22,13 +22,13 @@ static struct capwap_packet_rxmng* wtp_get_packet_rxmng(int isctrlmsg) {
if (isctrlmsg) {
if (!g_wtp.rxmngctrlpacket) {
g_wtp.rxmngctrlpacket = capwap_packet_rxmng_create_message(1);
g_wtp.rxmngctrlpacket = capwap_packet_rxmng_create_message(CAPWAP_CONTROL_PACKET);
}
rxmngpacket = g_wtp.rxmngctrlpacket;
} else {
if (!g_wtp.rxmngdatapacket) {
g_wtp.rxmngdatapacket = capwap_packet_rxmng_create_message(0);
g_wtp.rxmngdatapacket = capwap_packet_rxmng_create_message(CAPWAP_DATA_PACKET);
}
rxmngpacket = g_wtp.rxmngdatapacket;

View File

@ -99,6 +99,47 @@ static void receive_reset_request(struct capwap_parsed_packet* packet) {
}
}
/* */
static void receive_station_configuration_request(struct capwap_parsed_packet* packet) {
unsigned short binding;
ASSERT(packet != NULL);
/* */
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
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;
/* TODO */
/* 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 */
/* Station Configuration response complete, get fragment packets */
wtp_free_reference_last_response();
capwap_packet_txmng_get_fragment_packets(txmngpacket, g_wtp.responsefragmentpacket, g_wtp.fragmentid);
if (g_wtp.responsefragmentpacket->count > 1) {
g_wtp.fragmentid++;
}
/* Free packets manager */
capwap_packet_txmng_free(txmngpacket);
/* Save remote sequence number */
g_wtp.remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
capwap_get_packet_digest(packet->rxmngpacket, packet->connection, g_wtp.lastrecvpackethash);
/* Send Station Configuration response to AC */
if (!capwap_crypt_sendto_fragmentpacket(&g_wtp.ctrldtls, g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], g_wtp.responsefragmentpacket, &g_wtp.wtpctrladdress, &g_wtp.acctrladdress)) {
capwap_logging_debug("Warning: error to send Station Configuration response packet");
}
}
}
/* */
static void receive_ieee80211_wlan_configuration_request(struct capwap_parsed_packet* packet) {
unsigned short binding;
@ -293,7 +334,7 @@ void wtp_dfa_state_run(struct capwap_parsed_packet* packet) {
}
case CAPWAP_STATION_CONFIGURATION_REQUEST: {
/* TODO */
receive_station_configuration_request(packet);
break;
}