Improved handling of message elements parsed. Reduces the memory occupied but

it introduces a small overhead in retrieving of message elements parsed.
This commit is contained in:
vemax78 2013-06-09 17:41:52 +02:00
parent d9e02ded5a
commit 794a8e72d2
88 changed files with 1323 additions and 1027 deletions

View File

@ -23,7 +23,7 @@ static int ac_init(void) {
g_ac.net.bind_sock_ctrl_port = CAPWAP_CONTROL_PORT;
/* Standard name */
strcpy((char*)g_ac.acname.name, AC_STANDARD_NAME);
g_ac.acname.name = (uint8_t*)capwap_duplicate_string(AC_STANDARD_NAME);
/* Descriptor */
g_ac.descriptor.stationlimit = AC_DEFAULT_MAXSTATION;
@ -65,12 +65,24 @@ static int ac_init(void) {
/* Destroy AC */
static void ac_destroy(void) {
int i;
/* Dtls */
capwap_crypt_freecontext(&g_ac.dtlscontext);
/* */
for (i = 0; i < g_ac.descriptor.descsubelement->count; i++) {
struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(g_ac.descriptor.descsubelement, i);
if (desc->data) {
capwap_free(desc->data);
}
}
/* */
capwap_array_free(g_ac.descriptor.descsubelement);
capwap_array_free(g_ac.binding);
capwap_free(g_ac.acname.name);
/* */
capwap_array_free(g_ac.dfa.acipv4list.addresses);
@ -153,7 +165,8 @@ static int ac_parsing_configuration_1_0(config_t* config) {
return 0;
}
strcpy((char*)g_ac.acname.name, configString);
capwap_free(g_ac.acname.name);
g_ac.acname.name = (uint8_t*)capwap_duplicate_string(configString);
}
/* Set binding of AC */
@ -267,7 +280,9 @@ static int ac_parsing_configuration_1_0(config_t* config) {
desc->vendor = (unsigned long)configVendor;
desc->type = type;
desc->length = lengthValue;
desc->data = (uint8_t*)capwap_alloc(desc->length + 1);
strcpy((char*)desc->data, configValue);
desc->data[desc->length] = 0;
} else {
capwap_logging_error("Invalid configuration file, application.descriptor.info.value string length exceeded");
return 0;

View File

@ -7,6 +7,7 @@
int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
unsigned long i;
unsigned short binding;
struct capwap_array* radioadmstate;
struct capwap_header_data capwapheader;
struct capwap_packet_txmng* txmngpacket;
int status = AC_DFA_ACCEPT_PACKET;
@ -24,9 +25,10 @@ int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_parsed_pa
/* Add message element */
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TIMERS, &session->dfa.timers);
for (i = 0; i < packet->messageelements.radioadmstate->count; i++) {
radioadmstate = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RADIOADMSTATE);
for (i = 0; i < radioadmstate->count; i++) {
struct capwap_decrypterrorreportperiod_element report;
struct capwap_radioadmstate_element* radioadm = *(struct capwap_radioadmstate_element**)capwap_array_get_item_pointer(packet->messageelements.radioadmstate, i);
struct capwap_radioadmstate_element* radioadm = *(struct capwap_radioadmstate_element**)capwap_array_get_item_pointer(radioadmstate, i);
report.radioid = radioadm->radioid;
report.interval = session->dfa.decrypterrorreport_interval;

View File

@ -67,7 +67,7 @@ int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_pa
if (packet) {
/* Wait Data Channel Keep-Alive packet */
if (!packet->rxmngpacket->isctrlpacket && IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
if (!memcmp(packet->messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
if (!memcmp(capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID), &session->sessionid, sizeof(struct capwap_sessionid_element))) {
int result = 0;
/* Build packet */

View File

@ -23,7 +23,7 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet*
resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
/* Get sessionid */
memcpy(&session->sessionid, packet->messageelements.sessionid, sizeof(struct capwap_sessionid_element));
memcpy(&session->sessionid, capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID), sizeof(struct capwap_sessionid_element));
/* Get binding */
session->binding = binding;
@ -52,10 +52,12 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet*
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_ac.acname);
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
for (i = 0; i < packet->messageelements.ieee80211.wtpradioinformation->count; i++) {
struct capwap_array* wtpradioinformation = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
for (i = 0; i < wtpradioinformation->count; i++) {
struct capwap_80211_wtpradioinformation_element* radio;
radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(packet->messageelements.ieee80211.wtpradioinformation, i);
radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(wtpradioinformation, i);
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, radio);
}
}

View File

@ -137,7 +137,7 @@ int ac_dfa_state_run(struct ac_session_t* session, struct capwap_parsed_packet*
}
} else {
if (IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
if (!memcmp(packet->messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
if (!memcmp(capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID), &session->sessionid, sizeof(struct capwap_sessionid_element))) {
if (ac_send_data_keepalive(session, packet)) {
ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
status = AC_DFA_NO_PACKET;

View File

@ -115,10 +115,12 @@ static struct capwap_packet_txmng* ac_create_discovery_response(struct capwap_pa
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACDESCRIPTION, &g_ac.descriptor);
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_ac.acname);
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
for (i = 0; i < packet->messageelements.ieee80211.wtpradioinformation->count; i++) {
struct capwap_array* wtpradioinformation = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION);
for (i = 0; i < wtpradioinformation->count; i++) {
struct capwap_80211_wtpradioinformation_element* radio;
radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(packet->messageelements.ieee80211.wtpradioinformation, i);
radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(wtpradioinformation, i);
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, radio);
}
}

View File

@ -87,8 +87,7 @@ static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buff
/* Validate packet */
if (!capwap_validate_parsed_packet(&packet, NULL)) {
struct capwap_list_item* search;
ASSERT(packet.messageelements.sessionid != NULL);
struct capwap_sessionid_element* sessionid = (struct capwap_sessionid_element*)capwap_get_message_element_data(&packet, CAPWAP_ELEMENT_SESSIONID);
capwap_lock_enter(&g_ac.sessionslock);
@ -98,7 +97,7 @@ static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buff
ASSERT(session != NULL);
if (!memcmp(packet.messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
if (!memcmp(sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
session->count++;
result = session;
break;

View File

@ -3,35 +3,42 @@
#include "capwap_protocol.h"
#include "capwap_array.h"
/* Helper create parsed message element */
#define PARSING_MESSAGE_ELEMENT(data) \
if (data) { return 1; } \
data = read_ops->parsing_message_element((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops); \
if (!data) { return 1; }
#define CAPWAP_MESSAGE_ELEMENT_SINGLE 0
#define CAPWAP_MESSAGE_ELEMENT_ARRAY 1
#define ARRAY_PARSING_MESSAGE_ELEMENT(data, type) \
type msgelement; \
if (!data) { data = capwap_array_create(sizeof(type), 0, 0); } \
msgelement = read_ops->parsing_message_element((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops); \
if (!msgelement) { return 1; } \
memcpy(capwap_array_get_item_pointer(data, data->count), &msgelement, sizeof(type));
/* Helper free parsed message element */
#define FREE_PARSED_MESSAGE_ELEMENT(type, data) \
if (data) { \
capwap_get_message_element_ops(type)->free_parsed_message_element(data); \
data = NULL; \
/* */
static int capwap_get_message_element_category(uint16_t type) {
switch (type) {
case CAPWAP_ELEMENT_ACNAMEPRIORITY:
case CAPWAP_ELEMENT_CONTROLIPV4:
case CAPWAP_ELEMENT_CONTROLIPV6:
case CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD:
case CAPWAP_ELEMENT_RADIOADMSTATE:
case CAPWAP_ELEMENT_RADIOOPRSTATE:
case CAPWAP_ELEMENT_RETURNEDMESSAGE:
case CAPWAP_ELEMENT_80211_ANTENNA:
case CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL:
case CAPWAP_ELEMENT_80211_MACOPERATION:
case CAPWAP_ELEMENT_80211_MIC_COUNTERMEASURES:
case CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY:
case CAPWAP_ELEMENT_80211_OFDMCONTROL:
case CAPWAP_ELEMENT_80211_RATESET:
case CAPWAP_ELEMENT_80211_STATION:
case CAPWAP_ELEMENT_80211_STATION_QOS_PROFILE:
case CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE:
case CAPWAP_ELEMENT_80211_STATISTICS:
case CAPWAP_ELEMENT_80211_SUPPORTEDRATES:
case CAPWAP_ELEMENT_80211_TXPOWER:
case CAPWAP_ELEMENT_80211_TXPOWERLEVEL:
case CAPWAP_ELEMENT_80211_WTP_QOS:
case CAPWAP_ELEMENT_80211_WTP_RADIO_CONF:
case CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION: {
return CAPWAP_MESSAGE_ELEMENT_ARRAY;
}
}
#define FREE_ARRAY_PARSED_MESSAGE_ELEMENT(type, data) \
if (data) { \
unsigned long i; \
for (i = 0; i < data->count; i++) { \
capwap_get_message_element_ops(type)->free_parsed_message_element(*(void**)capwap_array_get_item_pointer(data, i)); \
} \
capwap_array_free(data); \
data = NULL; \
}
return CAPWAP_MESSAGE_ELEMENT_SINGLE;
}
/* */
static struct capwap_message_elements_ops* capwap_message_elements[CAPWAP_MESSAGE_ELEMENTS_COUNT] = {
@ -130,6 +137,46 @@ struct capwap_message_elements_ops* capwap_get_message_element_ops(unsigned shor
return NULL;
}
/* */
struct capwap_list_item* capwap_get_message_element(struct capwap_parsed_packet* packet, uint16_t type) {
struct capwap_list_item* search;
ASSERT(packet != NULL);
ASSERT(packet->messages != NULL);
search = packet->messages->first;
while (search) {
struct capwap_message_element_itemlist* messageelement = (struct capwap_message_element_itemlist*)search->item;
if (messageelement->type == type) {
return search;
}
/* */
search = search->next;
}
return NULL;
}
/* */
void* capwap_get_message_element_data(struct capwap_parsed_packet* packet, uint16_t type) {
struct capwap_list_item* itemlist;
struct capwap_message_element_itemlist* messageelement;
/* Retrieve item list */
itemlist = capwap_get_message_element(packet, type);
if (!itemlist) {
return NULL;
}
/* Get message element info */
messageelement = (struct capwap_message_element_itemlist*)itemlist->item;
ASSERT(messageelement != NULL);
return messageelement->data;
}
/* */
int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, struct capwap_parsed_packet* packet) {
unsigned short binding;
@ -141,6 +188,7 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
memset(packet, 0, sizeof(struct capwap_parsed_packet));
packet->rxmngpacket = rxmngpacket;
packet->connection = connection;
packet->messages = capwap_list_create();
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
@ -152,6 +200,9 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
while (bodylength > 0) {
uint16_t type;
uint16_t msglength;
int category;
struct capwap_list_item* itemlist;
struct capwap_message_element_itemlist* messageelement;
struct capwap_message_elements_ops* read_ops;
/* Get type and length */
@ -160,6 +211,7 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
/* TODO */
return 1;
}
if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &msglength) != sizeof(uint16_t)) {
/* TODO */
return 1;
@ -171,255 +223,73 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
return 1;
}
/* */
/* Check binding */
if (IS_80211_MESSAGE_ELEMENTS(type) && (binding != CAPWAP_WIRELESS_BINDING_IEEE80211)) {
/* TODO */
return 1;
}
/* Reader function */
read_ops = capwap_get_message_element_ops(type);
if (!read_ops) {
/* TODO */
return 1;
}
/* Allowed to parsing only the size of message element */
rxmngpacket->readerpacketallowed = msglength;
if (IS_MESSAGE_ELEMENTS(type) && read_ops) {
/* Parsing standard message element */
switch (type) {
case CAPWAP_ELEMENT_ACDESCRIPTION: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.acdescriptor);
break;
}
case CAPWAP_ELEMENT_ACIPV4LIST: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.acipv4list);
break;
}
case CAPWAP_ELEMENT_ACIPV6LIST: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.acipv6list);
break;
}
case CAPWAP_ELEMENT_ACNAME: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.acname);
break;
}
case CAPWAP_ELEMENT_ACNAMEPRIORITY: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.acnamepriority, struct capwap_acnamepriority_element*);
break;
}
case CAPWAP_ELEMENT_CONTROLIPV4: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.controlipv4, struct capwap_controlipv4_element*);
break;
}
case CAPWAP_ELEMENT_CONTROLIPV6: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.controlipv6, struct capwap_controlipv6_element*);
break;
}
case CAPWAP_ELEMENT_TIMERS: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.timers);
break;
}
case CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.decrypterrorreportperiod, struct capwap_decrypterrorreportperiod_element*);
break;
}
case CAPWAP_ELEMENT_DISCOVERYTYPE: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.discoverytype);
break;
}
case CAPWAP_ELEMENT_IDLETIMEOUT: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.idletimeout);
break;
}
case CAPWAP_ELEMENT_IMAGEIDENTIFIER: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.imageidentifier);
break;
}
case CAPWAP_ELEMENT_LOCATION: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.location);
break;
}
case CAPWAP_ELEMENT_MAXIMUMLENGTH: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.maximumlength);
break;
}
case CAPWAP_ELEMENT_LOCALIPV4: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.localipv4);
break;
}
case CAPWAP_ELEMENT_RADIOADMSTATE: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.radioadmstate, struct capwap_radioadmstate_element*);
break;
}
case CAPWAP_ELEMENT_RADIOOPRSTATE: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.radiooprstate, struct capwap_radiooprstate_element*);
break;
}
case CAPWAP_ELEMENT_RESULTCODE: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.resultcode);
break;
}
case CAPWAP_ELEMENT_RETURNEDMESSAGE: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.returnedmessage, struct capwap_returnedmessage_element*);
break;
}
case CAPWAP_ELEMENT_SESSIONID: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.sessionid);
break;
}
case CAPWAP_ELEMENT_STATISTICSTIMER: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.statisticstimer);
break;
}
case CAPWAP_ELEMENT_VENDORPAYLOAD: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.vendorpayload);
break;
}
case CAPWAP_ELEMENT_WTPBOARDDATA: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtpboarddata);
break;
}
case CAPWAP_ELEMENT_WTPDESCRIPTOR: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtpdescriptor);
break;
}
case CAPWAP_ELEMENT_WTPFALLBACK: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtpfallback);
break;
}
case CAPWAP_ELEMENT_WTPFRAMETUNNELMODE: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtpframetunnel);
break;
}
case CAPWAP_ELEMENT_WTPMACTYPE: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtpmactype);
break;
}
case CAPWAP_ELEMENT_WTPNAME: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtpname);
break;
}
case CAPWAP_ELEMENT_WTPREBOOTSTAT: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtprebootstat);
break;
}
case CAPWAP_ELEMENT_WTPSTATICIPADDRESS: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.wtpstaticipaddress);
break;
}
case CAPWAP_ELEMENT_LOCALIPV6: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.localipv6);
break;
}
case CAPWAP_ELEMENT_TRANSPORT: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.transport);
break;
}
case CAPWAP_ELEMENT_MTUDISCOVERY: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.mtudiscovery);
break;
}
case CAPWAP_ELEMENT_ECNSUPPORT: {
PARSING_MESSAGE_ELEMENT(packet->messageelements.ecnsupport);
break;
}
default: {
/* TODO */
return 1;
}
}
} else if (IS_80211_MESSAGE_ELEMENTS(type) && read_ops) {
if (binding != CAPWAP_WIRELESS_BINDING_IEEE80211) {
/* TODO */
/* */
itemlist = capwap_get_message_element(packet, type);
category = capwap_get_message_element_category(type);
if (category == CAPWAP_MESSAGE_ELEMENT_SINGLE) {
/* Check for multiple message element */
if (itemlist) {
return 1;
}
/* Parsing ieee80211 message element */
switch (type) {
case CAPWAP_ELEMENT_80211_ANTENNA: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.antenna, struct capwap_80211_antenna_element*);
break;
}
case CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.directsequencecontrol, struct capwap_80211_directsequencecontrol_element*);
break;
}
case CAPWAP_ELEMENT_80211_MACOPERATION: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.macoperation, struct capwap_80211_macoperation_element*);
break;
}
case CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.multidomaincapability, struct capwap_80211_multidomaincapability_element*);
break;
}
case CAPWAP_ELEMENT_80211_OFDMCONTROL: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.ofdmcontrol, struct capwap_80211_ofdmcontrol_element*);
break;
}
case CAPWAP_ELEMENT_80211_RATESET: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.rateset, struct capwap_80211_rateset_element*);
break;
}
case CAPWAP_ELEMENT_80211_SUPPORTEDRATES: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.supportedrates, struct capwap_80211_supportedrates_element*);
break;
}
case CAPWAP_ELEMENT_80211_TXPOWER: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.txpower, struct capwap_80211_txpower_element*);
break;
}
case CAPWAP_ELEMENT_80211_TXPOWERLEVEL: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.txpowerlevel, struct capwap_80211_txpowerlevel_element*);
break;
}
case CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION: {
ARRAY_PARSING_MESSAGE_ELEMENT(packet->messageelements.ieee80211.wtpradioinformation, struct capwap_80211_wtpradioinformation_element*);
break;
}
default: {
/* TODO */
return 1;
}
/* Create new message element */
itemlist = capwap_itemlist_create(sizeof(struct capwap_message_element_itemlist));
messageelement = (struct capwap_message_element_itemlist*)itemlist->item;
messageelement->type = type;
messageelement->category = CAPWAP_MESSAGE_ELEMENT_SINGLE;
messageelement->data = read_ops->parsing_message_element((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops);
if (!messageelement->data) {
capwap_itemlist_free(itemlist);
return 1;
}
} else {
/* TODO */
return 1;
/* */
capwap_itemlist_insert_after(packet->messages, NULL, itemlist);
} else if (category == CAPWAP_MESSAGE_ELEMENT_ARRAY) {
void* datamsgelement;
struct capwap_array* arraymessageelement;
if (itemlist) {
messageelement = (struct capwap_message_element_itemlist*)itemlist->item;
arraymessageelement = (struct capwap_array*)messageelement->data;
} else {
arraymessageelement = capwap_array_create(sizeof(void*), 0, 0);
/* */
itemlist = capwap_itemlist_create(sizeof(struct capwap_message_element_itemlist));
messageelement = (struct capwap_message_element_itemlist*)itemlist->item;
messageelement->type = type;
messageelement->category = CAPWAP_MESSAGE_ELEMENT_ARRAY;
messageelement->data = (void*)arraymessageelement;
/* */
capwap_itemlist_insert_after(packet->messages, NULL, itemlist);
}
/* Get message element */
datamsgelement = read_ops->parsing_message_element((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops);
if (!datamsgelement) {
return 1;
}
/* */
memcpy(capwap_array_get_item_pointer(arraymessageelement, arraymessageelement->count), &datamsgelement, sizeof(void*));
}
/* Check if read all data of message element */
@ -434,6 +304,8 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
} else if (IS_FLAG_K_HEADER(rxmngpacket->header)) {
uint16_t type;
uint16_t msglength;
struct capwap_list_item* itemlist;
struct capwap_message_element_itemlist* messageelement;
struct capwap_message_elements_ops* read_ops;
unsigned short bodylength = rxmngpacket->datamsg.length - CAPWAP_DATA_MESSAGE_KEEPALIVE_MIN_LENGTH;
@ -457,11 +329,18 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
/* Retrieve session id */
read_ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_SESSIONID);
packet->messageelements.sessionid = read_ops->parsing_message_element((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops);
if (!packet->messageelements.sessionid) {
/* TODO */
itemlist = capwap_itemlist_create(sizeof(struct capwap_message_element_itemlist));
messageelement = (struct capwap_message_element_itemlist*)itemlist->item;
messageelement->type = CAPWAP_ELEMENT_SESSIONID;
messageelement->category = CAPWAP_MESSAGE_ELEMENT_SINGLE;
messageelement->data = read_ops->parsing_message_element((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops);
if (!messageelement->data) {
capwap_itemlist_free(itemlist);
return 1;
}
/* */
capwap_itemlist_insert_after(packet->messages, NULL, itemlist);
}
return 0;
@ -479,14 +358,14 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
if (packet->rxmngpacket->isctrlpacket) {
switch (packet->rxmngpacket->ctrlmsg.type) {
case CAPWAP_DISCOVERY_REQUEST: {
if (packet->messageelements.discoverytype &&
packet->messageelements.wtpboarddata &&
packet->messageelements.wtpdescriptor &&
packet->messageelements.wtpframetunnel &&
packet->messageelements.wtpmactype) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DISCOVERYTYPE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPBOARDDATA) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPDESCRIPTOR) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPMACTYPE)) {
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
if (packet->messageelements.ieee80211.wtpradioinformation) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
return 0;
}
} else {
@ -498,12 +377,12 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_DISCOVERY_RESPONSE: {
if (packet->messageelements.acdescriptor &&
packet->messageelements.acname &&
(packet->messageelements.controlipv4 || packet->messageelements.controlipv6)) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACDESCRIPTION) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) &&
(capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV6))) {
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
if (packet->messageelements.ieee80211.wtpradioinformation) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
return 0;
}
} else {
@ -515,18 +394,18 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_JOIN_REQUEST: {
if (packet->messageelements.location &&
packet->messageelements.wtpboarddata &&
packet->messageelements.wtpdescriptor &&
packet->messageelements.wtpname &&
packet->messageelements.sessionid &&
packet->messageelements.wtpframetunnel &&
packet->messageelements.wtpmactype &&
packet->messageelements.ecnsupport &&
(packet->messageelements.localipv4 || packet->messageelements.localipv6)) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCATION) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPBOARDDATA) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPDESCRIPTOR) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPNAME) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_SESSIONID) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPMACTYPE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_ECNSUPPORT) &&
(capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV6))) {
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
if (packet->messageelements.ieee80211.wtpradioinformation) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
return 0;
}
} else {
@ -538,15 +417,15 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_JOIN_RESPONSE: {
if (packet->messageelements.resultcode &&
packet->messageelements.acdescriptor &&
packet->messageelements.acname &&
packet->messageelements.ecnsupport &&
(packet->messageelements.controlipv4 || packet->messageelements.controlipv6) &&
(packet->messageelements.localipv4 || packet->messageelements.localipv6)) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_ACDESCRIPTION) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_ECNSUPPORT) &&
(capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV6)) &&
(capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCALIPV6))) {
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
if (packet->messageelements.ieee80211.wtpradioinformation) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
return 0;
}
} else {
@ -558,13 +437,13 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_CONFIGURATION_STATUS_REQUEST: {
if (packet->messageelements.acname &&
packet->messageelements.radioadmstate &&
packet->messageelements.statisticstimer &&
packet->messageelements.wtprebootstat) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOADMSTATE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_STATISTICSTIMER) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPREBOOTSTAT)) {
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
if (packet->messageelements.ieee80211.wtpradioinformation) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
return 0;
}
} else {
@ -576,11 +455,11 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_CONFIGURATION_STATUS_RESPONSE: {
if (packet->messageelements.timers &&
packet->messageelements.decrypterrorreportperiod &&
packet->messageelements.idletimeout &&
packet->messageelements.wtpfallback &&
(packet->messageelements.acipv4list || packet->messageelements.acipv6list)) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_TIMERS) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_IDLETIMEOUT) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFALLBACK) &&
(capwap_get_message_element(packet, CAPWAP_ELEMENT_ACIPV4LIST) || capwap_get_message_element(packet, CAPWAP_ELEMENT_ACIPV6LIST))) {
return 0;
}
@ -589,21 +468,21 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_CONFIGURATION_UPDATE_REQUEST: {
if (packet->messageelements.acnamepriority ||
//packet->messageelements.actimestamp || TODO
//packet->messageelements.addaclmac || TODO
packet->messageelements.timers ||
packet->messageelements.decrypterrorreportperiod ||
//packet->messageelements.delaclmac || TODO
packet->messageelements.idletimeout ||
packet->messageelements.location ||
packet->messageelements.radioadmstate ||
packet->messageelements.statisticstimer ||
packet->messageelements.wtpfallback ||
packet->messageelements.wtpname ||
packet->messageelements.wtpstaticipaddress ||
packet->messageelements.imageidentifier ||
packet->messageelements.vendorpayload) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAMEPRIORITY) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_ACTIMESTAMP) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_ADDMACACL) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_TIMERS) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETEMACACL) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_IDLETIMEOUT) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_LOCATION) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOADMSTATE) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_STATISTICSTIMER) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFALLBACK) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPNAME) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPSTATICIPADDRESS) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_IMAGEIDENTIFIER) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_VENDORPAYLOAD)) {
return 0;
}
@ -616,13 +495,13 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_WTP_EVENT_REQUEST: {
if (packet->messageelements.decrypterrorreportperiod ||
//packet->messageelements.duplicateipv4 || TODO
//packet->messageelements.duplicateipv6 || TODO
//packet->messageelements.wtpradiostat || TODO
packet->messageelements.wtprebootstat ||
//packet->messageelements.deletestation || TODO
packet->messageelements.vendorpayload) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_DUPLICATEIPV4) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_DUPLICATEIPV6) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPRADIOSTAT) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPREBOOTSTAT) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETESTATION) ||
capwap_get_message_element(packet, CAPWAP_ELEMENT_VENDORPAYLOAD)) {
return 0;
}
@ -635,8 +514,8 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_CHANGE_STATE_EVENT_REQUEST: {
if (packet->messageelements.radiooprstate &&
packet->messageelements.resultcode) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOOPRSTATE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
return 0;
}
@ -661,7 +540,7 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_IMAGE_DATA_RESPONSE: {
if (packet->messageelements.resultcode) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
return 0;
}
@ -669,7 +548,7 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_RESET_REQUEST: {
if (packet->messageelements.imageidentifier) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_IMAGEIDENTIFIER)) {
return 0;
}
@ -681,14 +560,14 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_PRIMARY_DISCOVERY_REQUEST: {
if (packet->messageelements.discoverytype &&
packet->messageelements.wtpboarddata &&
packet->messageelements.wtpdescriptor &&
packet->messageelements.wtpframetunnel &&
packet->messageelements.wtpmactype) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DISCOVERYTYPE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPBOARDDATA) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPDESCRIPTOR) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_WTPMACTYPE)) {
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
if (packet->messageelements.ieee80211.wtpradioinformation) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
return 0;
}
} else {
@ -700,12 +579,12 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_PRIMARY_DISCOVERY_RESPONSE: {
if (packet->messageelements.acdescriptor &&
packet->messageelements.acname &&
(packet->messageelements.controlipv4 || packet->messageelements.controlipv6)) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ACDESCRIPTION) &&
capwap_get_message_element(packet, CAPWAP_ELEMENT_ACNAME) &&
(capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV4) || capwap_get_message_element(packet, CAPWAP_ELEMENT_CONTROLIPV6))) {
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
if (packet->messageelements.ieee80211.wtpradioinformation) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
return 0;
}
} else {
@ -722,7 +601,7 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_DATA_TRANSFER_RESPONSE: {
if (packet->messageelements.resultcode) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
return 0;
}
@ -734,7 +613,7 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_CLEAR_CONFIGURATION_RESPONSE: {
if (packet->messageelements.resultcode) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
return 0;
}
@ -747,7 +626,7 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
case CAPWAP_STATION_CONFIGURATION_RESPONSE: {
if (packet->messageelements.resultcode) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
return 0;
}
@ -756,7 +635,7 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
}
} else if (IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
/* Keep alive data message require session id */
if (packet->messageelements.sessionid) {
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_SESSIONID)) {
return 0;
}
}
@ -766,62 +645,42 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
/* */
void capwap_free_parsed_packet(struct capwap_parsed_packet* packet) {
int i;
struct capwap_list_item* itemlist;
struct capwap_message_element_itemlist* messageelement;
struct capwap_message_elements_ops* msgops;
ASSERT(packet != NULL);
if (packet->rxmngpacket) {
unsigned short binding = GET_WBID_HEADER(packet->rxmngpacket->header);
if (packet->rxmngpacket && packet->messages) {
itemlist = packet->messages->first;
while (itemlist) {
messageelement = (struct capwap_message_element_itemlist*)itemlist->item;
if (messageelement->data) {
msgops = capwap_get_message_element_ops(messageelement->type);
/* */
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_ACDESCRIPTION, packet->messageelements.acdescriptor);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_ACIPV4LIST, packet->messageelements.acipv4list);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_ACIPV6LIST, packet->messageelements.acipv6list);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_ACNAME, packet->messageelements.acname);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_ACNAMEPRIORITY, packet->messageelements.acnamepriority);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_CONTROLIPV4, packet->messageelements.controlipv4);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_CONTROLIPV6, packet->messageelements.controlipv6);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_TIMERS, packet->messageelements.timers);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD, packet->messageelements.decrypterrorreportperiod);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_DISCOVERYTYPE, packet->messageelements.discoverytype);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_IDLETIMEOUT, packet->messageelements.idletimeout);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_IMAGEIDENTIFIER, packet->messageelements.imageidentifier);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_LOCATION, packet->messageelements.location);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_MAXIMUMLENGTH, packet->messageelements.maximumlength);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_LOCALIPV4, packet->messageelements.localipv4);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_RADIOADMSTATE, packet->messageelements.radioadmstate);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_RADIOOPRSTATE, packet->messageelements.radiooprstate);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_RESULTCODE, packet->messageelements.resultcode);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_RETURNEDMESSAGE, packet->messageelements.returnedmessage);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_SESSIONID, packet->messageelements.sessionid);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_STATISTICSTIMER, packet->messageelements.statisticstimer);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_VENDORPAYLOAD, packet->messageelements.vendorpayload);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPBOARDDATA, packet->messageelements.wtpboarddata);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPDESCRIPTOR, packet->messageelements.wtpdescriptor);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPFALLBACK, packet->messageelements.wtpfallback);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPFRAMETUNNELMODE, packet->messageelements.wtpframetunnel);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPMACTYPE, packet->messageelements.wtpmactype);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPNAME, packet->messageelements.wtpname);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPREBOOTSTAT, packet->messageelements.wtprebootstat);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_WTPSTATICIPADDRESS, packet->messageelements.wtpstaticipaddress);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_LOCALIPV6, packet->messageelements.localipv6);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_TRANSPORT, packet->messageelements.transport);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_MTUDISCOVERY, packet->messageelements.mtudiscovery);
FREE_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_ECNSUPPORT, packet->messageelements.ecnsupport);
if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_SINGLE) {
msgops->free_parsed_message_element(messageelement->data);
} else if (messageelement->category == CAPWAP_MESSAGE_ELEMENT_ARRAY) {
struct capwap_array* arraymessageelement = (struct capwap_array*)messageelement->data;
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_ANTENNA, packet->messageelements.ieee80211.antenna);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_DIRECTSEQUENCECONTROL, packet->messageelements.ieee80211.directsequencecontrol);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_MACOPERATION, packet->messageelements.ieee80211.macoperation);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_MULTIDOMAINCAPABILITY, packet->messageelements.ieee80211.multidomaincapability);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_OFDMCONTROL, packet->messageelements.ieee80211.ofdmcontrol);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_RATESET, packet->messageelements.ieee80211.rateset);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_SUPPORTEDRATES, packet->messageelements.ieee80211.supportedrates);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_TXPOWER, packet->messageelements.ieee80211.txpower);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_TXPOWERLEVEL, packet->messageelements.ieee80211.txpowerlevel);
FREE_ARRAY_PARSED_MESSAGE_ELEMENT(CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, packet->messageelements.ieee80211.wtpradioinformation);
for (i = 0; i < arraymessageelement->count; i++) {
msgops->free_parsed_message_element(*(void**)capwap_array_get_item_pointer(arraymessageelement, i));
}
/* */
capwap_array_free(arraymessageelement);
}
}
/* */
itemlist = itemlist->next;
}
/* */
packet->rxmngpacket = NULL;
capwap_list_free(packet->messages);
packet->messages = NULL;
}
/* */

