Started implementing the packet management of IEEE802.11 by AC side.
Made it clear some constants.
This commit is contained in:
parent
7fd2d4357a
commit
ae97e96f57
@ -52,6 +52,7 @@ ac_SOURCES = \
|
|||||||
$(top_srcdir)/src/ac/ac_execute.c \
|
$(top_srcdir)/src/ac/ac_execute.c \
|
||||||
$(top_srcdir)/src/ac/ac_session.c \
|
$(top_srcdir)/src/ac/ac_session.c \
|
||||||
$(top_srcdir)/src/ac/ac_session_data.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_ieee80211_data.c \
|
||||||
$(top_srcdir)/src/ac/ac_discovery.c \
|
$(top_srcdir)/src/ac/ac_discovery.c \
|
||||||
$(top_srcdir)/src/ac/ac_80211_json.c \
|
$(top_srcdir)/src/ac/ac_80211_json.c \
|
||||||
|
@ -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));
|
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 */
|
/* Alloc AC */
|
||||||
static int ac_init(void) {
|
static int ac_init(void) {
|
||||||
g_ac.standalone = 1;
|
g_ac.standalone = 1;
|
||||||
@ -79,7 +74,8 @@ static int ac_init(void) {
|
|||||||
capwap_rwlock_init(&g_ac.sessionslock);
|
capwap_rwlock_init(&g_ac.sessionslock);
|
||||||
|
|
||||||
/* Stations */
|
/* 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 */
|
/* Backend */
|
||||||
g_ac.availablebackends = capwap_array_create(sizeof(struct ac_http_soap_server*), 0, 0);
|
g_ac.availablebackends = capwap_array_create(sizeof(struct ac_http_soap_server*), 0, 0);
|
||||||
@ -121,6 +117,7 @@ static void ac_destroy(void) {
|
|||||||
|
|
||||||
/* Stations */
|
/* Stations */
|
||||||
capwap_hash_free(g_ac.stations);
|
capwap_hash_free(g_ac.stations);
|
||||||
|
capwap_rwlock_destroy(&g_ac.stationslock);
|
||||||
|
|
||||||
/* Backend */
|
/* Backend */
|
||||||
if (g_ac.backendacid) {
|
if (g_ac.backendacid) {
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
/* */
|
/* */
|
||||||
#define AC_STATIONS_HASH_SIZE 65536
|
#define AC_STATIONS_HASH_SIZE 65536
|
||||||
#define AC_STATIONS_KEY_SIZE ETH_ALEN
|
#define AC_STATIONS_KEY_SIZE MACADDRESS_EUI48_LENGTH
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
struct ac_state {
|
struct ac_state {
|
||||||
@ -99,6 +99,7 @@ struct ac_t {
|
|||||||
|
|
||||||
/* Stations */
|
/* Stations */
|
||||||
struct capwap_hash* stations;
|
struct capwap_hash* stations;
|
||||||
|
capwap_rwlock_t stationslock;
|
||||||
|
|
||||||
/* Dtls */
|
/* Dtls */
|
||||||
int enabledtls;
|
int enabledtls;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include "ac.h"
|
#include "ac.h"
|
||||||
#include "capwap_dfa.h"
|
#include "capwap_dfa.h"
|
||||||
#include "capwap_array.h"
|
#include "capwap_array.h"
|
||||||
|
#include "capwap_array.h"
|
||||||
#include "ac_session.h"
|
#include "ac_session.h"
|
||||||
|
#include "ac_wlans.h"
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int receive_echo_request(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
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;
|
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) {
|
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;
|
struct capwap_resultcode_element* resultcode;
|
||||||
|
|
||||||
/* Check the success of the Request */
|
/* Check the success of the Request */
|
||||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
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);
|
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);
|
sizedata = itempacket->itemsize - sizeof(struct ac_discovery_packet);
|
||||||
|
|
||||||
/* Accept only discovery request don't fragment */
|
/* 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) {
|
if (capwap_packet_rxmng_add_recv_packet(rxmngpacket, acpacket->data, sizedata) == CAPWAP_RECEIVE_COMPLETE_PACKET) {
|
||||||
/* Validate message */
|
/* Validate message */
|
||||||
if (capwap_check_message_type(rxmngpacket) == VALID_MESSAGE_TYPE) {
|
if (capwap_check_message_type(rxmngpacket) == VALID_MESSAGE_TYPE) {
|
||||||
/* Parsing packet */
|
/* Parsing packet */
|
||||||
if (!capwap_parsing_packet(rxmngpacket, NULL, &packet)) {
|
if (capwap_parsing_packet(rxmngpacket, NULL, &packet) == PARSING_COMPLETE) {
|
||||||
/* Validate packet */
|
/* Validate packet */
|
||||||
if (!capwap_validate_parsed_packet(&packet, NULL)) {
|
if (!capwap_validate_parsed_packet(&packet, NULL)) {
|
||||||
struct capwap_packet_txmng* txmngpacket;
|
struct capwap_packet_txmng* txmngpacket;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "ac_session.h"
|
#include "ac_session.h"
|
||||||
#include "ac_discovery.h"
|
#include "ac_discovery.h"
|
||||||
#include "ac_backend.h"
|
#include "ac_backend.h"
|
||||||
|
#include "ac_wlans.h"
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
@ -501,6 +502,9 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
|
|||||||
session->count = 2;
|
session->count = 2;
|
||||||
capwap_event_init(&session->changereference);
|
capwap_event_init(&session->changereference);
|
||||||
|
|
||||||
|
/* */
|
||||||
|
session->wlans = ac_wlans_init();
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
session->timeout = capwap_timeout_init();
|
session->timeout = capwap_timeout_init();
|
||||||
session->idtimercontrol = capwap_timeout_createtimer(session->timeout);
|
session->idtimercontrol = capwap_timeout_createtimer(session->timeout);
|
||||||
|
@ -3,8 +3,165 @@
|
|||||||
#include "ieee80211.h"
|
#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(sessiondata != NULL);
|
||||||
ASSERT(buffer != 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 "capwap_dfa.h"
|
||||||
#include "ac_session.h"
|
#include "ac_session.h"
|
||||||
#include "ac_backend.h"
|
#include "ac_backend.h"
|
||||||
|
#include "ac_wlans.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#define AC_ERROR_TIMEOUT -1000
|
#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);
|
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));
|
memset(&addwlan, 0, sizeof(struct capwap_80211_addwlan_element));
|
||||||
addwlan.radioid = notify->radioid;
|
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));
|
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->changereference);
|
||||||
capwap_event_destroy(&session->waitpacket);
|
capwap_event_destroy(&session->waitpacket);
|
||||||
@ -497,7 +508,7 @@ static void ac_session_run(struct ac_session_t* session) {
|
|||||||
|
|
||||||
/* Defragment management */
|
/* Defragment management */
|
||||||
if (!session->rxmngpacket) {
|
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 */
|
/* If request, defragmentation packet */
|
||||||
|
@ -92,6 +92,9 @@ struct ac_session_t {
|
|||||||
long count;
|
long count;
|
||||||
capwap_event_t changereference;
|
capwap_event_t changereference;
|
||||||
|
|
||||||
|
/* WLAN Reference */
|
||||||
|
struct ac_wlans* wlans;
|
||||||
|
|
||||||
/* Soap */
|
/* Soap */
|
||||||
struct ac_http_soap_request* soaprequest;
|
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_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_release_reference(struct ac_session_data_t* sessiondata);
|
||||||
|
|
||||||
/* IEEE802.11 Data Packet */
|
/* IEEE802.11 Packet */
|
||||||
void ac_ieee80211_data(struct ac_session_data_t* sessiondata, uint8_t* buffer, int length);
|
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);
|
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 */
|
/* Defragment management */
|
||||||
if (!sessiondata->rxmngpacket) {
|
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 */
|
/* If request, defragmentation packet */
|
||||||
@ -368,8 +368,8 @@ static void ac_session_data_run(struct ac_session_data_t* sessiondata) {
|
|||||||
/* Parsing body packet */
|
/* Parsing body packet */
|
||||||
if (bodypacketlength > 0) {
|
if (bodypacketlength > 0) {
|
||||||
binding = GET_WBID_HEADER(sessiondata->rxmngpacket->header);
|
binding = GET_WBID_HEADER(sessiondata->rxmngpacket->header);
|
||||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
if ((binding == CAPWAP_WIRELESS_BINDING_IEEE80211) && (bodypacketlength >= sizeof(struct ieee80211_header))) {
|
||||||
ac_ieee80211_data(sessiondata, bodypacket, bodypacketlength);
|
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__ */
|
@ -2586,7 +2586,7 @@ static int nl80211_wlan_startap(wifi_wlan_handle handle, struct wlan_startap_par
|
|||||||
|
|
||||||
/* Configuration complete */
|
/* Configuration complete */
|
||||||
wlanhandle->devicehandle->wlanactive++;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -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->radioid);
|
||||||
func->write_u8(handle, element->wlanid);
|
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 */
|
/* Retrieve data */
|
||||||
func->read_u8(handle, &data->radioid);
|
func->read_u8(handle, &data->radioid);
|
||||||
func->read_u8(handle, &data->wlanid);
|
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;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,10 @@
|
|||||||
|
|
||||||
#define CAPWAP_ELEMENT_80211_ASSIGN_BSSID 1026
|
#define CAPWAP_ELEMENT_80211_ASSIGN_BSSID 1026
|
||||||
|
|
||||||
#define CAPWAP_ASSIGN_BSSID_LENGTH 6
|
|
||||||
|
|
||||||
struct capwap_80211_assignbssid_element {
|
struct capwap_80211_assignbssid_element {
|
||||||
uint8_t radioid;
|
uint8_t radioid;
|
||||||
uint8_t wlanid;
|
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;
|
extern struct capwap_message_elements_ops capwap_element_80211_assignbssid_ops;
|
||||||
|
@ -57,7 +57,7 @@ static void* capwap_80211_updatestationqos_element_parsing(capwap_message_elemen
|
|||||||
|
|
||||||
/* Retrieve data */
|
/* Retrieve data */
|
||||||
func->read_u8(handle, &data->radioid);
|
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++) {
|
for (i = 0; i < CAPWAP_UPDATE_STATION_QOS_SUBELEMENTS; i++) {
|
||||||
func->read_u8(handle, &data->qos[i].priority8021p);
|
func->read_u8(handle, &data->qos[i].priority8021p);
|
||||||
data->qos[i].priority8021p &= CAPWAP_UPDATE_STATION_QOS_PRIORIY_MASK;
|
data->qos[i].priority8021p &= CAPWAP_UPDATE_STATION_QOS_PRIORIY_MASK;
|
||||||
|
@ -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) {
|
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(hash != NULL);
|
||||||
ASSERT(item_foreach != NULL);
|
ASSERT(item_foreach != NULL);
|
||||||
ASSERT(item != 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 (!item_foreach(item->key, hash->keysize, item->data, param)) {
|
||||||
if (!result) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
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]);
|
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) {
|
} 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 (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) {
|
if (sscanf(buffer, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddress[0], &macaddress[1], &macaddress[2], &macaddress[3], &macaddress[4], &macaddress[5]) != 6) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -8,11 +8,6 @@
|
|||||||
#define CAPWAP_CONTROL_PORT 5246
|
#define CAPWAP_CONTROL_PORT 5246
|
||||||
#define CAPWAP_MAX_PACKET_SIZE 65535
|
#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 */
|
/* 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_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) { \
|
#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);
|
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);
|
char* capwap_printf_macaddress(char* buffer, const uint8_t* macaddress, int type);
|
||||||
int capwap_scanf_macaddress(unsigned char* macaddress, const char* buffer, int type);
|
int capwap_scanf_macaddress(uint8_t* macaddress, const char* buffer, int type);
|
||||||
|
|
||||||
#endif /* __CAPWAP_NETWORK_HEADER__ */
|
#endif /* __CAPWAP_NETWORK_HEADER__ */
|
||||||
|
@ -208,7 +208,7 @@ void capwap_header_set_radio_macaddress(struct capwap_header_data* data, int rad
|
|||||||
ASSERT(data != NULL);
|
ASSERT(data != NULL);
|
||||||
|
|
||||||
header = (struct capwap_header*)&data->headerbuffer[0];
|
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_M_HEADER(header)) {
|
||||||
if (!IS_FLAG_W_HEADER(header)) {
|
if (!IS_FLAG_W_HEADER(header)) {
|
||||||
SET_HLEN_HEADER(header, sizeof(struct capwap_header) / 4);
|
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;
|
int size = sizeof(struct capwap_header) / 4;
|
||||||
|
|
||||||
ASSERT(macaddress != NULL);
|
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)) {
|
if (IS_FLAG_M_HEADER(header)) {
|
||||||
radio = GET_RADIO_MAC_ADDRESS_STRUCT(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 */
|
/* 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*/
|
/* Radio mac address size*/
|
||||||
@ -1001,6 +1001,45 @@ int capwap_packet_rxmng_add_recv_packet(struct capwap_packet_rxmng* rxmngpacket,
|
|||||||
return CAPWAP_WRONG_FRAGMENT;
|
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) {
|
void capwap_packet_rxmng_free(struct capwap_packet_rxmng* rxmngpacket) {
|
||||||
if (rxmngpacket) {
|
if (rxmngpacket) {
|
||||||
|
@ -107,10 +107,16 @@ struct capwap_packet_rxmng {
|
|||||||
#define CAPWAP_REQUEST_MORE_FRAGMENT 0
|
#define CAPWAP_REQUEST_MORE_FRAGMENT 0
|
||||||
#define CAPWAP_RECEIVE_COMPLETE_PACKET 1
|
#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);
|
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);
|
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);
|
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);
|
int capwap_is_request_type(unsigned long type);
|
||||||
|
|
||||||
|
@ -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 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
|
#define MACADDRESS_EUI48_LENGTH 6
|
||||||
struct capwap_macaddress_eui48 {
|
struct capwap_macaddress_eui48 {
|
||||||
|
@ -22,13 +22,13 @@ static struct capwap_packet_rxmng* wtp_get_packet_rxmng(int isctrlmsg) {
|
|||||||
|
|
||||||
if (isctrlmsg) {
|
if (isctrlmsg) {
|
||||||
if (!g_wtp.rxmngctrlpacket) {
|
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;
|
rxmngpacket = g_wtp.rxmngctrlpacket;
|
||||||
} else {
|
} else {
|
||||||
if (!g_wtp.rxmngdatapacket) {
|
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;
|
rxmngpacket = g_wtp.rxmngdatapacket;
|
||||||
|
@ -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) {
|
static void receive_ieee80211_wlan_configuration_request(struct capwap_parsed_packet* packet) {
|
||||||
unsigned short binding;
|
unsigned short binding;
|
||||||
@ -293,7 +334,7 @@ void wtp_dfa_state_run(struct capwap_parsed_packet* packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CAPWAP_STATION_CONFIGURATION_REQUEST: {
|
case CAPWAP_STATION_CONFIGURATION_REQUEST: {
|
||||||
/* TODO */
|
receive_station_configuration_request(packet);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user