View File

@ -5,21 +5,6 @@
#include "capwap_array.h"
#include "capwap_list.h"
/* Standard message elements 1 -> 52 (1 - 1023) */
#define CAPWAP_MESSAGE_ELEMENTS_START 1
#define CAPWAP_MESSAGE_ELEMENTS_STOP 53
#define CAPWAP_MESSAGE_ELEMENTS_COUNT ((CAPWAP_MESSAGE_ELEMENTS_STOP - CAPWAP_MESSAGE_ELEMENTS_START) + 1)
#define IS_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* 802.11 message elements 1024 -> 1024 (1024 - 2047) */
#define CAPWAP_80211_MESSAGE_ELEMENTS_START 1024
#define CAPWAP_80211_MESSAGE_ELEMENTS_STOP 1048
#define CAPWAP_80211_MESSAGE_ELEMENTS_COUNT ((CAPWAP_80211_MESSAGE_ELEMENTS_STOP - CAPWAP_80211_MESSAGE_ELEMENTS_START) + 1)
#define IS_80211_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_80211_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_80211_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* */
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= 31))
/* */
typedef void* capwap_message_elements_handle;
struct capwap_write_message_elements_ops {
@ -132,66 +117,22 @@ struct capwap_message_elements_ops* capwap_get_message_element_ops(unsigned shor
#include "capwap_element_80211_wtpradioinformation.h" /* 01048 */
/*********************************************************************************************************************/
struct capwap_message_elements {
struct capwap_acdescriptor_element* acdescriptor;
struct capwap_acipv4list_element* acipv4list;
struct capwap_acipv6list_element* acipv6list;
struct capwap_acname_element* acname;
struct capwap_array* acnamepriority;
struct capwap_array* controlipv4;
struct capwap_array* controlipv6;
struct capwap_timers_element* timers;
struct capwap_array* decrypterrorreportperiod;
struct capwap_discoverytype_element* discoverytype;
struct capwap_idletimeout_element* idletimeout;
struct capwap_imageidentifier_element* imageidentifier;
struct capwap_location_element* location;
struct capwap_maximumlength_element* maximumlength;
struct capwap_localipv4_element* localipv4;
struct capwap_array* radioadmstate;
struct capwap_array* radiooprstate;
struct capwap_resultcode_element* resultcode;
struct capwap_array* returnedmessage;
struct capwap_sessionid_element* sessionid;
struct capwap_statisticstimer_element* statisticstimer;
struct capwap_vendorpayload_element* vendorpayload;
struct capwap_wtpboarddata_element* wtpboarddata;
struct capwap_wtpdescriptor_element* wtpdescriptor;
struct capwap_wtpfallback_element* wtpfallback;
struct capwap_wtpframetunnelmode_element* wtpframetunnel;
struct capwap_wtpmactype_element* wtpmactype;
struct capwap_wtpname_element* wtpname;
struct capwap_wtprebootstat_element* wtprebootstat;
struct capwap_wtpstaticipaddress_element* wtpstaticipaddress;
struct capwap_localipv6_element* localipv6;
struct capwap_transport_element* transport;
struct capwap_mtudiscovery_element* mtudiscovery;
struct capwap_ecnsupport_element* ecnsupport;
union {
struct {
struct capwap_array* antenna;
struct capwap_array* directsequencecontrol;
struct capwap_array* macoperation;
struct capwap_array* multidomaincapability;
struct capwap_array* ofdmcontrol;
struct capwap_array* rateset;
struct capwap_array* supportedrates;
struct capwap_array* txpower;
struct capwap_array* txpowerlevel;
struct capwap_array* wtpradioinformation;
} ieee80211;
};
struct capwap_message_element_itemlist {
uint16_t type;
int category;
void* data;
};
struct capwap_parsed_packet {
struct capwap_packet_rxmng* rxmngpacket;
struct capwap_connection* connection;
struct capwap_message_elements messageelements;
struct capwap_list* messages;
};
int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, struct capwap_parsed_packet* packet);
int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct capwap_array* returnedmessage);
void capwap_free_parsed_packet(struct capwap_parsed_packet* packet);
struct capwap_list_item* capwap_get_message_element(struct capwap_parsed_packet* packet, uint16_t type);
void* capwap_get_message_element_data(struct capwap_parsed_packet* packet, uint16_t type);
#endif /* __CAPWAP_ELEMENT_HEADER__ */

View File

@ -27,9 +27,12 @@ Length: >= 20
/* */
static void capwap_80211_addwlan_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
int length;
struct capwap_80211_addwlan_element* element = (struct capwap_80211_addwlan_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
ASSERT(IS_VALID_WLANID(element->wlanid));
func->write_u8(handle, element->radioid);
func->write_u8(handle, element->wlanid);
@ -46,7 +49,11 @@ static void capwap_80211_addwlan_element_create(void* data, capwap_message_eleme
func->write_u8(handle, element->macmode);
func->write_u8(handle, element->tunnelmode);
func->write_u8(handle, element->suppressssid);
func->write_block(handle, element->ssid, element->ssidlength);
length = strlen((char*)element->ssid);
ASSERT((length > 0) && (length <= CAPWAP_ADD_WLAN_SSID_LENGTH));
func->write_block(handle, element->ssid, length);
}
/* */
@ -63,7 +70,7 @@ static void capwap_80211_addwlan_element_free(void* data) {
capwap_free(element->key);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -76,7 +83,7 @@ static void* capwap_80211_addwlan_element_parsing(capwap_message_elements_handle
length = func->read_ready(handle);
if (length < 20) {
capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element");
capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: underbuffer");
return NULL;
}
@ -88,9 +95,19 @@ static void* capwap_80211_addwlan_element_parsing(capwap_message_elements_handle
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_80211_addwlan_element));
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->wlanid);
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_80211_addwlan_element_free((void*)data);
capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: invalid radioid");
return NULL;
} else if (!IS_VALID_WLANID(data->wlanid)) {
capwap_80211_addwlan_element_free((void*)data);
capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: invalid wlanid");
return NULL;
}
func->read_u16(handle, &data->capability);
func->read_u8(handle, &data->keyindex);
func->read_u8(handle, &data->keystatus);
@ -112,16 +129,16 @@ static void* capwap_80211_addwlan_element_parsing(capwap_message_elements_handle
func->read_u8(handle, &data->tunnelmode);
func->read_u8(handle, &data->suppressssid);
data->ssidlength = length - (19 + data->keylength);
if (data->ssidlength > CAPWAP_ADD_WLAN_SSID_LENGTH) {
length -= (19 + data->keylength);
if (!length || (length > CAPWAP_ADD_WLAN_SSID_LENGTH)) {
capwap_80211_addwlan_element_free((void*)data);
capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element");
capwap_logging_debug("Invalid IEEE 802.11 Add WLAN element: invalid ssid");
return NULL;
}
data->ssid = (uint8_t*)capwap_alloc(data->ssidlength + 1);
func->read_block(handle, data->ssid, data->ssidlength);
data->ssid[data->ssidlength] = 0;
data->ssid = (uint8_t*)capwap_alloc(length + 1);
func->read_block(handle, data->ssid, length);
data->ssid[length] = 0;
return data;
}

View File

@ -56,7 +56,6 @@ struct capwap_80211_addwlan_element {
uint8_t macmode;
uint8_t tunnelmode;
uint8_t suppressssid;
uint16_t ssidlength;
uint8_t* ssid;
};

View File

@ -72,7 +72,7 @@ static void capwap_80211_ie_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(element->ie);
capwap_free(element);
capwap_free(data);
}
/* */

View File

@ -85,7 +85,7 @@ static void capwap_80211_stationkey_element_free(void* data) {
capwap_free(element->key);
}
capwap_free(element);
capwap_free(data);
}
/* */

View File

@ -1,7 +1,7 @@
#ifndef __CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_HEADER__
#define __CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_HEADER__
#define CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE 1037
#define CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE 1038
#define CAPWAP_STATION_SESSION_KEY_ADDRESS_LENGTH 6
#define CAPWAP_STATION_SESSION_KEY_PAIRWISE_TSC_LENGTH 6

View File

@ -46,7 +46,7 @@ static void capwap_80211_updatewlan_element_free(void* data) {
capwap_free(element->key);
}
capwap_free(element);
capwap_free(data);
}
/* */

View File

@ -37,6 +37,9 @@ static void capwap_acdescriptor_element_create(void* data, capwap_message_elemen
struct capwap_acdescriptor_element* element = (struct capwap_acdescriptor_element*)data;
ASSERT(data != NULL);
ASSERT(!(element->security & ~CAPWAP_ACDESC_SECURITY_MASK));
ASSERT(!(element->dtlspolicy & ~CAPWAP_ACDESC_DTLS_POLICY_MASK));
ASSERT((element->rmacfield == CAPWAP_ACDESC_RMACFIELD_SUPPORTED) || (element->rmacfield == CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED));
/* */
func->write_u16(handle, element->stations);
@ -52,6 +55,9 @@ static void capwap_acdescriptor_element_create(void* data, capwap_message_elemen
for (i = 0; i < element->descsubelement->count; i++) {
struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
ASSERT(desc->length > 0);
ASSERT(desc->data != NULL);
func->write_u32(handle, desc->vendor);
func->write_u16(handle, desc->type);
func->write_u16(handle, desc->length);
@ -61,13 +67,23 @@ static void capwap_acdescriptor_element_create(void* data, capwap_message_elemen
/* */
static void capwap_acdescriptor_element_free(void* data) {
struct capwap_acdescriptor_element* dataelement = (struct capwap_acdescriptor_element*)data;
int i;
struct capwap_acdescriptor_element* element = (struct capwap_acdescriptor_element*)data;
ASSERT(dataelement != NULL);
ASSERT(dataelement->descsubelement != NULL);
ASSERT(element != NULL);
ASSERT(element->descsubelement != NULL);
capwap_array_free(dataelement->descsubelement);
capwap_free(dataelement);
/* */
for (i = 0; i < element->descsubelement->count; i++) {
struct capwap_acdescriptor_desc_subelement* desc = (struct capwap_acdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
if (desc->data) {
capwap_free(desc->data);
}
}
capwap_array_free(element->descsubelement);
capwap_free(data);
}
/* */
@ -78,7 +94,7 @@ static void* capwap_acdescriptor_element_parsing(capwap_message_elements_handle
ASSERT(func != NULL);
if (func->read_ready(handle) < 12) {
capwap_logging_debug("Invalid AC Descriptor element");
capwap_logging_debug("Invalid AC Descriptor element: underbuffer");
return NULL;
}
@ -98,8 +114,12 @@ static void* capwap_acdescriptor_element_parsing(capwap_message_elements_handle
func->read_u16(handle, &data->maxwtp);
/* Check */
if ((data->stations > data->stationlimit) || (data->activewtp > data->maxwtp)) {
capwap_logging_debug("Invalid AC Descriptor element");
if (data->stations > data->stationlimit) {
capwap_logging_debug("Invalid AC Descriptor element: stations > stationlimit");
capwap_acdescriptor_element_free(data);
return NULL;
} else if (data->activewtp > data->maxwtp) {
capwap_logging_debug("Invalid AC Descriptor element: activewtp > maxwtp");
capwap_acdescriptor_element_free(data);
return NULL;
}
@ -110,6 +130,21 @@ static void* capwap_acdescriptor_element_parsing(capwap_message_elements_handle
func->read_u8(handle, NULL);
func->read_u8(handle, &data->dtlspolicy);
/* */
if (data->security & ~CAPWAP_ACDESC_SECURITY_MASK) {
capwap_logging_debug("Invalid AC Descriptor element: security");
capwap_acdescriptor_element_free(data);
return NULL;
} else if (data->dtlspolicy & ~CAPWAP_ACDESC_DTLS_POLICY_MASK) {
capwap_logging_debug("Invalid AC Descriptor element: dtlspolicy");
capwap_acdescriptor_element_free(data);
return NULL;
} else if ((data->rmacfield != CAPWAP_ACDESC_RMACFIELD_SUPPORTED) && (data->rmacfield != CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED)) {
capwap_logging_debug("Invalid AC Descriptor element: rmacfield");
capwap_acdescriptor_element_free(data);
return NULL;
}
/* Description Subelement */
while (func->read_ready(handle) > 0) {
unsigned short length;
@ -120,15 +155,23 @@ static void* capwap_acdescriptor_element_parsing(capwap_message_elements_handle
func->read_u16(handle, &desc->type);
func->read_u16(handle, &desc->length);
/* Check buffer size */
length = func->read_ready(handle);
if ((length > CAPWAP_ACDESC_SUBELEMENT_MAXDATA) || (length < desc->length)) {
capwap_logging_debug("Invalid AC Descriptor element");
if ((desc->type != CAPWAP_ACDESC_SUBELEMENT_HARDWAREVERSION) && (desc->type != CAPWAP_ACDESC_SUBELEMENT_SOFTWAREVERSION)) {
capwap_logging_debug("Invalid AC Descriptor subelement: type");
capwap_acdescriptor_element_free(data);
return NULL;
}
/* Check buffer size */
length = func->read_ready(handle);
if ((length > CAPWAP_ACDESC_SUBELEMENT_MAXDATA) || (length < desc->length)) {
capwap_logging_debug("Invalid AC Descriptor subelement: length");
capwap_acdescriptor_element_free(data);
return NULL;
}
desc->data = (uint8_t*)capwap_alloc(desc->length + 1);
func->read_block(handle, desc->data, desc->length);
desc->data[desc->length] = 0;
}
return data;

View File

@ -5,12 +5,14 @@
#define CAPWAP_ACDESC_SECURITY_PRESHARED_KEY 0x04
#define CAPWAP_ACDESC_SECURITY_X509_CERT 0x02
#define CAPWAP_ACDESC_SECURITY_MASK 0x06
#define CAPWAP_ACDESC_RMACFIELD_SUPPORTED 1
#define CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED 2
#define CAPWAP_ACDESC_DTLS_DATA_CHANNEL_ENABLED 0x04
#define CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED 0x02
#define CAPWAP_ACDESC_DTLS_POLICY_MASK 0x06
struct capwap_acdescriptor_element {
uint16_t stations;
@ -31,7 +33,7 @@ struct capwap_acdescriptor_desc_subelement {
uint32_t vendor;
uint16_t type;
uint16_t length;
uint8_t data[CAPWAP_ACDESC_SUBELEMENT_MAXDATA];
uint8_t* data;
};
extern struct capwap_message_elements_ops capwap_element_acdescriptor_ops;

View File

@ -38,7 +38,7 @@ static void* capwap_acipv4list_element_parsing(capwap_message_elements_handle ha
length = func->read_ready(handle);
if ((length >= 4) && (length <= CAPWAP_ACIPV4LIST_MAX_ELEMENTS * 4) && (length % 4)) {
capwap_logging_debug("Invalid AC IPv4 List element");
capwap_logging_debug("Invalid AC IPv4 List element: unbuffer");
return NULL;
}

View File

@ -44,7 +44,7 @@ static void* capwap_acipv6list_element_parsing(capwap_message_elements_handle ha
length = func->read_ready(handle);
if ((length >= 16) && (length <= CAPWAP_ACIPV4LIST_MAX_ELEMENTS * 16) && (length % 16)) {
capwap_logging_debug("Invalid AC IPv6 List element");
capwap_logging_debug("Invalid AC IPv6 List element: underbuffer");
return NULL;
}

View File

@ -20,6 +20,7 @@ static void capwap_acname_element_create(void* data, capwap_message_elements_han
struct capwap_acname_element* element = (struct capwap_acname_element*)data;
ASSERT(data != NULL);
ASSERT(element->name != NULL);
func->write_block(handle, element->name, strlen((char*)element->name));
}
@ -34,7 +35,7 @@ static void* capwap_acname_element_parsing(capwap_message_elements_handle handle
length = func->read_ready(handle);
if ((length < 1) || (length > CAPWAP_ACNAME_MAXLENGTH)) {
capwap_logging_debug("Invalid AC Name element");
capwap_logging_debug("Invalid AC Name element: underbuffer");
return NULL;
}
@ -44,17 +45,28 @@ static void* capwap_acname_element_parsing(capwap_message_elements_handle handle
capwap_outofmemory();
}
data->name = (uint8_t*)capwap_alloc(length + 1);
if (!data->name) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_acname_element));
func->read_block(handle, data->name, length);
data->name[length] = 0;
return data;
}
/* */
static void capwap_acname_element_free(void* data) {
struct capwap_acname_element* element = (struct capwap_acname_element*)data;
ASSERT(data != NULL);
if (element->name) {
capwap_free(element->name);
}
capwap_free(data);
}

View File

@ -6,7 +6,7 @@
#define CAPWAP_ACNAME_MAXLENGTH 512
struct capwap_acname_element {
uint8_t name[CAPWAP_ACNAME_MAXLENGTH + 1];
uint8_t* name;
};
extern struct capwap_message_elements_ops capwap_element_acname_ops;

View File

@ -35,7 +35,7 @@ static void* capwap_acnamepriority_element_parsing(capwap_message_elements_handl
length = func->read_ready(handle) - 1;
if ((length < 1) || (length > CAPWAP_ACNAMEPRIORITY_MAXLENGTH)) {
capwap_logging_debug("Invalid AC Name Priority element");
capwap_logging_debug("Invalid AC Name Priority element: underbuffer");
return NULL;
}
@ -45,18 +45,29 @@ static void* capwap_acnamepriority_element_parsing(capwap_message_elements_handl
capwap_outofmemory();
}
data->name = (uint8_t*)capwap_alloc(length + 1);
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_acnamepriority_element));
func->read_u8(handle, &data->priority);
func->read_block(handle, data->name, length);
data->name[length] = 0;
return data;
}
/* */
static void capwap_acnamepriority_element_free(void* data) {
struct capwap_acnamepriority_element* element = (struct capwap_acnamepriority_element*)data;
ASSERT(data != NULL);
if (element->name) {
capwap_free(element->name);
}
capwap_free(data);
}

View File

@ -7,7 +7,7 @@
struct capwap_acnamepriority_element {
uint8_t priority;
uint8_t name[CAPWAP_ACNAMEPRIORITY_MAXLENGTH + 1];
uint8_t* name;
};
extern struct capwap_message_elements_ops capwap_element_acnamepriority_ops;

View File

@ -33,7 +33,7 @@ static void* capwap_actimestamp_element_parsing(capwap_message_elements_handle h
ASSERT(func != NULL);
if (func->read_ready(handle) != 4) {
capwap_logging_debug("Invalid AC Timestamp element");
capwap_logging_debug("Invalid AC Timestamp element: underbuffer");
return NULL;
}
@ -44,7 +44,6 @@ static void* capwap_actimestamp_element_parsing(capwap_message_elements_handle h
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_actimestamp_element));
func->read_u32(handle, &data->timestamp);
return data;

View File

@ -20,6 +20,8 @@ static void capwap_addmacacl_element_create(void* data, capwap_message_elements_
struct capwap_addmacacl_element* element = (struct capwap_addmacacl_element*)data;
ASSERT(data != NULL);
ASSERT(element->entry > 0);
ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length));
func->write_u8(handle, element->entry);
func->write_u8(handle, element->length);
@ -36,7 +38,7 @@ static void capwap_addmacacl_element_free(void* data) {
capwap_free(element->address);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -49,15 +51,11 @@ static void* capwap_addmacacl_element_parsing(capwap_message_elements_handle han
length = func->read_ready(handle);
if (length < 8) {
capwap_logging_debug("Invalid Add MAC ACL Entry element");
capwap_logging_debug("Invalid Add MAC ACL Entry element: underbuffer");
return NULL;
}
length -= 2;
if ((length % 6) && (length % 8)) {
capwap_logging_debug("Invalid Add MAC ACL Entry element");
return NULL;
}
/* */
data = (struct capwap_addmacacl_element*)capwap_alloc(sizeof(struct capwap_addmacacl_element));
@ -67,13 +65,22 @@ static void* capwap_addmacacl_element_parsing(capwap_message_elements_handle han
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_addmacacl_element));
func->read_u8(handle, &data->entry);
func->read_u8(handle, &data->length);
if (!data->entry) {
capwap_addmacacl_element_free((void*)data);
capwap_logging_debug("Invalid Add MAC ACL Entry element: invalid entry");
return NULL;
} else if (!IS_VALID_MACADDRESS_LENGTH(data->length)) {
capwap_addmacacl_element_free((void*)data);
capwap_logging_debug("Invalid Add MAC ACL Entry element: invalid length");
return NULL;
}
if (length != (data->entry * data->length)) {
capwap_addmacacl_element_free((void*)data);
capwap_logging_debug("Invalid Add MAC ACL Entry element");
capwap_logging_debug("Invalid Add MAC ACL Entry element: invalid total length");
return NULL;
}

View File

@ -22,12 +22,18 @@ static void capwap_addstation_element_create(void* data, capwap_message_elements
struct capwap_addstation_element* element = (struct capwap_addstation_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length));
func->write_u8(handle, element->radioid);
func->write_u8(handle, element->length);
func->write_block(handle, element->address, element->length);
if (element->vlan && *element->vlan) {
func->write_block(handle, element->vlan, strlen((char*)element->vlan));
unsigned short length = strlen((char*)element->vlan);
ASSERT(length <= CAPWAP_ADDSTATION_VLAN_MAX_LENGTH);
func->write_block(handle, element->vlan, length);
}
}
@ -58,7 +64,7 @@ static void* capwap_addstation_element_parsing(capwap_message_elements_handle ha
length = func->read_ready(handle);
if (length < 8) {
capwap_logging_debug("Invalid Add Station element");
capwap_logging_debug("Invalid Add Station element: underbuffer");
return NULL;
}
@ -72,13 +78,16 @@ static void* capwap_addstation_element_parsing(capwap_message_elements_handle ha
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_addstation_element));
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->length);
if (length < data->length) {
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_addstation_element_free((void*)data);
capwap_logging_debug("Invalid Add Station element");
capwap_logging_debug("Invalid Add Station element: invalid radio");
return NULL;
} else if (!IS_VALID_MACADDRESS_LENGTH(data->length) || (length < data->length)) {
capwap_addstation_element_free((void*)data);
capwap_logging_debug("Invalid Add Station element: invalid length");
return NULL;
}
@ -90,14 +99,20 @@ static void* capwap_addstation_element_parsing(capwap_message_elements_handle ha
func->read_block(handle, data->address, data->length);
length -= data->length;
if (length) {
data->vlan = (uint8_t*)capwap_alloc(length + 1);
if (!data->vlan) {
capwap_outofmemory();
}
if (length > 0) {
if (length <= CAPWAP_ADDSTATION_VLAN_MAX_LENGTH) {
data->vlan = (uint8_t*)capwap_alloc(length + 1);
if (!data->vlan) {
capwap_outofmemory();
}
func->read_block(handle, data->vlan, length);
data->vlan[length] = 0;
func->read_block(handle, data->vlan, length);
data->vlan[length] = 0;
} else {
capwap_addstation_element_free((void*)data);
capwap_logging_debug("Invalid Add Station element: invalid vlan");
return NULL;
}
}
return data;

View File

@ -3,6 +3,8 @@
#define CAPWAP_ELEMENT_ADDSTATION 8
#define CAPWAP_ADDSTATION_VLAN_MAX_LENGTH 512
struct capwap_addstation_element {
uint8_t radioid;
uint8_t length;

View File

@ -36,7 +36,7 @@ static void* capwap_controlipv4_element_parsing(capwap_message_elements_handle h
ASSERT(func != NULL);
if (func->read_ready(handle) != 6) {
capwap_logging_debug("Invalid Control IPv4 Address element");
capwap_logging_debug("Invalid Control IPv4 Address element: underbuffer");
return NULL;
}
@ -47,7 +47,6 @@ static void* capwap_controlipv4_element_parsing(capwap_message_elements_handle h
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_controlipv4_element));
func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in_addr));
func->read_u16(handle, &data->wtpcount);

View File

@ -42,7 +42,7 @@ static void* capwap_controlipv6_element_parsing(capwap_message_elements_handle h
ASSERT(func != NULL);
if (func->read_ready(handle) != 18) {
capwap_logging_debug("Invalid Control IPv6 Address element");
capwap_logging_debug("Invalid Control IPv6 Address element: underbuffer");
return NULL;
}
@ -53,7 +53,6 @@ static void* capwap_controlipv6_element_parsing(capwap_message_elements_handle h
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_controlipv6_element));
func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in6_addr));
func->read_u16(handle, &data->wtpcount);

View File

@ -22,6 +22,9 @@ static void capwap_datatransferdata_element_create(void* data, capwap_message_el
struct capwap_datatransferdata_element* element = (struct capwap_datatransferdata_element*)data;
ASSERT(data != NULL);
ASSERT((element->type == CAPWAP_DATATRANSFERDATA_TYPE_DATA_IS_INCLUDED) || (element->type == CAPWAP_DATATRANSFERDATA_TYPE_DATA_EOF) || (element->type == CAPWAP_DATATRANSFERDATA_TYPE_ERROR));
ASSERT((element->mode == CAPWAP_DATATRANSFERDATA_MODE_CRASH_DUMP) || (element->mode == CAPWAP_DATATRANSFERDATA_MODE_MEMORY_DUMP));
ASSERT(element->length > 0);
func->write_u8(handle, element->type);
func->write_u8(handle, element->mode);
@ -39,7 +42,7 @@ static void capwap_datatransferdata_element_free(void* data) {
capwap_free(element->data);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -52,7 +55,7 @@ static void* capwap_datatransferdata_element_parsing(capwap_message_elements_han
length = func->read_ready(handle);
if (length < 5) {
capwap_logging_debug("Invalid Data Transfer Data element");
capwap_logging_debug("Invalid Data Transfer Data element: underbuffer");
return NULL;
}
@ -66,14 +69,21 @@ static void* capwap_datatransferdata_element_parsing(capwap_message_elements_han
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_datatransferdata_element));
func->read_u8(handle, &data->type);
func->read_u8(handle, &data->mode);
func->read_u16(handle, &data->length);
if (length != data->length) {
if ((data->type != CAPWAP_DATATRANSFERDATA_TYPE_DATA_IS_INCLUDED) && (data->type != CAPWAP_DATATRANSFERDATA_TYPE_DATA_EOF) && (data->type != CAPWAP_DATATRANSFERDATA_TYPE_ERROR)) {
capwap_datatransferdata_element_free((void*)data);
capwap_logging_debug("Invalid Data Transfer Data element");
capwap_logging_debug("Invalid Data Transfer Data element: invalid type");
return NULL;
} else if ((data->mode != CAPWAP_DATATRANSFERDATA_MODE_CRASH_DUMP) && (data->mode != CAPWAP_DATATRANSFERDATA_MODE_MEMORY_DUMP)) {
capwap_datatransferdata_element_free((void*)data);
capwap_logging_debug("Invalid Data Transfer Data element: invalid mode");
return NULL;
} else if (length != data->length) {
capwap_datatransferdata_element_free((void*)data);
capwap_logging_debug("Invalid Data Transfer Data element: invalid length");
return NULL;
}

View File

@ -20,36 +20,12 @@ static void capwap_datatransfermode_element_create(void* data, capwap_message_el
struct capwap_datatransfermode_element* element = (struct capwap_datatransfermode_element*)data;
ASSERT(data != NULL);
ASSERT((element->mode == CAPWAP_DATATRANSFERMODE_MODE_CRASH_DUMP) || (element->mode == CAPWAP_DATATRANSFERMODE_MODE_MEMORY_DUMP));
/* */
func->write_u8(handle, element->mode);
}
/* */
static void* capwap_datatransfermode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_datatransfermode_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid Data Transfer Mode element");
return NULL;
}
/* */
data = (struct capwap_datatransfermode_element*)capwap_alloc(sizeof(struct capwap_datatransfermode_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_datatransfermode_element));
func->read_u8(handle, &data->mode);
return data;
}
/* */
static void capwap_datatransfermode_element_free(void* data) {
ASSERT(data != NULL);
@ -57,6 +33,35 @@ static void capwap_datatransfermode_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_datatransfermode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_datatransfermode_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid Data Transfer Mode element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_datatransfermode_element*)capwap_alloc(sizeof(struct capwap_datatransfermode_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->mode);
if ((data->mode != CAPWAP_DATATRANSFERMODE_MODE_CRASH_DUMP) && (data->mode != CAPWAP_DATATRANSFERMODE_MODE_MEMORY_DUMP)) {
capwap_datatransfermode_element_free((void*)data);
capwap_logging_debug("Invalid Data Transfer Mode element: invalid mode");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_datatransfermode_ops = {
.create_message_element = capwap_datatransfermode_element_create,

View File

@ -20,6 +20,9 @@ static void capwap_decrypterrorreport_element_create(void* data, capwap_message_
struct capwap_decrypterrorreport_element* element = (struct capwap_decrypterrorreport_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
ASSERT(element->entry > 0);
ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length));
func->write_u8(handle, element->radioid);
func->write_u8(handle, element->entry);
@ -37,7 +40,7 @@ static void capwap_decrypterrorreport_element_free(void* data) {
capwap_free(element->address);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -50,15 +53,11 @@ static void* capwap_decrypterrorreport_element_parsing(capwap_message_elements_h
length = func->read_ready(handle);
if (length < 9) {
capwap_logging_debug("Invalid Decryption Error Report element");
capwap_logging_debug("Invalid Decryption Error Report element: underbuffer");
return NULL;
}
length -= 3;
if ((length % 6) && (length % 8)) {
capwap_logging_debug("Invalid Decryption Error Report element");
return NULL;
}
/* */
data = (struct capwap_decrypterrorreport_element*)capwap_alloc(sizeof(struct capwap_decrypterrorreport_element));
@ -68,14 +67,27 @@ static void* capwap_decrypterrorreport_element_parsing(capwap_message_elements_h
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_decrypterrorreport_element));
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->entry);
func->read_u8(handle, &data->length);
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_decrypterrorreport_element_free((void*)data);
capwap_logging_debug("Invalid Decryption Error Report element: invalid radioid");
return NULL;
} else if (!data->entry) {
capwap_decrypterrorreport_element_free((void*)data);
capwap_logging_debug("Invalid Decryption Error Report element: invalid entry");
return NULL;
} else if (!IS_VALID_MACADDRESS_LENGTH(data->length)) {
capwap_decrypterrorreport_element_free((void*)data);
capwap_logging_debug("Invalid Decryption Error Report element: invalid length");
return NULL;
}
if (length != (data->entry * data->length)) {
capwap_decrypterrorreport_element_free((void*)data);
capwap_logging_debug("Invalid Decryption Error Report element");
capwap_logging_debug("Invalid Decryption Error Report element: invalid total length");
return NULL;
}

View File

@ -20,38 +20,13 @@ static void capwap_decrypterrorreportperiod_element_create(void* data, capwap_me
struct capwap_decrypterrorreportperiod_element* element = (struct capwap_decrypterrorreportperiod_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
/* */
func->write_u8(handle, element->radioid);
func->write_u16(handle, element->interval);
}
/* */
static void* capwap_decrypterrorreportperiod_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_decrypterrorreportperiod_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 3) {
capwap_logging_debug("Invalid Decryption Error Report Period element");
return NULL;
}
/* */
data = (struct capwap_decrypterrorreportperiod_element*)capwap_alloc(sizeof(struct capwap_decrypterrorreportperiod_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_decrypterrorreportperiod_element));
func->read_u8(handle, &data->radioid);
func->read_u16(handle, &data->interval);
return data;
}
/* */
static void capwap_decrypterrorreportperiod_element_free(void* data) {
ASSERT(data != NULL);
@ -59,6 +34,37 @@ static void capwap_decrypterrorreportperiod_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_decrypterrorreportperiod_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_decrypterrorreportperiod_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 3) {
capwap_logging_debug("Invalid Decryption Error Report Period element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_decrypterrorreportperiod_element*)capwap_alloc(sizeof(struct capwap_decrypterrorreportperiod_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->radioid);
func->read_u16(handle, &data->interval);
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_decrypterrorreportperiod_element_free((void*)data);
capwap_logging_debug("Invalid Decryption Error Report Period element: invalid radioid");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_decrypterrorreportperiod_ops = {
.create_message_element = capwap_decrypterrorreportperiod_element_create,

View File

@ -20,6 +20,8 @@ static void capwap_deletemacacl_element_create(void* data, capwap_message_elemen
struct capwap_deletemacacl_element* element = (struct capwap_deletemacacl_element*)data;
ASSERT(data != NULL);
ASSERT(element->entry > 0);
ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length));
func->write_u8(handle, element->entry);
func->write_u8(handle, element->length);
@ -36,7 +38,7 @@ static void capwap_deletemacacl_element_free(void* data) {
capwap_free(element->address);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -49,15 +51,11 @@ static void* capwap_deletemacacl_element_parsing(capwap_message_elements_handle
length = func->read_ready(handle);
if (length < 8) {
capwap_logging_debug("Invalid Delete MAC ACL Entry element");
capwap_logging_debug("Invalid Delete MAC ACL Entry element: underbuffer");
return NULL;
}
length -= 2;
if ((length % 6) && (length % 8)) {
capwap_logging_debug("Invalid Delete MAC ACL Entry element");
return NULL;
}
/* */
data = (struct capwap_deletemacacl_element*)capwap_alloc(sizeof(struct capwap_deletemacacl_element));
@ -67,10 +65,19 @@ static void* capwap_deletemacacl_element_parsing(capwap_message_elements_handle
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_deletemacacl_element));
func->read_u8(handle, &data->entry);
func->read_u8(handle, &data->length);
if (!data->entry) {
capwap_deletemacacl_element_free((void*)data);
capwap_logging_debug("Invalid Delete MAC ACL Entry element: invalid entry");
return NULL;
} else if (!IS_VALID_MACADDRESS_LENGTH(data->length)) {
capwap_deletemacacl_element_free((void*)data);
capwap_logging_debug("Invalid Delete MAC ACL Entry element: invalid length");
return NULL;
}
if (length != (data->entry * data->length)) {
capwap_deletemacacl_element_free((void*)data);
capwap_logging_debug("Invalid Delete MAC ACL Entry element");

View File

@ -20,6 +20,8 @@ static void capwap_deletestation_element_create(void* data, capwap_message_eleme
struct capwap_deletestation_element* element = (struct capwap_deletestation_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length));
func->write_u8(handle, element->radioid);
func->write_u8(handle, element->length);
@ -36,7 +38,7 @@ static void capwap_deletestation_element_free(void* data) {
capwap_free(element->address);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -49,7 +51,7 @@ static void* capwap_deletestation_element_parsing(capwap_message_elements_handle
length = func->read_ready(handle);
if (length < 8) {
capwap_logging_debug("Invalid Delete Station element");
capwap_logging_debug("Invalid Delete Station element: underbuffer");
return NULL;
}
@ -63,13 +65,16 @@ static void* capwap_deletestation_element_parsing(capwap_message_elements_handle
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_deletestation_element));
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->length);
if (length != data->length) {
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_deletestation_element_free((void*)data);
capwap_logging_debug("Invalid Delete Station element");
capwap_logging_debug("Invalid Delete Station element: invalid radio");
return NULL;
} else if (!IS_VALID_MACADDRESS_LENGTH(data->length) || (length != data->length)) {
capwap_deletestation_element_free((void*)data);
capwap_logging_debug("Invalid Delete Station element: invalid length");
return NULL;
}

View File

@ -20,36 +20,14 @@ static void capwap_discoverytype_element_create(void* data, capwap_message_eleme
struct capwap_discoverytype_element* element = (struct capwap_discoverytype_element*)data;
ASSERT(data != NULL);
ASSERT((element->type == CAPWAP_DISCOVERYTYPE_TYPE_UNKNOWN) || (element->type == CAPWAP_DISCOVERYTYPE_TYPE_STATIC) ||
(element->type == CAPWAP_DISCOVERYTYPE_TYPE_DHCP) || (element->type == CAPWAP_DISCOVERYTYPE_TYPE_DNS) ||
(element->type == CAPWAP_DISCOVERYTYPE_TYPE_ACREFERRAL));
/* */
func->write_u8(handle, element->type);
}
/* */
static void* capwap_discoverytype_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_discoverytype_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid Discovery Type element");
return NULL;
}
/* */
data = (struct capwap_discoverytype_element*)capwap_alloc(sizeof(struct capwap_discoverytype_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_discoverytype_element));
func->read_u8(handle, &data->type);
return data;
}
/* */
static void capwap_discoverytype_element_free(void* data) {
ASSERT(data != NULL);
@ -57,6 +35,37 @@ static void capwap_discoverytype_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_discoverytype_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_discoverytype_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid Discovery Type element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_discoverytype_element*)capwap_alloc(sizeof(struct capwap_discoverytype_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->type);
if ((data->type != CAPWAP_DISCOVERYTYPE_TYPE_UNKNOWN) && (data->type != CAPWAP_DISCOVERYTYPE_TYPE_STATIC) &&
(data->type != CAPWAP_DISCOVERYTYPE_TYPE_DHCP) && (data->type != CAPWAP_DISCOVERYTYPE_TYPE_DNS) &&
(data->type != CAPWAP_DISCOVERYTYPE_TYPE_ACREFERRAL)) {
capwap_discoverytype_element_free((void*)data);
capwap_logging_debug("Invalid Discovery Type element: invalid type");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_discoverytype_ops = {
.create_message_element = capwap_discoverytype_element_create,

View File

@ -3,11 +3,11 @@
#define CAPWAP_ELEMENT_DISCOVERYTYPE 20
#define CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_UNKNOWN 0
#define CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_STATIC 1
#define CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_DHCP 2
#define CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_DNS 3
#define CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_ACREFERRAL 4
#define CAPWAP_DISCOVERYTYPE_TYPE_UNKNOWN 0
#define CAPWAP_DISCOVERYTYPE_TYPE_STATIC 1
#define CAPWAP_DISCOVERYTYPE_TYPE_DHCP 2
#define CAPWAP_DISCOVERYTYPE_TYPE_DNS 3
#define CAPWAP_DISCOVERYTYPE_TYPE_ACREFERRAL 4
struct capwap_discoverytype_element {
uint8_t type;

View File

@ -22,6 +22,8 @@ static void capwap_duplicateipv4_element_create(void* data, capwap_message_eleme
struct capwap_duplicateipv4_element* element = (struct capwap_duplicateipv4_element*)data;
ASSERT(data != NULL);
ASSERT((element->status == CAPWAP_DUPLICATEIPv4_CLEARED) || (element->status == CAPWAP_DUPLICATEIPv4_DETECTED));
ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length));
func->write_block(handle, (uint8_t*)&element->address, sizeof(struct in_addr));
func->write_u8(handle, element->status);
@ -39,7 +41,7 @@ static void capwap_duplicateipv4_element_free(void* data) {
capwap_free(element->macaddress);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -52,7 +54,7 @@ static void* capwap_duplicateipv4_element_parsing(capwap_message_elements_handle
length = func->read_ready(handle);
if (length < 12) {
capwap_logging_debug("Invalid Duplicate IPv4 Address element");
capwap_logging_debug("Invalid Duplicate IPv4 Address element: underbuffer");
return NULL;
}
@ -66,14 +68,17 @@ static void* capwap_duplicateipv4_element_parsing(capwap_message_elements_handle
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_duplicateipv4_element));
func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in_addr));
func->read_u8(handle, &data->status);
func->read_u8(handle, &data->length);
if (length != data->length) {
if ((data->status != CAPWAP_DUPLICATEIPv4_CLEARED) && (data->status != CAPWAP_DUPLICATEIPv4_DETECTED)) {
capwap_duplicateipv4_element_free((void*)data);
capwap_logging_debug("Invalid Duplicate IPv4 Address element");
capwap_logging_debug("Invalid Duplicate IPv4 Address element: invalid status");
return NULL;
} else if (!IS_VALID_MACADDRESS_LENGTH(data->length) || (length != data->length)) {
capwap_duplicateipv4_element_free((void*)data);
capwap_logging_debug("Invalid Duplicate IPv4 Address element: invalid length");
return NULL;
}

View File

@ -3,6 +3,9 @@
#define CAPWAP_ELEMENT_DUPLICATEIPV4 21
#define CAPWAP_DUPLICATEIPv4_CLEARED 0
#define CAPWAP_DUPLICATEIPv4_DETECTED 1
struct capwap_duplicateipv4_element {
struct in_addr address;
uint8_t status;

View File

@ -28,6 +28,8 @@ static void capwap_duplicateipv6_element_create(void* data, capwap_message_eleme
struct capwap_duplicateipv6_element* element = (struct capwap_duplicateipv6_element*)data;
ASSERT(data != NULL);
ASSERT((element->status == CAPWAP_DUPLICATEIPv6_CLEARED) || (element->status == CAPWAP_DUPLICATEIPv6_DETECTED));
ASSERT(IS_VALID_MACADDRESS_LENGTH(element->length));
func->write_block(handle, (uint8_t*)&element->address, sizeof(struct in6_addr));
func->write_u8(handle, element->status);
@ -45,7 +47,7 @@ static void capwap_duplicateipv6_element_free(void* data) {
capwap_free(element->macaddress);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -58,7 +60,7 @@ static void* capwap_duplicateipv6_element_parsing(capwap_message_elements_handle
length = func->read_ready(handle);
if (length < 24) {
capwap_logging_debug("Invalid Duplicate IPv6 Address element");
capwap_logging_debug("Invalid Duplicate IPv6 Address element: underbuffer");
return NULL;
}
@ -72,14 +74,17 @@ static void* capwap_duplicateipv6_element_parsing(capwap_message_elements_handle
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_duplicateipv6_element));
func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in6_addr));
func->read_u8(handle, &data->status);
func->read_u8(handle, &data->length);
if (length != data->length) {
if ((data->status != CAPWAP_DUPLICATEIPv6_CLEARED) && (data->status != CAPWAP_DUPLICATEIPv6_DETECTED)) {
capwap_duplicateipv6_element_free((void*)data);
capwap_logging_debug("Invalid Duplicate IPv6 Address element");
capwap_logging_debug("Invalid Duplicate IPv6 Address element: invalid status");
return NULL;
} else if (!IS_VALID_MACADDRESS_LENGTH(data->length) || (length != data->length)) {
capwap_duplicateipv6_element_free((void*)data);
capwap_logging_debug("Invalid Duplicate IPv6 Address element: invalid length");
return NULL;
}

View File

@ -3,6 +3,9 @@
#define CAPWAP_ELEMENT_DUPLICATEIPV6 22
#define CAPWAP_DUPLICATEIPv6_CLEARED 0
#define CAPWAP_DUPLICATEIPv6_DETECTED 1
struct capwap_duplicateipv6_element {
struct in6_addr address;
uint8_t status;

View File

@ -20,36 +20,12 @@ static void capwap_ecnsupport_element_create(void* data, capwap_message_elements
struct capwap_ecnsupport_element* element = (struct capwap_ecnsupport_element*)data;
ASSERT(data != NULL);
ASSERT((element->flag == CAPWAP_LIMITED_ECN_SUPPORT) || (element->flag == CAPWAP_FULL_ECN_SUPPORT));
/* */
func->write_u8(handle, element->flag);
}
/* */
static void* capwap_ecnsupport_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_ecnsupport_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid ECN Support element");
return NULL;
}
/* */
data = (struct capwap_ecnsupport_element*)capwap_alloc(sizeof(struct capwap_ecnsupport_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_ecnsupport_element));
func->read_u8(handle, &data->flag);
return data;
}
/* */
static void capwap_ecnsupport_element_free(void* data) {
ASSERT(data != NULL);
@ -57,6 +33,36 @@ static void capwap_ecnsupport_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_ecnsupport_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_ecnsupport_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid ECN Support element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_ecnsupport_element*)capwap_alloc(sizeof(struct capwap_ecnsupport_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->flag);
if ((data->flag != CAPWAP_LIMITED_ECN_SUPPORT) && (data->flag != CAPWAP_FULL_ECN_SUPPORT)) {
capwap_ecnsupport_element_free((void*)data);
capwap_logging_debug("Invalid ECN Support element: invalid flag");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_ecnsupport_ops = {
.create_message_element = capwap_ecnsupport_element_create,

View File

@ -32,7 +32,7 @@ static void* capwap_idletimeout_element_parsing(capwap_message_elements_handle h
ASSERT(func != NULL);
if (func->read_ready(handle) != 4) {
capwap_logging_debug("Invalid Idle Timeout element");
capwap_logging_debug("Invalid Idle Timeout element: underbuffer");
return NULL;
}
@ -43,7 +43,6 @@ static void* capwap_idletimeout_element_parsing(capwap_message_elements_handle h
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_idletimeout_element));
func->read_u32(handle, &data->timeout);
return data;

View File

@ -20,9 +20,13 @@ static void capwap_imagedata_element_create(void* data, capwap_message_elements_
struct capwap_imagedata_element* element = (struct capwap_imagedata_element*)data;
ASSERT(data != NULL);
ASSERT((element->type == CAPWAP_IMAGEDATA_TYPE_DATA_IS_INCLUDED) || (element->type == CAPWAP_IMAGEDATA_TYPE_DATA_EOF) || (element->type == CAPWAP_IMAGEDATA_TYPE_ERROR));
ASSERT(element->length <= CAPWAP_IMAGEDATA_DATA_MAX_LENGTH);
func->write_u8(handle, element->type);
func->write_block(handle, element->data, element->length);
if (element->length > 0) {
func->write_block(handle, element->data, element->length);
}
}
/* */
@ -35,7 +39,7 @@ static void capwap_imagedata_element_free(void* data) {
capwap_free(element->data);
}
capwap_free(element);
capwap_free(data);
}
/* */
@ -48,7 +52,7 @@ static void* capwap_imagedata_element_parsing(capwap_message_elements_handle han
length = func->read_ready(handle);
if (length < 1) {
capwap_logging_debug("Invalid Image Data element");
capwap_logging_debug("Invalid Image Data element: underbuffer");
return NULL;
}
@ -62,10 +66,26 @@ static void* capwap_imagedata_element_parsing(capwap_message_elements_handle han
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_imagedata_element));
func->read_u8(handle, &data->type);
if ((data->type != CAPWAP_IMAGEDATA_TYPE_DATA_IS_INCLUDED) && (data->type != CAPWAP_IMAGEDATA_TYPE_DATA_EOF) && (data->type != CAPWAP_IMAGEDATA_TYPE_ERROR)) {
capwap_imagedata_element_free((void*)data);
capwap_logging_debug("Invalid Image Data element: underbuffer: invalid type");
return NULL;
} else if ((data->type == CAPWAP_IMAGEDATA_TYPE_ERROR) && (length > 0)) {
capwap_imagedata_element_free((void*)data);
capwap_logging_debug("Invalid Image Data element: underbuffer: invalid error type");
return NULL;
} else if (length > CAPWAP_IMAGEDATA_DATA_MAX_LENGTH) {
capwap_imagedata_element_free((void*)data);
capwap_logging_debug("Invalid Image Data element: underbuffer: invalid length");
return NULL;
}
data->length = length;
if (length > 0) {
if (!length) {
data->data = NULL;
} else {
data->data = (uint8_t*)capwap_alloc(length);
if (!data->data) {
capwap_outofmemory();

View File

@ -7,6 +7,8 @@
#define CAPWAP_IMAGEDATA_TYPE_DATA_EOF 2
#define CAPWAP_IMAGEDATA_TYPE_ERROR 5
#define CAPWAP_IMAGEDATA_DATA_MAX_LENGTH 1024
struct capwap_imagedata_element {
uint8_t type;
uint16_t length;

View File

@ -19,12 +19,29 @@ Length: >= 5
/* */
static void capwap_imageidentifier_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
int length;
struct capwap_imageidentifier_element* element = (struct capwap_imageidentifier_element*)data;
ASSERT(data != NULL);
length = strlen((char*)element->name);
ASSERT(length <= CAPWAP_IMAGEDATA_DATA_MAX_LENGTH);
func->write_u32(handle, element->vendor);
func->write_block(handle, element->name, strlen((char*)element->name));
func->write_block(handle, element->name, length);
}
/* */
static void capwap_imageidentifier_element_free(void* data) {
struct capwap_imageidentifier_element* element = (struct capwap_imageidentifier_element*)data;
ASSERT(data != NULL);
if (element->name) {
capwap_free(element->name);
}
capwap_free(data);
}
/* */
@ -37,13 +54,13 @@ static void* capwap_imageidentifier_element_parsing(capwap_message_elements_hand
length = func->read_ready(handle);
if (length < 5) {
capwap_logging_debug("Invalid Image Indentifier element");
capwap_logging_debug("Invalid Image Indentifier element: underbuffer");
return NULL;
}
length -= 4;
if (length > CAPWAP_IMAGEIDENTIFIER_MAXLENGTH) {
capwap_logging_debug("Invalid AC Name element");
capwap_logging_debug("Invalid Image Indentifier element: invalid length");
return NULL;
}
@ -53,21 +70,19 @@ static void* capwap_imageidentifier_element_parsing(capwap_message_elements_hand
capwap_outofmemory();
}
data->name = (uint8_t*)capwap_alloc(length + 1);
if (!data->name) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_imageidentifier_element));
func->read_u32(handle, &data->vendor);
func->read_block(handle, data->name, length);
data->name[length] = 0;
return data;
}
/* */
static void capwap_imageidentifier_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(data);
}
/* */
struct capwap_message_elements_ops capwap_element_imageidentifier_ops = {
.create_message_element = capwap_imageidentifier_element_create,

View File

@ -7,7 +7,7 @@
struct capwap_imageidentifier_element {
uint32_t vendor;
uint8_t name[CAPWAP_IMAGEIDENTIFIER_MAXLENGTH + 1];
uint8_t* name;
};
extern struct capwap_message_elements_ops capwap_element_imageidentifier_ops;

View File

@ -48,7 +48,7 @@ static void* capwap_imageinfo_element_parsing(capwap_message_elements_handle han
ASSERT(func != NULL);
if (func->read_ready(handle) != 20) {
capwap_logging_debug("Invalid Image Information element");
capwap_logging_debug("Invalid Image Information element: underbuffer");
return NULL;
}
@ -59,7 +59,6 @@ static void* capwap_imageinfo_element_parsing(capwap_message_elements_handle han
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_imageinfo_element));
func->read_u32(handle, &data->length);
func->read_block(handle, data->hash, CAPWAP_IMAGEINFO_HASH_LENGTH);

View File

@ -3,9 +3,6 @@
#define CAPWAP_ELEMENT_INITIATEDOWNLOAD 27
#define CAPWAP_LIMITED_ECN_SUPPORT 0
#define CAPWAP_FULL_ECN_SUPPORT 1
struct capwap_initdownload_element {
uint8_t dummy;
};

View File

@ -33,7 +33,7 @@ static void* capwap_localipv4_element_parsing(capwap_message_elements_handle han
ASSERT(func != NULL);
if (func->read_ready(handle) != 4) {
capwap_logging_debug("Invalid Local IPv4 Address element");
capwap_logging_debug("Invalid Local IPv4 Address element: underbuffer");
return NULL;
}
@ -44,7 +44,6 @@ static void* capwap_localipv4_element_parsing(capwap_message_elements_handle han
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_localipv4_element));
func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in_addr));
return data;

View File

@ -38,7 +38,7 @@ static void* capwap_localipv6_element_parsing(capwap_message_elements_handle han
ASSERT(func != NULL);
if (func->read_ready(handle) != 16) {
capwap_logging_debug("Invalid Local IPv6 Address element");
capwap_logging_debug("Invalid Local IPv6 Address element: underbuffer");
return NULL;
}
@ -49,7 +49,6 @@ static void* capwap_localipv6_element_parsing(capwap_message_elements_handle han
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_localipv6_element));
func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in6_addr));
return data;

View File

@ -17,11 +17,28 @@ Length: >= 1
/* */
static void capwap_location_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
int length;
struct capwap_location_element* element = (struct capwap_location_element*)data;
ASSERT(data != NULL);
func->write_block(handle, element->value, strlen((char*)element->value));
length = strlen((char*)element->value);
ASSERT(length <= CAPWAP_LOCATION_MAXLENGTH);
func->write_block(handle, element->value, length);
}
/* */
static void capwap_location_element_free(void* data) {
struct capwap_location_element* element = (struct capwap_location_element*)data;
ASSERT(data != NULL);
if (element->value) {
capwap_free(element->value);
}
capwap_free(data);
}
/* */
@ -33,8 +50,8 @@ static void* capwap_location_element_parsing(capwap_message_elements_handle hand
ASSERT(func != NULL);
length = func->read_ready(handle);
if ((length < 1) || (length > CAPWAP_ACNAME_MAXLENGTH)) {
capwap_logging_debug("Invalid AC Name element");
if ((length < 1) || (length > CAPWAP_LOCATION_MAXLENGTH)) {
capwap_logging_debug("Invalid Location Data element: underbuffer");
return NULL;
}
@ -44,20 +61,18 @@ static void* capwap_location_element_parsing(capwap_message_elements_handle hand
capwap_outofmemory();
}
data->value = (uint8_t*)capwap_alloc(length + 1);
if (!data->value) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_location_element));
func->read_block(handle, data->value, length);
data->value[length] = 0;
return data;
}
/* */
static void capwap_location_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(data);
}
/* */
struct capwap_message_elements_ops capwap_element_location_ops = {
.create_message_element = capwap_location_element_create,

View File

@ -6,7 +6,7 @@
#define CAPWAP_LOCATION_MAXLENGTH 1024
struct capwap_location_element {
uint8_t value[CAPWAP_LOCATION_MAXLENGTH + 1];
uint8_t* value;
};
extern struct capwap_message_elements_ops capwap_element_location_ops;

View File

@ -33,7 +33,7 @@ static void* capwap_maximumlength_element_parsing(capwap_message_elements_handle
ASSERT(func != NULL);
if (func->read_ready(handle) != 2) {
capwap_logging_debug("Invalid Maxium Message Length element");
capwap_logging_debug("Invalid Maxium Message Length element: underbuffer");
return NULL;
}
@ -44,7 +44,6 @@ static void* capwap_maximumlength_element_parsing(capwap_message_elements_handle
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_maximumlength_element));
func->read_u16(handle, &data->length);
return data;

View File

@ -40,7 +40,7 @@ static void* capwap_mtudiscovery_element_parsing(capwap_message_elements_handle
length = func->read_ready(handle);
if (length > 0) {
capwap_logging_debug("Invalid MTU Discovery Padding element");
capwap_logging_debug("Invalid MTU Discovery Padding element: underbuffer");
return NULL;
}
@ -52,10 +52,7 @@ static void* capwap_mtudiscovery_element_parsing(capwap_message_elements_handle
/* Retrieve data */
data->length = length;
while (length > 0) {
func->read_u8(handle, NULL);
length--;
}
func->read_block(handle, NULL, length);
return data;
}
@ -63,7 +60,7 @@ static void* capwap_mtudiscovery_element_parsing(capwap_message_elements_handle
/* */
static void capwap_mtudiscovery_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(data);
}

View File

@ -20,38 +20,14 @@ static void capwap_radioadmstate_element_create(void* data, capwap_message_eleme
struct capwap_radioadmstate_element* element = (struct capwap_radioadmstate_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
ASSERT((element->state == CAPWAP_RADIO_ADMIN_STATE_ENABLED) || (element->state == CAPWAP_RADIO_ADMIN_STATE_DISABLED));
/* */
func->write_u8(handle, element->radioid);
func->write_u8(handle, element->state);
}
/* */
static void* capwap_radioadmstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_radioadmstate_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 2) {
capwap_logging_debug("Invalid Radio Administrative State element");
return NULL;
}
/* */
data = (struct capwap_radioadmstate_element*)capwap_alloc(sizeof(struct capwap_radioadmstate_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_radioadmstate_element));
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->state);
return data;
}
/* */
static void capwap_radioadmstate_element_free(void* data) {
ASSERT(data != NULL);
@ -59,6 +35,41 @@ static void capwap_radioadmstate_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_radioadmstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_radioadmstate_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 2) {
capwap_logging_debug("Invalid Radio Administrative State element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_radioadmstate_element*)capwap_alloc(sizeof(struct capwap_radioadmstate_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->state);
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_radioadmstate_element_free((void*)data);
capwap_logging_debug("Invalid Radio Administrative State element: invalid radioid");
return NULL;
} else if ((data->state != CAPWAP_RADIO_ADMIN_STATE_ENABLED) && (data->state != CAPWAP_RADIO_ADMIN_STATE_DISABLED)) {
capwap_radioadmstate_element_free((void*)data);
capwap_logging_debug("Invalid Radio Administrative State element: invalid state");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_radioadmstate_ops = {
.create_message_element = capwap_radioadmstate_element_create,

View File

@ -20,6 +20,10 @@ static void capwap_radiooprstate_element_create(void* data, capwap_message_eleme
struct capwap_radiooprstate_element* element = (struct capwap_radiooprstate_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
ASSERT((element->state == CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED) || (element->state == CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED));
ASSERT((element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL) || (element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE) ||
(element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE) || (element->cause == CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET));
/* */
func->write_u8(handle, element->radioid);
@ -27,33 +31,6 @@ static void capwap_radiooprstate_element_create(void* data, capwap_message_eleme
func->write_u8(handle, element->cause);
}
/* */
static void* capwap_radiooprstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_radiooprstate_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 3) {
capwap_logging_debug("Invalid Radio Operational State element");
return NULL;
}
/* */
data = (struct capwap_radiooprstate_element*)capwap_alloc(sizeof(struct capwap_radiooprstate_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_radiooprstate_element));
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->state);
func->read_u8(handle, &data->cause);
return data;
}
/* */
static void capwap_radiooprstate_element_free(void* data) {
ASSERT(data != NULL);
@ -61,6 +38,49 @@ static void capwap_radiooprstate_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_radiooprstate_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_radiooprstate_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 3) {
capwap_logging_debug("Invalid Radio Operational State element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_radiooprstate_element*)capwap_alloc(sizeof(struct capwap_radiooprstate_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->state);
func->read_u8(handle, &data->cause);
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_radiooprstate_element_free((void*)data);
capwap_logging_debug("Invalid Radio Operational State element: invalid radioid");
return NULL;
} else if ((data->state != CAPWAP_RADIO_OPERATIONAL_STATE_ENABLED) && (data->state != CAPWAP_RADIO_OPERATIONAL_STATE_DISABLED)) {
capwap_radiooprstate_element_free((void*)data);
capwap_logging_debug("Invalid Radio Operational State element: invalid state");
return NULL;
} else if ((data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_NORMAL) &&
(data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_RADIOFAILURE) &&
(data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_SOFTWAREFAILURE) &&
(data->cause != CAPWAP_RADIO_OPERATIONAL_CAUSE_ADMINSET)) {
capwap_radiooprstate_element_free((void*)data);
capwap_logging_debug("Invalid Radio Operational State element: invalid cause");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_radiooprstate_ops = {
.create_message_element = capwap_radiooprstate_element_create,

View File

@ -20,36 +20,12 @@ static void capwap_resultcode_element_create(void* data, capwap_message_elements
struct capwap_resultcode_element* element = (struct capwap_resultcode_element*)data;
ASSERT(data != NULL);
ASSERT((element->code >= CAPWAP_RESULTCODE_FIRST) && (element->code <= CAPWAP_RESULTCODE_LAST));
/* */
func->write_u32(handle, element->code);
}
/* */
static void* capwap_resultcode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_resultcode_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 4) {
capwap_logging_debug("Invalid Result Code element");
return NULL;
}
/* */
data = (struct capwap_resultcode_element*)capwap_alloc(sizeof(struct capwap_resultcode_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_resultcode_element));
func->read_u32(handle, &data->code);
return data;
}
/* */
static void capwap_resultcode_element_free(void* data) {
ASSERT(data != NULL);
@ -57,6 +33,35 @@ static void capwap_resultcode_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_resultcode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_resultcode_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 4) {
capwap_logging_debug("Invalid Result Code element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_resultcode_element*)capwap_alloc(sizeof(struct capwap_resultcode_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u32(handle, &data->code);
if ((data->code < CAPWAP_RESULTCODE_FIRST) || (data->code > CAPWAP_RESULTCODE_LAST)) {
capwap_resultcode_element_free((void*)data);
capwap_logging_debug("Invalid Result Code element: invalid code");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_resultcode_ops = {
.create_message_element = capwap_resultcode_element_create,

View File

@ -3,6 +3,7 @@
#define CAPWAP_ELEMENT_RESULTCODE 33
#define CAPWAP_RESULTCODE_FIRST 0
#define CAPWAP_RESULTCODE_SUCCESS 0
#define CAPWAP_RESULTCODE_FAILURE 1
#define CAPWAP_RESULTCODE_SUCCESS_NAT_DETECTED 2
@ -26,6 +27,7 @@
#define CAPWAP_RESULTCODE_FAILURE_MISSING_MANDATORY_MSG_ELEMENT 20
#define CAPWAP_RESULTCODE_FAILURE_UNRECOGNIZED_MESSAGE_ELEMENT 21
#define CAPWAP_RESULTCODE_DATA_TRANSFER_ERROR 22
#define CAPWAP_RESULTCODE_LAST 22
struct capwap_resultcode_element {
uint32_t code;

View File

@ -20,12 +20,28 @@ static void capwap_returnedmessage_element_create(void* data, capwap_message_ele
struct capwap_returnedmessage_element* element = (struct capwap_returnedmessage_element*)data;
ASSERT(data != NULL);
ASSERT(element->length >= 4);
ASSERT((element->reason == CAPWAP_RETURNED_MESSAGE_UNKNOWN_MESSAGE_ELEMENT) || (element->reason == CAPWAP_RETURNED_MESSAGE_UNSUPPORTED_MESSAGE_ELEMENT) ||
(element->reason == CAPWAP_RETURNED_MESSAGE_UNKNOWN_MESSAGE_ELEMENT_VALUE) || (element->reason == CAPWAP_RETURNED_MESSAGE_UNSUPPORTED_MESSAGE_ELEMENT_VALUE));
func->write_u8(handle, element->reason);
func->write_u8(handle, element->length);
func->write_block(handle, element->message, element->length);
}
/* */
static void capwap_returnedmessage_element_free(void* data) {
struct capwap_returnedmessage_element* element = (struct capwap_returnedmessage_element*)data;
ASSERT(data != NULL);
if (element->message) {
capwap_free(element->message);
}
capwap_free(data);
}
/* */
static void* capwap_returnedmessage_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
unsigned short length;
@ -36,13 +52,13 @@ static void* capwap_returnedmessage_element_parsing(capwap_message_elements_hand
length = func->read_ready(handle);
if (length < 6) {
capwap_logging_debug("Invalid Returned Message element");
capwap_logging_debug("Invalid Returned Message element: underbuffer");
return NULL;
}
length -= 2;
if (length > CAPWAP_RETURNED_MESSAGE_MAX_LENGTH) {
capwap_logging_debug("Invalid Returned Message element");
capwap_logging_debug("Invalid Returned Message element: overbuffer");
return NULL;
}
@ -56,18 +72,30 @@ static void* capwap_returnedmessage_element_parsing(capwap_message_elements_hand
memset(data, 0, sizeof(struct capwap_returnedmessage_element));
func->read_u8(handle, &data->reason);
func->read_u8(handle, &data->length);
if ((data->reason != CAPWAP_RETURNED_MESSAGE_UNKNOWN_MESSAGE_ELEMENT) &&
(data->reason != CAPWAP_RETURNED_MESSAGE_UNSUPPORTED_MESSAGE_ELEMENT) &&
(data->reason != CAPWAP_RETURNED_MESSAGE_UNKNOWN_MESSAGE_ELEMENT_VALUE) &&
(data->reason != CAPWAP_RETURNED_MESSAGE_UNSUPPORTED_MESSAGE_ELEMENT_VALUE)) {
capwap_returnedmessage_element_free((void*)data);
capwap_logging_debug("Invalid Returned Message element: invalid reason");
return NULL;
} else if (data->length != length) {
capwap_returnedmessage_element_free((void*)data);
capwap_logging_debug("Invalid Returned Message element: invalid length");
return NULL;
}
data->message = (uint8_t*)capwap_alloc(data->length);
if (!data->message) {
capwap_outofmemory();
}
func->read_block(handle, data->message, data->length);
return data;
}
/* */
static void capwap_returnedmessage_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(data);
}
/* */
struct capwap_message_elements_ops capwap_element_returnedmessage_ops = {
.create_message_element = capwap_returnedmessage_element_create,

View File

@ -3,17 +3,17 @@
#define CAPWAP_ELEMENT_RETURNEDMESSAGE 34
#define CAPWAP_REASON_UNKNOWN_MESSAGE_ELEMENT 1
#define CAPWAP_REASON_UNSUPPORTED_MESSAGE_ELEMENT 2
#define CAPWAP_REASON_UNKNOWN_MESSAGE_ELEMENT_VALUE 3
#define CAPWAP_REASON_UNSUPPORTED_MESSAGE_ELEMENT_VALUE 4
#define CAPWAP_RETURNED_MESSAGE_UNKNOWN_MESSAGE_ELEMENT 1
#define CAPWAP_RETURNED_MESSAGE_UNSUPPORTED_MESSAGE_ELEMENT 2
#define CAPWAP_RETURNED_MESSAGE_UNKNOWN_MESSAGE_ELEMENT_VALUE 3
#define CAPWAP_RETURNED_MESSAGE_UNSUPPORTED_MESSAGE_ELEMENT_VALUE 4
#define CAPWAP_RETURNED_MESSAGE_MAX_LENGTH 255
struct capwap_returnedmessage_element {
uint8_t reason;
uint8_t length;
uint8_t message[CAPWAP_RETURNED_MESSAGE_MAX_LENGTH];
uint8_t* message;
};
extern struct capwap_message_elements_ops capwap_element_returnedmessage_ops;

View File

@ -28,7 +28,7 @@ void capwap_sessionid_generate(struct capwap_sessionid_element* session) {
ASSERT(session != NULL);
for (i = 0; i < 16; i++) {
session->id[i] = (unsigned char)capwap_get_rand(256);
session->id[i] = (uint8_t)capwap_get_rand(256);
}
}
@ -65,7 +65,7 @@ static void* capwap_sessionid_element_parsing(capwap_message_elements_handle han
ASSERT(func != NULL);
if (func->read_ready(handle) != 16) {
capwap_logging_debug("Invalid Session ID element");
capwap_logging_debug("Invalid Session ID element: underbuffer");
return NULL;
}
@ -76,7 +76,6 @@ static void* capwap_sessionid_element_parsing(capwap_message_elements_handle han
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_sessionid_element));
func->read_block(handle, data->id, 16);
return data;

View File

@ -33,7 +33,7 @@ static void* capwap_statisticstimer_element_parsing(capwap_message_elements_hand
ASSERT(func != NULL);
if (func->read_ready(handle) != 2) {
capwap_logging_debug("Invalid Statistics Timer element");
capwap_logging_debug("Invalid Statistics Timer element: underbuffer");
return NULL;
}
@ -44,7 +44,6 @@ static void* capwap_statisticstimer_element_parsing(capwap_message_elements_hand
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_statisticstimer_element));
func->read_u16(handle, &data->timer);
return data;

View File

@ -34,7 +34,7 @@ static void* capwap_timers_element_parsing(capwap_message_elements_handle handle
ASSERT(func != NULL);
if (func->read_ready(handle) != 2) {
capwap_logging_debug("Invalid Timers element");
capwap_logging_debug("Invalid Timers element: underbuffer");
return NULL;
}
@ -45,7 +45,6 @@ static void* capwap_timers_element_parsing(capwap_message_elements_handle handle
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_timers_element));
func->read_u8(handle, &data->discovery);
func->read_u8(handle, &data->echorequest);

View File

@ -20,36 +20,12 @@ static void capwap_transport_element_create(void* data, capwap_message_elements_
struct capwap_transport_element* element = (struct capwap_transport_element*)data;
ASSERT(data != NULL);
ASSERT((element->type == CAPWAP_UDPLITE_TRANSPORT) || (element->type == CAPWAP_UDP_TRANSPORT));
/* */
func->write_u8(handle, element->type);
}
/* */
static void* capwap_transport_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_transport_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid Transport Protocol element");
return NULL;
}
/* */
data = (struct capwap_transport_element*)capwap_alloc(sizeof(struct capwap_transport_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_transport_element));
func->read_u8(handle, &data->type);
return data;
}
/* */
static void capwap_transport_element_free(void* data) {
ASSERT(data != NULL);
@ -57,6 +33,35 @@ static void capwap_transport_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_transport_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_transport_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid Transport Protocol element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_transport_element*)capwap_alloc(sizeof(struct capwap_transport_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->type);
if ((data->type != CAPWAP_UDPLITE_TRANSPORT) && (data->type != CAPWAP_UDP_TRANSPORT)) {
capwap_transport_element_free((void*)data);
capwap_logging_debug("Invalid Transport Protocol element: invalid type");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_transport_ops = {
.create_message_element = capwap_transport_element_create,

View File

@ -22,12 +22,26 @@ static void capwap_vendorpayload_element_create(void* data, capwap_message_eleme
struct capwap_vendorpayload_element* element = (struct capwap_vendorpayload_element*)data;
ASSERT(data != NULL);
ASSERT(element->datalength > 0);
func->write_u32(handle, element->vendorid);
func->write_u16(handle, element->elementid);
func->write_block(handle, element->data, element->datalength);
}
/* */
static void capwap_vendorpayload_element_free(void* data) {
struct capwap_vendorpayload_element* element = (struct capwap_vendorpayload_element*)data;
ASSERT(data != NULL);
if (element->data) {
capwap_free(element->data);
}
capwap_free(data);
}
/* */
static void* capwap_vendorpayload_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
unsigned short length;
@ -38,13 +52,13 @@ static void* capwap_vendorpayload_element_parsing(capwap_message_elements_handle
length = func->read_ready(handle);
if (length < 7) {
capwap_logging_debug("Invalid Vendor Specific Payload element");
capwap_logging_debug("Invalid Vendor Specific Payload element: underbuffer");
return NULL;
}
length -= 6;
if (length > CAPWAP_VENDORPAYLOAD_MAXLENGTH) {
capwap_logging_debug("Invalid Vendor Specific Payload element");
capwap_logging_debug("Invalid Vendor Specific Payload element: overbuffer");
return NULL;
}
@ -54,22 +68,20 @@ static void* capwap_vendorpayload_element_parsing(capwap_message_elements_handle
capwap_outofmemory();
}
data->data = (uint8_t*)capwap_alloc(length);
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_vendorpayload_element));
func->read_u32(handle, &data->vendorid);
func->read_u16(handle, &data->elementid);
data->datalength = length;
func->read_block(handle, data->data, length);
return data;
}
/* */
static void capwap_vendorpayload_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(data);
}
/* */
struct capwap_message_elements_ops capwap_element_vendorpayload_ops = {
.create_message_element = capwap_vendorpayload_element_create,

View File

@ -9,7 +9,7 @@ struct capwap_vendorpayload_element {
uint32_t vendorid;
uint16_t elementid;
uint16_t datalength;
uint8_t data[CAPWAP_VENDORPAYLOAD_MAXLENGTH];
uint8_t* data;
};
extern struct capwap_message_elements_ops capwap_element_vendorpayload_ops;

View File

@ -32,6 +32,8 @@ static void capwap_wtpboarddata_element_create(void* data, capwap_message_elemen
struct capwap_wtpboarddata_element* element = (struct capwap_wtpboarddata_element*)data;
ASSERT(data != NULL);
ASSERT(element->vendor != 0);
ASSERT(element->boardsubelement->count > 0);
/* */
func->write_u32(handle, element->vendor);
@ -40,6 +42,9 @@ static void capwap_wtpboarddata_element_create(void* data, capwap_message_elemen
for (i = 0; i < element->boardsubelement->count; i++) {
struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(element->boardsubelement, i);
ASSERT((desc->type >= CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST) && (desc->type <= CAPWAP_BOARD_SUBELEMENT_TYPE_LAST));
ASSERT((desc->length > 0) && (desc->length <= CAPWAP_BOARD_SUBELEMENT_MAXDATA));
func->write_u16(handle, desc->type);
func->write_u16(handle, desc->length);
func->write_block(handle, desc->data, desc->length);
@ -48,13 +53,23 @@ static void capwap_wtpboarddata_element_create(void* data, capwap_message_elemen
/* */
static void capwap_wtpboarddata_element_free(void* data) {
struct capwap_wtpboarddata_element* dataelement = (struct capwap_wtpboarddata_element*)data;
int i;
struct capwap_wtpboarddata_element* element = (struct capwap_wtpboarddata_element*)data;
ASSERT(dataelement != NULL);
ASSERT(dataelement->boardsubelement != NULL);
ASSERT(data != NULL);
ASSERT(element->boardsubelement != NULL);
capwap_array_free(dataelement->boardsubelement);
capwap_free(dataelement);
/* */
for (i = 0; i < element->boardsubelement->count; i++) {
struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(element->boardsubelement, i);
if (desc->data) {
capwap_free(desc->data);
}
}
capwap_array_free(element->boardsubelement);
capwap_free(data);
}
/* */
@ -65,7 +80,7 @@ static void* capwap_wtpboarddata_element_parsing(capwap_message_elements_handle
ASSERT(func != NULL);
if (func->read_ready(handle) < 14) {
capwap_logging_debug("Invalid WTP Board Data element");
capwap_logging_debug("Invalid WTP Board Data element: underbuffer");
return NULL;
}
@ -79,6 +94,11 @@ static void* capwap_wtpboarddata_element_parsing(capwap_message_elements_handle
/* Retrieve data */
func->read_u32(handle, &data->vendor);
if (!data->vendor) {
capwap_wtpboarddata_element_free((void*)data);
capwap_logging_debug("Invalid WTP Board Data element: invalid vendor");
return NULL;
}
/* WTP Board Data Subelement */
while (func->read_ready(handle) > 0) {
@ -89,14 +109,25 @@ static void* capwap_wtpboarddata_element_parsing(capwap_message_elements_handle
func->read_u16(handle, &desc->type);
func->read_u16(handle, &desc->length);
/* Check buffer size */
length = func->read_ready(handle);
if ((length > CAPWAP_BOARD_SUBELEMENT_MAXDATA) || (length < desc->length)) {
capwap_logging_debug("Invalid WTP Board Data element");
if ((desc->type < CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST) || (desc->type > CAPWAP_BOARD_SUBELEMENT_TYPE_LAST)) {
capwap_logging_debug("Invalid WTP Board Data element: invalid type");
capwap_wtpboarddata_element_free(data);
return NULL;
}
/* Check buffer size */
length = func->read_ready(handle);
if (!length || (length > CAPWAP_BOARD_SUBELEMENT_MAXDATA) || (length < desc->length)) {
capwap_logging_debug("Invalid WTP Board Data element: invalid length");
capwap_wtpboarddata_element_free(data);
return NULL;
}
desc->data = (uint8_t*)capwap_alloc(desc->length);
if (!desc->data) {
capwap_outofmemory();
}
func->read_block(handle, desc->data, desc->length);
}

View File

@ -1,24 +1,27 @@
#ifndef __CAPWAP_ELEMENT_WTPBOARDDATA_HEADER__
#define __CAPWAP_ELEMENT_WTPBOARDDATA_HEADER__
#define CAPWAP_ELEMENT_WTPBOARDDATA 38
#define CAPWAP_ELEMENT_WTPBOARDDATA 38
struct capwap_wtpboarddata_element {
uint32_t vendor;
struct capwap_array* boardsubelement;
};
#define CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST 0
#define CAPWAP_BOARD_SUBELEMENT_MODELNUMBER 0
#define CAPWAP_BOARD_SUBELEMENT_SERIALNUMBER 1
#define CAPWAP_BOARD_SUBELEMENT_ID 2
#define CAPWAP_BOARD_SUBELEMENT_REVISION 3
#define CAPWAP_BOARD_SUBELEMENT_MACADDRESS 4
#define CAPWAP_BOARD_SUBELEMENT_TYPE_LAST 4
#define CAPWAP_BOARD_SUBELEMENT_MAXDATA 1024
struct capwap_wtpboarddata_board_subelement {
uint16_t type;
uint16_t length;
uint8_t data[CAPWAP_BOARD_SUBELEMENT_MAXDATA];
uint8_t* data;
};
extern struct capwap_message_elements_ops capwap_element_wtpboarddata_ops;

View File

@ -40,6 +40,9 @@ static void capwap_wtpdescriptor_element_create(void* data, capwap_message_eleme
struct capwap_wtpdescriptor_element* element = (struct capwap_wtpdescriptor_element*)data;
ASSERT(data != NULL);
ASSERT(element->maxradios >= element->radiosinuse);
ASSERT(element->encryptsubelement->count > 0);
ASSERT(element->descsubelement->count > 0);
/* */
func->write_u8(handle, element->maxradios);
@ -50,7 +53,9 @@ static void capwap_wtpdescriptor_element_create(void* data, capwap_message_eleme
for (i = 0; i < element->encryptsubelement->count; i++) {
struct capwap_wtpdescriptor_encrypt_subelement* desc = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(element->encryptsubelement, i);
func->write_u8(handle, desc->wbid & 0x1f);
ASSERT((desc->wbid & CAPWAP_WTPDESC_SUBELEMENT_WBID_MASK) == desc->wbid);
func->write_u8(handle, desc->wbid);
func->write_u16(handle, desc->capabilities);
}
@ -58,6 +63,9 @@ static void capwap_wtpdescriptor_element_create(void* data, capwap_message_eleme
for (i = 0; i < element->descsubelement->count; i++) {
struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
ASSERT((desc->type >= CAPWAP_WTPDESC_SUBELEMENT_TYPE_FIRST) && (desc->type <= CAPWAP_WTPDESC_SUBELEMENT_TYPE_LAST));
ASSERT(desc->length > 0);
func->write_u32(handle, desc->vendor);
func->write_u16(handle, desc->type);
func->write_u16(handle, desc->length);
@ -67,15 +75,25 @@ static void capwap_wtpdescriptor_element_create(void* data, capwap_message_eleme
/* */
static void capwap_wtpdescriptor_element_free(void* data) {
struct capwap_wtpdescriptor_element* dataelement = (struct capwap_wtpdescriptor_element*)data;
int i;
struct capwap_wtpdescriptor_element* element = (struct capwap_wtpdescriptor_element*)data;
ASSERT(dataelement != NULL);
ASSERT(dataelement->encryptsubelement != NULL);
ASSERT(dataelement->descsubelement != NULL);
ASSERT(data != NULL);
ASSERT(element->encryptsubelement != NULL);
ASSERT(element->descsubelement != NULL);
capwap_array_free(dataelement->encryptsubelement);
capwap_array_free(dataelement->descsubelement);
capwap_free(dataelement);
/* */
for (i = 0; i < element->descsubelement->count; i++) {
struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
if (desc->data) {
capwap_free(desc->data);
}
}
capwap_array_free(element->encryptsubelement);
capwap_array_free(element->descsubelement);
capwap_free(data);
}
/* */
@ -88,7 +106,7 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
ASSERT(func != NULL);
if (func->read_ready(handle) < 33) {
capwap_logging_debug("Invalid WTP Descriptor element");
capwap_logging_debug("Invalid WTP Descriptor element: underbufer");
return NULL;
}
@ -108,8 +126,12 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
/* Check */
if (!encryptlength) {
capwap_logging_debug("Invalid WTP Descriptor element");
capwap_wtpdescriptor_element_free(data);
capwap_logging_debug("Invalid WTP Descriptor element: invalid encryptlength");
return NULL;
} else if (data->maxradios < data->radiosinuse) {
capwap_wtpdescriptor_element_free(data);
capwap_logging_debug("Invalid WTP Descriptor element: invalid radio");
return NULL;
}
@ -119,7 +141,7 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
/* Check */
if (func->read_ready(handle) < 3) {
capwap_logging_debug("Invalid WTP Descriptor element");
capwap_logging_debug("Invalid WTP Descriptor subelement: underbuffer");
capwap_wtpdescriptor_element_free(data);
return NULL;
}
@ -128,6 +150,12 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
desc = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(data->encryptsubelement, data->encryptsubelement->count);
func->read_u8(handle, &desc->wbid);
func->read_u16(handle, &desc->capabilities);
if ((desc->wbid & CAPWAP_WTPDESC_SUBELEMENT_WBID_MASK) != desc->wbid) {
capwap_wtpdescriptor_element_free(data);
capwap_logging_debug("Invalid WTP Descriptor element: invalid wbid");
return NULL;
}
}
/* WTP Description Subelement */
@ -137,7 +165,7 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
/* Check */
if (func->read_ready(handle) < 8) {
capwap_logging_debug("Invalid WTP Descriptor element");
capwap_logging_debug("Invalid WTP Descriptor subelement: underbuffer");
capwap_wtpdescriptor_element_free(data);
return NULL;
}
@ -148,9 +176,15 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
func->read_u16(handle, &desc->type);
func->read_u16(handle, &desc->length);
if ((desc->type < CAPWAP_WTPDESC_SUBELEMENT_TYPE_FIRST) || (desc->type > CAPWAP_WTPDESC_SUBELEMENT_TYPE_LAST)) {
capwap_logging_debug("Invalid WTP Descriptor subelement: invalid type");
capwap_wtpdescriptor_element_free(data);
return NULL;
}
/* Check buffer size */
length = func->read_ready(handle);
if ((length > CAPWAP_WTPDESC_SUBELEMENT_MAXDATA) || (length < desc->length)) {
if (!length || (length > CAPWAP_WTPDESC_SUBELEMENT_MAXDATA) || (length < desc->length)) {
capwap_logging_debug("Invalid WTP Descriptor element");
capwap_wtpdescriptor_element_free(data);
return NULL;

View File

@ -1,7 +1,7 @@
#ifndef __CAPWAP_ELEMENT_WTPDESCRIPTOR_HEADER__
#define __CAPWAP_ELEMENT_WTPDESCRIPTOR_HEADER__
#define CAPWAP_ELEMENT_WTPDESCRIPTOR 39
#define CAPWAP_ELEMENT_WTPDESCRIPTOR 39
struct capwap_wtpdescriptor_element {
uint8_t maxradios;
@ -10,22 +10,27 @@ struct capwap_wtpdescriptor_element {
struct capwap_array* descsubelement;
};
#define CAPWAP_WTPDESC_SUBELEMENT_WBID_MASK 0x1f
struct capwap_wtpdescriptor_encrypt_subelement {
uint8_t wbid;
uint16_t capabilities;
};
#define CAPWAP_WTPDESC_SUBELEMENT_TYPE_FIRST 0
#define CAPWAP_WTPDESC_SUBELEMENT_HARDWAREVERSION 0
#define CAPWAP_WTPDESC_SUBELEMENT_SOFTWAREVERSION 1
#define CAPWAP_WTPDESC_SUBELEMENT_BOOTVERSION 2
#define CAPWAP_WTPDESC_SUBELEMENT_OTHERVERSION 3
#define CAPWAP_WTPDESC_SUBELEMENT_TYPE_LAST 3
#define CAPWAP_WTPDESC_SUBELEMENT_MAXDATA 1024
struct capwap_wtpdescriptor_desc_subelement {
uint32_t vendor;
uint16_t type;
uint16_t length;
uint8_t data[CAPWAP_WTPDESC_SUBELEMENT_MAXDATA];
uint8_t* data;
};
extern struct capwap_message_elements_ops capwap_element_wtpdescriptor_ops;

View File

@ -20,36 +20,12 @@ static void capwap_wtpfallback_element_create(void* data, capwap_message_element
struct capwap_wtpfallback_element* element = (struct capwap_wtpfallback_element*)data;
ASSERT(data != NULL);
ASSERT((element->mode == CAPWAP_WTP_FALLBACK_ENABLED) || (element->mode == CAPWAP_WTP_FALLBACK_DISABLED));
/* */
func->write_u8(handle, element->mode);
}
/* */
static void* capwap_wtpfallback_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_wtpfallback_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid WTP Fallback element");
return NULL;
}
/* */
data = (struct capwap_wtpfallback_element*)capwap_alloc(sizeof(struct capwap_wtpfallback_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_wtpfallback_element));
func->read_u8(handle, &data->mode);
return data;
}
/* */
static void capwap_wtpfallback_element_free(void* data) {
ASSERT(data != NULL);
@ -57,6 +33,35 @@ static void capwap_wtpfallback_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_wtpfallback_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_wtpfallback_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid WTP Fallback element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_wtpfallback_element*)capwap_alloc(sizeof(struct capwap_wtpfallback_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->mode);
if ((data->mode != CAPWAP_WTP_FALLBACK_ENABLED) && (data->mode != CAPWAP_WTP_FALLBACK_DISABLED)) {
capwap_wtpfallback_element_free((void*)data);
capwap_logging_debug("Invalid WTP Fallback element: invalid mode");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_wtpfallback_ops = {
.create_message_element = capwap_wtpfallback_element_create,

View File

@ -20,34 +20,10 @@ static void capwap_wtpframetunnelmode_element_create(void* data, capwap_message_
struct capwap_wtpframetunnelmode_element* element = (struct capwap_wtpframetunnelmode_element*)data;
ASSERT(data != NULL);
ASSERT((element->mode & CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK) == element->mode);
/* */
func->write_u8(handle, element->mode & CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK);
}
/* */
static void* capwap_wtpframetunnelmode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_wtpframetunnelmode_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid WTP Frame Tunnel Mode element");
return NULL;
}
/* */
data = (struct capwap_wtpframetunnelmode_element*)capwap_alloc(sizeof(struct capwap_wtpframetunnelmode_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_wtpframetunnelmode_element));
func->read_u8(handle, &data->mode);
return data;
func->write_u8(handle, element->mode);
}
/* */
@ -57,6 +33,35 @@ static void capwap_wtpframetunnelmode_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_wtpframetunnelmode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_wtpframetunnelmode_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid WTP Frame Tunnel Mode element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_wtpframetunnelmode_element*)capwap_alloc(sizeof(struct capwap_wtpframetunnelmode_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->mode);
if ((data->mode & CAPWAP_WTP_FRAME_TUNNEL_MODE_MASK) != data->mode) {
capwap_wtpframetunnelmode_element_free((void*)data);
capwap_logging_debug("Invalid WTP Frame Tunnel Mode element: invalid mode");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_wtpframetunnelmode_ops = {
.create_message_element = capwap_wtpframetunnelmode_element_create,

View File

@ -20,36 +20,12 @@ static void capwap_wtpmactype_element_create(void* data, capwap_message_elements
struct capwap_wtpmactype_element* element = (struct capwap_wtpmactype_element*)data;
ASSERT(data != NULL);
ASSERT((element->type == CAPWAP_LOCALMAC) || (element->type == CAPWAP_SPLITMAC) || (element->type == CAPWAP_LOCALANDSPLITMAC));
/* */
func->write_u8(handle, element->type);
}
/* */
static void* capwap_wtpmactype_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_wtpmactype_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid ECN Support element");
return NULL;
}
/* */
data = (struct capwap_wtpmactype_element*)capwap_alloc(sizeof(struct capwap_wtpmactype_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_wtpmactype_element));
func->read_u8(handle, &data->type);
return data;
}
/* */
static void capwap_wtpmactype_element_free(void* data) {
ASSERT(data != NULL);
@ -57,6 +33,35 @@ static void capwap_wtpmactype_element_free(void* data) {
capwap_free(data);
}
/* */
static void* capwap_wtpmactype_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_wtpmactype_element* data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) != 1) {
capwap_logging_debug("Invalid WTP MAC Type element: underbuffer");
return NULL;
}
/* */
data = (struct capwap_wtpmactype_element*)capwap_alloc(sizeof(struct capwap_wtpmactype_element));
if (!data) {
capwap_outofmemory();
}
/* Retrieve data */
func->read_u8(handle, &data->type);
if ((data->type != CAPWAP_LOCALMAC) && (data->type != CAPWAP_SPLITMAC) && (data->type != CAPWAP_LOCALANDSPLITMAC)) {
capwap_wtpmactype_element_free((void*)data);
capwap_logging_debug("Invalid WTP MAC Type element: invalid type");
return NULL;
}
return data;
}
/* */
struct capwap_message_elements_ops capwap_element_wtpmactype_ops = {
.create_message_element = capwap_wtpmactype_element_create,

View File

@ -3,8 +3,9 @@
#define CAPWAP_ELEMENT_WTPMACTYPE 44
#define CAPWAP_LOCALMAC 0
#define CAPWAP_SPLITMAC 1
#define CAPWAP_LOCALMAC 0
#define CAPWAP_SPLITMAC 1
#define CAPWAP_LOCALANDSPLITMAC 2
struct capwap_wtpmactype_element {
uint8_t type;

View File

@ -17,11 +17,15 @@ Length: >= 1
/* */
static void capwap_wtpname_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
int length;
struct capwap_wtpname_element* element = (struct capwap_wtpname_element*)data;
ASSERT(data != NULL);
func->write_block(handle, element->name, strlen((char*)element->name));
length = strlen((char*)element->name);
ASSERT(length > 0);
func->write_block(handle, element->name, length);
}
/* */
@ -34,7 +38,7 @@ static void* capwap_wtpname_element_parsing(capwap_message_elements_handle handl
length = func->read_ready(handle);
if ((length < 1) || (length > CAPWAP_WTPNAME_MAXLENGTH)) {
capwap_logging_debug("Invalid WTP Name element");
capwap_logging_debug("Invalid WTP Name element: underbuffer");
return NULL;
}
@ -44,17 +48,28 @@ static void* capwap_wtpname_element_parsing(capwap_message_elements_handle handl
capwap_outofmemory();
}
data->name = (uint8_t*)capwap_alloc(length + 1);
if (!data->name) {
capwap_outofmemory();
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_wtpname_element));
func->read_block(handle, data->name, length);
data->name[length] = 0;
return data;
}
/* */
static void capwap_wtpname_element_free(void* data) {
struct capwap_wtpname_element* element = (struct capwap_wtpname_element*)data;
ASSERT(data != NULL);
if (element->name) {
capwap_free(element->name);
}
capwap_free(data);
}

View File

@ -6,7 +6,7 @@
#define CAPWAP_WTPNAME_MAXLENGTH 512
struct capwap_wtpname_element {
uint8_t name[CAPWAP_WTPNAME_MAXLENGTH + 1];
uint8_t* name;
};
extern struct capwap_message_elements_ops capwap_element_wtpname_ops;

View File

@ -28,6 +28,7 @@ static void capwap_wtpradiostat_element_create(void* data, capwap_message_elemen
struct capwap_wtpradiostat_element* element = (struct capwap_wtpradiostat_element*)data;
ASSERT(data != NULL);
ASSERT(IS_VALID_RADIOID(element->radioid));
/* */
func->write_u8(handle, element->radioid);
@ -43,6 +44,13 @@ static void capwap_wtpradiostat_element_create(void* data, capwap_message_elemen
func->write_u16(handle, element->currentnoisefloor);
}
/* */
static void capwap_wtpradiostat_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(data);
}
/* */
static void* capwap_wtpradiostat_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
struct capwap_wtpradiostat_element* data;
@ -51,7 +59,7 @@ static void* capwap_wtpradiostat_element_parsing(capwap_message_elements_handle
ASSERT(func != NULL);
if (func->read_ready(handle) != 20) {
capwap_logging_debug("Invalid WTP Radio Statistics element");
capwap_logging_debug("Invalid WTP Radio Statistics element: underbuffer");
return NULL;
}
@ -62,8 +70,13 @@ static void* capwap_wtpradiostat_element_parsing(capwap_message_elements_handle
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_wtpradiostat_element));
func->read_u8(handle, &data->radioid);
if (!IS_VALID_RADIOID(data->radioid)) {
capwap_wtpradiostat_element_free((void*)data);
capwap_logging_debug("Invalid WTP Radio Statistics element: invalid radioid");
return NULL;
}
func->read_u8(handle, &data->lastfailtype);
func->read_u16(handle, &data->resetcount);
func->read_u16(handle, &data->swfailercount);
@ -78,13 +91,6 @@ static void* capwap_wtpradiostat_element_parsing(capwap_message_elements_handle
return data;
}
/* */
static void capwap_wtpradiostat_element_free(void* data) {
ASSERT(data != NULL);
capwap_free(data);
}
/* */
struct capwap_message_elements_ops capwap_element_wtpradiostat_ops = {
.create_message_element = capwap_wtpradiostat_element_create,

View File

@ -1,7 +1,7 @@
#ifndef __CAPWAP_ELEMENT_WTPRADIOSTAT_HEADER__
#define __CAPWAP_ELEMENT_WTPRADIOSTAT_HEADER__
#define CAPWAP_ELEMENT_WTPRADIOSTAT 47
#define CAPWAP_ELEMENT_WTPRADIOSTAT 47
#define CAPWAP_WTPRADIOSTAT_FAILER_TYPE_STATNOTSUPP 0
#define CAPWAP_WTPRADIOSTAT_FAILER_TYPE_SWFAIL 1

View File

@ -46,7 +46,7 @@ static void* capwap_wtprebootstat_element_parsing(capwap_message_elements_handle
ASSERT(func != NULL);
if (func->read_ready(handle) != 15) {
capwap_logging_debug("Invalid WTP Reboot Statistics element");
capwap_logging_debug("Invalid WTP Reboot Statistics element: underbuffer");
return NULL;
}
@ -57,7 +57,6 @@ static void* capwap_wtprebootstat_element_parsing(capwap_message_elements_handle
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_wtprebootstat_element));
func->read_u16(handle, &data->rebootcount);
func->read_u16(handle, &data->acinitiatedcount);
func->read_u16(handle, &data->linkfailurecount);

View File

@ -42,7 +42,7 @@ static void* capwap_wtpstaticipaddress_element_parsing(capwap_message_elements_h
ASSERT(func != NULL);
if (func->read_ready(handle) != 13) {
capwap_logging_debug("Invalid WTP Static IP Address Information element");
capwap_logging_debug("Invalid WTP Static IP Address Information element: underbuffer");
return NULL;
}
@ -53,7 +53,6 @@ static void* capwap_wtpstaticipaddress_element_parsing(capwap_message_elements_h
}
/* Retrieve data */
memset(data, 0, sizeof(struct capwap_wtpstaticipaddress_element));
func->read_block(handle, (uint8_t*)&data->address, sizeof(struct in_addr));
func->read_block(handle, (uint8_t*)&data->netmask, sizeof(struct in_addr));
func->read_block(handle, (uint8_t*)&data->gateway, sizeof(struct in_addr));

View File

@ -195,4 +195,19 @@ struct capwap_macaddress_eui64 {
#define IS_VALID_MACADDRESS_LENGTH(x) ((x == MACADDRESS_EUI48_LENGTH) || (x == MACADDRESS_EUI64_LENGTH))
#define IS_VALID_RADIOID(x) ((x >= 1) && (x <= 31))
#define IS_VALID_WLANID(x) ((x >= 1) && (x <= 16))
/* Standard message elements 1 -> 52 (1 - 1023) */
#define CAPWAP_MESSAGE_ELEMENTS_START 1
#define CAPWAP_MESSAGE_ELEMENTS_STOP 53
#define CAPWAP_MESSAGE_ELEMENTS_COUNT ((CAPWAP_MESSAGE_ELEMENTS_STOP - CAPWAP_MESSAGE_ELEMENTS_START) + 1)
#define IS_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
/* 802.11 message elements 1024 -> 1024 (1024 - 2047) */
#define CAPWAP_80211_MESSAGE_ELEMENTS_START 1024
#define CAPWAP_80211_MESSAGE_ELEMENTS_STOP 1048
#define CAPWAP_80211_MESSAGE_ELEMENTS_COUNT ((CAPWAP_80211_MESSAGE_ELEMENTS_STOP - CAPWAP_80211_MESSAGE_ELEMENTS_START) + 1)
#define IS_80211_MESSAGE_ELEMENTS(x) (((x >= CAPWAP_80211_MESSAGE_ELEMENTS_START) && (x <= CAPWAP_80211_MESSAGE_ELEMENTS_STOP)) ? 1 : 0)
#endif /* __CAPWAP_RFC_HEADER__ */

View File

@ -25,9 +25,9 @@ static int wtp_init(void) {
memset(&g_wtp, 0, sizeof(struct wtp_t));
/* Standard name */
strcpy((char*)g_wtp.name.name, WTP_STANDARD_NAME);
strcpy((char*)g_wtp.location.value, WTP_STANDARD_LOCATION);
g_wtp.name.name = (uint8_t*)capwap_duplicate_string(WTP_STANDARD_NAME);
g_wtp.location.value = (uint8_t*)capwap_duplicate_string(WTP_STANDARD_LOCATION);
/* State machine */
g_wtp.dfa.state = CAPWAP_START_STATE;
g_wtp.dfa.rfcMaxDiscoveryInterval = WTP_DEFAULT_DISCOVERY_INTERVAL;
@ -44,7 +44,7 @@ static int wtp_init(void) {
/* Socket */
capwap_network_init(&g_wtp.net);
/* Standard configuration */
g_wtp.boarddata.boardsubelement = capwap_array_create(sizeof(struct capwap_wtpboarddata_board_subelement), 0, 1);
g_wtp.descriptor.encryptsubelement = capwap_array_create(sizeof(struct capwap_wtpdescriptor_encrypt_subelement), 0, 0);
@ -58,17 +58,17 @@ static int wtp_init(void) {
g_wtp.mactype.type = CAPWAP_LOCALMAC;
g_wtp.mactunnel.mode = CAPWAP_WTP_LOCAL_BRIDGING;
/* DTLS */
g_wtp.validdtlsdatapolicy = CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED;
/* Tx fragment packets */
g_wtp.mtu = CAPWAP_MTU_DEFAULT;
g_wtp.requestfragmentpacket = capwap_list_create();
g_wtp.responsefragmentpacket = capwap_list_create();
/* AC information */
g_wtp.discoverytype.type = CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_UNKNOWN;
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_UNKNOWN;
g_wtp.acdiscoveryrequest = 1;
g_wtp.acdiscoveryarray = capwap_array_create(sizeof(struct sockaddr_storage), 0, 0);
g_wtp.acpreferedarray = capwap_array_create(sizeof(struct sockaddr_storage), 0, 0);
@ -82,25 +82,48 @@ static int wtp_init(void) {
/* Destroy WTP */
static void wtp_destroy(void) {
int i;
/* Dtls */
capwap_crypt_freecontext(&g_wtp.dtlscontext);
/* Free standard configuration */
capwap_array_free(g_wtp.descriptor.encryptsubelement);
for (i = 0; i < g_wtp.descriptor.descsubelement->count; i++) {
struct capwap_wtpdescriptor_desc_subelement* element = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(g_wtp.descriptor.descsubelement, i);
if (element->data) {
capwap_free(element->data);
}
}
for (i = 0; i < g_wtp.boarddata.boardsubelement->count; i++) {
struct capwap_wtpboarddata_board_subelement* element = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(g_wtp.boarddata.boardsubelement, i);
if (element->data) {
capwap_free(element->data);
}
}
capwap_array_free(g_wtp.descriptor.descsubelement);
capwap_array_free(g_wtp.boarddata.boardsubelement);
/* Free fragments packet */
capwap_list_free(g_wtp.requestfragmentpacket);
capwap_list_free(g_wtp.responsefragmentpacket);
/* Free list AC */
capwap_array_free(g_wtp.acdiscoveryarray);
capwap_array_free(g_wtp.acpreferedarray);
wtp_free_discovery_response_array();
capwap_array_free(g_wtp.acdiscoveryresponse);
/* Free local message elements */
capwap_free(g_wtp.name.name);
capwap_free(g_wtp.location.value);
/* Free radios */
capwap_array_free(g_wtp.radios);
}
@ -221,7 +244,8 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
return 0;
}
strcpy((char*)g_wtp.name.name, configString);
capwap_free(g_wtp.name.name);
g_wtp.name.name = (uint8_t*)capwap_duplicate_string(configString);
}
/* Set location of WTP */
@ -231,7 +255,8 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
return 0;
}
strcpy((char*)g_wtp.location.value, configString);
capwap_free(g_wtp.location.value);
g_wtp.location.value = (uint8_t*)capwap_duplicate_string(configString);
}
/* Set binding of WTP */
@ -327,29 +352,34 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
if (!strcmp(configName, "model")) {
element->type = CAPWAP_BOARD_SUBELEMENT_MODELNUMBER;
element->length = lengthValue;
strcpy((char*)element->data, configValue);
element->data = (uint8_t*)capwap_clone((void*)configValue, lengthValue);
} else if (!strcmp(configName, "serial")) {
element->type = CAPWAP_BOARD_SUBELEMENT_SERIALNUMBER;
element->length = lengthValue;
strcpy((char*)element->data, configValue);
element->data = (uint8_t*)capwap_clone((void*)configValue, lengthValue);
} else if (!strcmp(configName, "id")) {
element->type = CAPWAP_BOARD_SUBELEMENT_ID;
element->length = lengthValue;
strcpy((char*)element->data, configValue);
element->data = (uint8_t*)capwap_clone((void*)configValue, lengthValue);
} else if (!strcmp(configName, "revision")) {
element->type = CAPWAP_BOARD_SUBELEMENT_REVISION;
element->length = lengthValue;
strcpy((char*)element->data, configValue);
element->data = (uint8_t*)capwap_clone((void*)configValue, lengthValue);
} else if (!strcmp(configName, "macaddress")) {
const char* configType;
if (config_setting_lookup_string(configElement, "type", &configType) == CONFIG_TRUE) {
if (!strcmp(configType, "interface")) {
char macaddress[MACADDRESS_EUI64_LENGTH];
/* Retrieve macaddress */
element->type = CAPWAP_BOARD_SUBELEMENT_MACADDRESS;
element->length = capwap_get_macaddress_from_interface(configValue, (char*)element->data);
if (!element->length) {
element->length = capwap_get_macaddress_from_interface(configValue, macaddress);
if (!element->length || ((element->length != MACADDRESS_EUI64_LENGTH) && (element->length != MACADDRESS_EUI48_LENGTH))) {
capwap_logging_error("Invalid configuration file, unable found macaddress of interface: '%s'", configValue);
return 0;
}
element->data = (uint8_t*)capwap_clone((void*)macaddress, element->length);
} else {
capwap_logging_error("Invalid configuration file, unknown application.boardinfo.element.type value");
return 0;
@ -566,7 +596,7 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
desc->vendor = (unsigned long)configVendor;
desc->type = type;
desc->length = lengthValue;
strcpy((char*)desc->data, configValue);
desc->data = (uint8_t*)capwap_clone((void*)configValue, lengthValue);
} else {
capwap_logging_error("Invalid configuration file, application.descriptor.info.value string length exceeded");
return 0;
@ -824,7 +854,7 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
}
wtp_add_acaddress(&acaddr, g_wtp.acdiscoveryarray);
g_wtp.discoverytype.type = CAPWAP_ELEMENT_DISCOVERYTYPE_TYPE_STATIC;
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_STATIC;
} else {
capwap_logging_error("Invalid configuration file, invalid application.acdiscovery.host value");
return 0;

View File

@ -7,11 +7,14 @@
/* */
static unsigned long wtp_configure_ac(struct capwap_parsed_packet* packet) {
struct capwap_timers_element* timers;
/* TODO: gestione richiesta */
/* */
g_wtp.dfa.rfcMaxDiscoveryInterval = packet->messageelements.timers->discovery;
g_wtp.dfa.rfcEchoInterval = packet->messageelements.timers->echorequest;
timers = (struct capwap_timers_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_TIMERS);
g_wtp.dfa.rfcMaxDiscoveryInterval = timers->discovery;
g_wtp.dfa.rfcEchoInterval = timers->echorequest;
return CAPWAP_CONFIGURE_TO_DATA_CHECK_STATE;
}

View File

@ -22,6 +22,7 @@ void wtp_free_discovery_response_array(void) {
/* */
int wtp_dfa_state_discovery(struct capwap_parsed_packet* packet, struct timeout_control* timeout) {
struct capwap_array* controlip;
int status = WTP_DFA_ACCEPT_PACKET;
ASSERT(timeout != NULL);
@ -36,21 +37,27 @@ int wtp_dfa_state_discovery(struct capwap_parsed_packet* packet, struct timeout_
struct wtp_discovery_response* response = (struct wtp_discovery_response*)capwap_array_get_item_pointer(g_wtp.acdiscoveryresponse, g_wtp.acdiscoveryresponse->count);
/* Create controlipv4 */
response->controlipv4 = capwap_array_create(sizeof(struct capwap_controlipv4_element), 0, 0);
for (i = 0; i < packet->messageelements.controlipv4->count; i++) {
struct capwap_controlipv4_element* src = *(struct capwap_controlipv4_element**)capwap_array_get_item_pointer(packet->messageelements.controlipv4, i);
struct capwap_controlipv4_element* dst = (struct capwap_controlipv4_element*)capwap_array_get_item_pointer(response->controlipv4, i);
controlip = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_CONTROLIPV4);
if (controlip) {
response->controlipv4 = capwap_array_create(sizeof(struct capwap_controlipv4_element), 0, 0);
for (i = 0; i < controlip->count; i++) {
struct capwap_controlipv4_element* src = *(struct capwap_controlipv4_element**)capwap_array_get_item_pointer(controlip, i);
struct capwap_controlipv4_element* dst = (struct capwap_controlipv4_element*)capwap_array_get_item_pointer(response->controlipv4, i);
memcpy(dst, src, sizeof(struct capwap_controlipv4_element));
memcpy(dst, src, sizeof(struct capwap_controlipv4_element));
}
}
/* Create controlipv4 */
response->controlipv6 = capwap_array_create(sizeof(struct capwap_controlipv6_element), 0, 0);
for (i = 0; i < packet->messageelements.controlipv6->count; i++) {
struct capwap_controlipv6_element* src = *(struct capwap_controlipv6_element**)capwap_array_get_item_pointer(packet->messageelements.controlipv6, i);
struct capwap_controlipv6_element* dst = (struct capwap_controlipv6_element*)capwap_array_get_item_pointer(response->controlipv6, i);
/* Create controlipv6 */
controlip = (struct capwap_array*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_CONTROLIPV6);
if (controlip) {
response->controlipv6 = capwap_array_create(sizeof(struct capwap_controlipv6_element), 0, 0);
for (i = 0; i < (controlip)->count; i++) {
struct capwap_controlipv6_element* src = *(struct capwap_controlipv6_element**)capwap_array_get_item_pointer((controlip), i);
struct capwap_controlipv6_element* dst = (struct capwap_controlipv6_element*)capwap_array_get_item_pointer(response->controlipv6, i);
memcpy(dst, src, sizeof(struct capwap_controlipv6_element));
memcpy(dst, src, sizeof(struct capwap_controlipv6_element));
}
}
}
} else if (g_wtp.acdiscoveryresponse->count > 0) {

View File

@ -87,6 +87,12 @@ int wtp_dfa_state_dtlsteardown(struct capwap_parsed_packet* packet, struct timeo
capwap_crypt_freesession(&g_wtp.datadtls);
}
/* */
if (g_wtp.acname.name) {
capwap_free(g_wtp.acname.name);
g_wtp.acname.name = NULL;
}
/* */
wtp_free_reference_last_request();
wtp_free_reference_last_response();

View File

@ -7,20 +7,25 @@
/* */
static unsigned long wtp_join_ac(struct capwap_parsed_packet* packet) {
struct capwap_acdescriptor_element* acdescriptor;
struct capwap_acname_element* acname;
/* TODO: gestione richiesta
CAPWAP_JOIN_TO_IMAGE_DATA_STATE <-> CAPWAP_JOIN_TO_CONFIGURE_STATE
*/
/* Check DTLS data policy */
if (!(g_wtp.validdtlsdatapolicy & packet->messageelements.acdescriptor->dtlspolicy)) {
acdescriptor = (struct capwap_acdescriptor_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_ACDESCRIPTION);
if (!(g_wtp.validdtlsdatapolicy & acdescriptor->dtlspolicy)) {
return CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE;
}
/* AC name associated */
strcpy((char*)g_wtp.acname.name, (char*)packet->messageelements.acname->name);
acname = (struct capwap_acname_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_ACNAME);
g_wtp.acname.name = (uint8_t*)capwap_duplicate_string((const char*)acname->name);
/* DTLS data policy */
g_wtp.dtlsdatapolicy = packet->messageelements.acdescriptor->dtlspolicy & g_wtp.validdtlsdatapolicy;
g_wtp.dtlsdatapolicy = acdescriptor->dtlspolicy & g_wtp.validdtlsdatapolicy;
return CAPWAP_JOIN_TO_CONFIGURE_STATE;
}

View File

@ -148,7 +148,7 @@ int wtp_dfa_state_run(struct capwap_parsed_packet* packet, struct timeout_contro
}
} else {
if (IS_FLAG_K_HEADER(packet->rxmngpacket->header) && capwap_is_enable_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD)) {
if (!memcmp(packet->messageelements.sessionid, &g_wtp.sessionid, sizeof(struct capwap_sessionid_element))) {
if (!memcmp(capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID), &g_wtp.sessionid, sizeof(struct capwap_sessionid_element))) {
/* Receive Data Keep-Alive, wait for next packet */
capwap_kill_timeout(timeout, CAPWAP_TIMER_DATA_KEEPALIVEDEAD);
capwap_set_timeout(g_wtp.dfa.rfcDataChannelKeepAlive, timeout, CAPWAP_TIMER_DATA_KEEPALIVE);