diff --git a/src/ac/ac.c b/src/ac/ac.c index c872766..df22935 100644 --- a/src/ac/ac.c +++ b/src/ac/ac.c @@ -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; diff --git a/src/ac/ac_dfa_configure.c b/src/ac/ac_dfa_configure.c index 9f2bbd4..f7401e8 100644 --- a/src/ac/ac_dfa_configure.c +++ b/src/ac/ac_dfa_configure.c @@ -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; diff --git a/src/ac/ac_dfa_datacheck.c b/src/ac/ac_dfa_datacheck.c index 8576d38..2e6ff0f 100644 --- a/src/ac/ac_dfa_datacheck.c +++ b/src/ac/ac_dfa_datacheck.c @@ -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 */ diff --git a/src/ac/ac_dfa_join.c b/src/ac/ac_dfa_join.c index 4fdeefc..40a4131 100644 --- a/src/ac/ac_dfa_join.c +++ b/src/ac/ac_dfa_join.c @@ -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); } } diff --git a/src/ac/ac_dfa_run.c b/src/ac/ac_dfa_run.c index 884a18a..7831132 100644 --- a/src/ac/ac_dfa_run.c +++ b/src/ac/ac_dfa_run.c @@ -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; diff --git a/src/ac/ac_discovery.c b/src/ac/ac_discovery.c index c1b9013..4075c34 100644 --- a/src/ac/ac_discovery.c +++ b/src/ac/ac_discovery.c @@ -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); } } diff --git a/src/ac/ac_execute.c b/src/ac/ac_execute.c index 1405631..3d130f3 100644 --- a/src/ac/ac_execute.c +++ b/src/ac/ac_execute.c @@ -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; diff --git a/src/common/capwap_element.c b/src/common/capwap_element.c index 7648c99..5b94daa 100644 --- a/src/common/capwap_element.c +++ b/src/common/capwap_element.c @@ -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; } /* */ diff --git a/src/common/capwap_element.h b/src/common/capwap_element.h index f6227dd..04dc393 100644 --- a/src/common/capwap_element.h +++ b/src/common/capwap_element.h @@ -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__ */ diff --git a/src/common/capwap_element_80211_addwlan.c b/src/common/capwap_element_80211_addwlan.c index 990519e..0b3f791 100644 --- a/src/common/capwap_element_80211_addwlan.c +++ b/src/common/capwap_element_80211_addwlan.c @@ -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; } diff --git a/src/common/capwap_element_80211_addwlan.h b/src/common/capwap_element_80211_addwlan.h index cd3f55a..04573b0 100644 --- a/src/common/capwap_element_80211_addwlan.h +++ b/src/common/capwap_element_80211_addwlan.h @@ -56,7 +56,6 @@ struct capwap_80211_addwlan_element { uint8_t macmode; uint8_t tunnelmode; uint8_t suppressssid; - uint16_t ssidlength; uint8_t* ssid; }; diff --git a/src/common/capwap_element_80211_ie.c b/src/common/capwap_element_80211_ie.c index 7e27f9a..ad11356 100644 --- a/src/common/capwap_element_80211_ie.c +++ b/src/common/capwap_element_80211_ie.c @@ -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); } /* */ diff --git a/src/common/capwap_element_80211_stationkey.c b/src/common/capwap_element_80211_stationkey.c index b63fe42..636e270 100644 --- a/src/common/capwap_element_80211_stationkey.c +++ b/src/common/capwap_element_80211_stationkey.c @@ -85,7 +85,7 @@ static void capwap_80211_stationkey_element_free(void* data) { capwap_free(element->key); } - capwap_free(element); + capwap_free(data); } /* */ diff --git a/src/common/capwap_element_80211_stationkey.h b/src/common/capwap_element_80211_stationkey.h index d752b47..c5ed7da 100644 --- a/src/common/capwap_element_80211_stationkey.h +++ b/src/common/capwap_element_80211_stationkey.h @@ -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 diff --git a/src/common/capwap_element_80211_updatewlan.c b/src/common/capwap_element_80211_updatewlan.c index ca757bc..f2181e4 100644 --- a/src/common/capwap_element_80211_updatewlan.c +++ b/src/common/capwap_element_80211_updatewlan.c @@ -46,7 +46,7 @@ static void capwap_80211_updatewlan_element_free(void* data) { capwap_free(element->key); } - capwap_free(element); + capwap_free(data); } /* */ diff --git a/src/common/capwap_element_acdescriptor.c b/src/common/capwap_element_acdescriptor.c index 1feeee3..0fc1cd7 100644 --- a/src/common/capwap_element_acdescriptor.c +++ b/src/common/capwap_element_acdescriptor.c @@ -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; diff --git a/src/common/capwap_element_acdescriptor.h b/src/common/capwap_element_acdescriptor.h index 04136ba..6fca127 100644 --- a/src/common/capwap_element_acdescriptor.h +++ b/src/common/capwap_element_acdescriptor.h @@ -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; diff --git a/src/common/capwap_element_acipv4list.c b/src/common/capwap_element_acipv4list.c index d919f83..563c10a 100644 --- a/src/common/capwap_element_acipv4list.c +++ b/src/common/capwap_element_acipv4list.c @@ -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; } diff --git a/src/common/capwap_element_acipv6list.c b/src/common/capwap_element_acipv6list.c index e9d1b07..629fdc1 100644 --- a/src/common/capwap_element_acipv6list.c +++ b/src/common/capwap_element_acipv6list.c @@ -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; } diff --git a/src/common/capwap_element_acname.c b/src/common/capwap_element_acname.c index 64469d1..65db3e3 100644 --- a/src/common/capwap_element_acname.c +++ b/src/common/capwap_element_acname.c @@ -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); } diff --git a/src/common/capwap_element_acname.h b/src/common/capwap_element_acname.h index a9641b7..17b0fca 100644 --- a/src/common/capwap_element_acname.h +++ b/src/common/capwap_element_acname.h @@ -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; diff --git a/src/common/capwap_element_acnamepriority.c b/src/common/capwap_element_acnamepriority.c index 08da2fd..888e2f5 100644 --- a/src/common/capwap_element_acnamepriority.c +++ b/src/common/capwap_element_acnamepriority.c @@ -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); } diff --git a/src/common/capwap_element_acnamepriority.h b/src/common/capwap_element_acnamepriority.h index 5b508e2..c44ab8e 100644 --- a/src/common/capwap_element_acnamepriority.h +++ b/src/common/capwap_element_acnamepriority.h @@ -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; diff --git a/src/common/capwap_element_actimestamp.c b/src/common/capwap_element_actimestamp.c index d07cc25..4af5379 100644 --- a/src/common/capwap_element_actimestamp.c +++ b/src/common/capwap_element_actimestamp.c @@ -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; diff --git a/src/common/capwap_element_addmacacl.c b/src/common/capwap_element_addmacacl.c index 7049cf5..b7ccbef 100644 --- a/src/common/capwap_element_addmacacl.c +++ b/src/common/capwap_element_addmacacl.c @@ -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; } diff --git a/src/common/capwap_element_addstation.c b/src/common/capwap_element_addstation.c index 5e019ca..1e13a21 100644 --- a/src/common/capwap_element_addstation.c +++ b/src/common/capwap_element_addstation.c @@ -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; diff --git a/src/common/capwap_element_addstation.h b/src/common/capwap_element_addstation.h index a3d0a5d..00b120e 100644 --- a/src/common/capwap_element_addstation.h +++ b/src/common/capwap_element_addstation.h @@ -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; diff --git a/src/common/capwap_element_controlipv4.c b/src/common/capwap_element_controlipv4.c index ea0260f..217aa57 100644 --- a/src/common/capwap_element_controlipv4.c +++ b/src/common/capwap_element_controlipv4.c @@ -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); diff --git a/src/common/capwap_element_controlipv6.c b/src/common/capwap_element_controlipv6.c index 95cf892..742733d 100644 --- a/src/common/capwap_element_controlipv6.c +++ b/src/common/capwap_element_controlipv6.c @@ -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); diff --git a/src/common/capwap_element_datatransferdata.c b/src/common/capwap_element_datatransferdata.c index 485d360..5ac26b6 100644 --- a/src/common/capwap_element_datatransferdata.c +++ b/src/common/capwap_element_datatransferdata.c @@ -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; } diff --git a/src/common/capwap_element_datatransfermode.c b/src/common/capwap_element_datatransfermode.c index 2fb2090..6542382 100644 --- a/src/common/capwap_element_datatransfermode.c +++ b/src/common/capwap_element_datatransfermode.c @@ -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, diff --git a/src/common/capwap_element_decrypterrorreport.c b/src/common/capwap_element_decrypterrorreport.c index 43e78c9..d6a64ef 100644 --- a/src/common/capwap_element_decrypterrorreport.c +++ b/src/common/capwap_element_decrypterrorreport.c @@ -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; } diff --git a/src/common/capwap_element_decrypterrorreportperiod.c b/src/common/capwap_element_decrypterrorreportperiod.c index fd0e8b7..4a614f0 100644 --- a/src/common/capwap_element_decrypterrorreportperiod.c +++ b/src/common/capwap_element_decrypterrorreportperiod.c @@ -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, diff --git a/src/common/capwap_element_deletemacacl.c b/src/common/capwap_element_deletemacacl.c index 990edf9..637fee2 100644 --- a/src/common/capwap_element_deletemacacl.c +++ b/src/common/capwap_element_deletemacacl.c @@ -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"); diff --git a/src/common/capwap_element_deletestation.c b/src/common/capwap_element_deletestation.c index 4c99af7..9fa4ef5 100644 --- a/src/common/capwap_element_deletestation.c +++ b/src/common/capwap_element_deletestation.c @@ -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; } diff --git a/src/common/capwap_element_discoverytype.c b/src/common/capwap_element_discoverytype.c index 1869490..65f1e56 100644 --- a/src/common/capwap_element_discoverytype.c +++ b/src/common/capwap_element_discoverytype.c @@ -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, diff --git a/src/common/capwap_element_discoverytype.h b/src/common/capwap_element_discoverytype.h index dd6fabb..293995b 100644 --- a/src/common/capwap_element_discoverytype.h +++ b/src/common/capwap_element_discoverytype.h @@ -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; diff --git a/src/common/capwap_element_duplicateipv4.c b/src/common/capwap_element_duplicateipv4.c index 510c330..44d901c 100644 --- a/src/common/capwap_element_duplicateipv4.c +++ b/src/common/capwap_element_duplicateipv4.c @@ -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; } diff --git a/src/common/capwap_element_duplicateipv4.h b/src/common/capwap_element_duplicateipv4.h index aac8fdd..c0a582d 100644 --- a/src/common/capwap_element_duplicateipv4.h +++ b/src/common/capwap_element_duplicateipv4.h @@ -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; diff --git a/src/common/capwap_element_duplicateipv6.c b/src/common/capwap_element_duplicateipv6.c index d7e3e64..a130f1d 100644 --- a/src/common/capwap_element_duplicateipv6.c +++ b/src/common/capwap_element_duplicateipv6.c @@ -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; } diff --git a/src/common/capwap_element_duplicateipv6.h b/src/common/capwap_element_duplicateipv6.h index 8248d06..f667130 100644 --- a/src/common/capwap_element_duplicateipv6.h +++ b/src/common/capwap_element_duplicateipv6.h @@ -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; diff --git a/src/common/capwap_element_ecnsupport.c b/src/common/capwap_element_ecnsupport.c index 8886634..bad44ac 100644 --- a/src/common/capwap_element_ecnsupport.c +++ b/src/common/capwap_element_ecnsupport.c @@ -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, diff --git a/src/common/capwap_element_idletimeout.c b/src/common/capwap_element_idletimeout.c index 33270f8..f7c4b39 100644 --- a/src/common/capwap_element_idletimeout.c +++ b/src/common/capwap_element_idletimeout.c @@ -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; diff --git a/src/common/capwap_element_imagedata.c b/src/common/capwap_element_imagedata.c index 7387edd..0d91e85 100644 --- a/src/common/capwap_element_imagedata.c +++ b/src/common/capwap_element_imagedata.c @@ -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(); diff --git a/src/common/capwap_element_imagedata.h b/src/common/capwap_element_imagedata.h index 257d125..c44b4d8 100644 --- a/src/common/capwap_element_imagedata.h +++ b/src/common/capwap_element_imagedata.h @@ -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; diff --git a/src/common/capwap_element_imageidentifier.c b/src/common/capwap_element_imageidentifier.c index fd48646..5c2cbc5 100644 --- a/src/common/capwap_element_imageidentifier.c +++ b/src/common/capwap_element_imageidentifier.c @@ -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, diff --git a/src/common/capwap_element_imageidentifier.h b/src/common/capwap_element_imageidentifier.h index b62455c..897a7e1 100644 --- a/src/common/capwap_element_imageidentifier.h +++ b/src/common/capwap_element_imageidentifier.h @@ -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; diff --git a/src/common/capwap_element_imageinfo.c b/src/common/capwap_element_imageinfo.c index 0b1b042..9d74801 100644 --- a/src/common/capwap_element_imageinfo.c +++ b/src/common/capwap_element_imageinfo.c @@ -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); diff --git a/src/common/capwap_element_initdownload.h b/src/common/capwap_element_initdownload.h index c4e012d..f15bb6a 100644 --- a/src/common/capwap_element_initdownload.h +++ b/src/common/capwap_element_initdownload.h @@ -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; }; diff --git a/src/common/capwap_element_localipv4.c b/src/common/capwap_element_localipv4.c index f04acb7..bd7923a 100644 --- a/src/common/capwap_element_localipv4.c +++ b/src/common/capwap_element_localipv4.c @@ -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; diff --git a/src/common/capwap_element_localipv6.c b/src/common/capwap_element_localipv6.c index 2c29e9c..8df586e 100644 --- a/src/common/capwap_element_localipv6.c +++ b/src/common/capwap_element_localipv6.c @@ -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; diff --git a/src/common/capwap_element_location.c b/src/common/capwap_element_location.c index baaae48..3591014 100644 --- a/src/common/capwap_element_location.c +++ b/src/common/capwap_element_location.c @@ -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, diff --git a/src/common/capwap_element_location.h b/src/common/capwap_element_location.h index 08c093f..8d3d69c 100644 --- a/src/common/capwap_element_location.h +++ b/src/common/capwap_element_location.h @@ -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; diff --git a/src/common/capwap_element_maximumlength.c b/src/common/capwap_element_maximumlength.c index f2be408..c549eac 100644 --- a/src/common/capwap_element_maximumlength.c +++ b/src/common/capwap_element_maximumlength.c @@ -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; diff --git a/src/common/capwap_element_mtudiscovery.c b/src/common/capwap_element_mtudiscovery.c index cfaeb6f..5892b8f 100644 --- a/src/common/capwap_element_mtudiscovery.c +++ b/src/common/capwap_element_mtudiscovery.c @@ -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); } diff --git a/src/common/capwap_element_radioadmstate.c b/src/common/capwap_element_radioadmstate.c index 4635c8d..75acadf 100644 --- a/src/common/capwap_element_radioadmstate.c +++ b/src/common/capwap_element_radioadmstate.c @@ -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, diff --git a/src/common/capwap_element_radiooprstate.c b/src/common/capwap_element_radiooprstate.c index 294ece1..c082f46 100644 --- a/src/common/capwap_element_radiooprstate.c +++ b/src/common/capwap_element_radiooprstate.c @@ -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, diff --git a/src/common/capwap_element_resultcode.c b/src/common/capwap_element_resultcode.c index 67f1e5f..e85781b 100644 --- a/src/common/capwap_element_resultcode.c +++ b/src/common/capwap_element_resultcode.c @@ -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, diff --git a/src/common/capwap_element_resultcode.h b/src/common/capwap_element_resultcode.h index 45c5ceb..bb05832 100644 --- a/src/common/capwap_element_resultcode.h +++ b/src/common/capwap_element_resultcode.h @@ -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; diff --git a/src/common/capwap_element_returnedmessage.c b/src/common/capwap_element_returnedmessage.c index 6397a02..85cfedb 100644 --- a/src/common/capwap_element_returnedmessage.c +++ b/src/common/capwap_element_returnedmessage.c @@ -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, diff --git a/src/common/capwap_element_returnedmessage.h b/src/common/capwap_element_returnedmessage.h index 47157fa..2bf3938 100644 --- a/src/common/capwap_element_returnedmessage.h +++ b/src/common/capwap_element_returnedmessage.h @@ -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; diff --git a/src/common/capwap_element_sessionid.c b/src/common/capwap_element_sessionid.c index 83fba9a..46ffcea 100644 --- a/src/common/capwap_element_sessionid.c +++ b/src/common/capwap_element_sessionid.c @@ -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; diff --git a/src/common/capwap_element_statisticstimer.c b/src/common/capwap_element_statisticstimer.c index 422f28f..bece1bd 100644 --- a/src/common/capwap_element_statisticstimer.c +++ b/src/common/capwap_element_statisticstimer.c @@ -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; diff --git a/src/common/capwap_element_timers.c b/src/common/capwap_element_timers.c index c0c3a2f..518696e 100644 --- a/src/common/capwap_element_timers.c +++ b/src/common/capwap_element_timers.c @@ -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); diff --git a/src/common/capwap_element_transport.c b/src/common/capwap_element_transport.c index 7ee2174..4229eb4 100644 --- a/src/common/capwap_element_transport.c +++ b/src/common/capwap_element_transport.c @@ -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, diff --git a/src/common/capwap_element_vendorpayload.c b/src/common/capwap_element_vendorpayload.c index 034dc6b..24e30c9 100644 --- a/src/common/capwap_element_vendorpayload.c +++ b/src/common/capwap_element_vendorpayload.c @@ -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, diff --git a/src/common/capwap_element_vendorpayload.h b/src/common/capwap_element_vendorpayload.h index 9dc390f..03e9119 100644 --- a/src/common/capwap_element_vendorpayload.h +++ b/src/common/capwap_element_vendorpayload.h @@ -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; diff --git a/src/common/capwap_element_wtpboarddata.c b/src/common/capwap_element_wtpboarddata.c index 88798ea..a953c94 100644 --- a/src/common/capwap_element_wtpboarddata.c +++ b/src/common/capwap_element_wtpboarddata.c @@ -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); } diff --git a/src/common/capwap_element_wtpboarddata.h b/src/common/capwap_element_wtpboarddata.h index fad326a..81665e7 100644 --- a/src/common/capwap_element_wtpboarddata.h +++ b/src/common/capwap_element_wtpboarddata.h @@ -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; diff --git a/src/common/capwap_element_wtpdescriptor.c b/src/common/capwap_element_wtpdescriptor.c index aba7234..6e0b548 100644 --- a/src/common/capwap_element_wtpdescriptor.c +++ b/src/common/capwap_element_wtpdescriptor.c @@ -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; diff --git a/src/common/capwap_element_wtpdescriptor.h b/src/common/capwap_element_wtpdescriptor.h index ae7cd61..d18f11d 100644 --- a/src/common/capwap_element_wtpdescriptor.h +++ b/src/common/capwap_element_wtpdescriptor.h @@ -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; diff --git a/src/common/capwap_element_wtpfallback.c b/src/common/capwap_element_wtpfallback.c index 2e7e90d..8a8f9f6 100644 --- a/src/common/capwap_element_wtpfallback.c +++ b/src/common/capwap_element_wtpfallback.c @@ -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, diff --git a/src/common/capwap_element_wtpframetunnelmode.c b/src/common/capwap_element_wtpframetunnelmode.c index 2f0f889..b577bb2 100644 --- a/src/common/capwap_element_wtpframetunnelmode.c +++ b/src/common/capwap_element_wtpframetunnelmode.c @@ -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, diff --git a/src/common/capwap_element_wtpmactype.c b/src/common/capwap_element_wtpmactype.c index 145673d..e34c82a 100644 --- a/src/common/capwap_element_wtpmactype.c +++ b/src/common/capwap_element_wtpmactype.c @@ -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, diff --git a/src/common/capwap_element_wtpmactype.h b/src/common/capwap_element_wtpmactype.h index 47c51c2..3ffa08e 100644 --- a/src/common/capwap_element_wtpmactype.h +++ b/src/common/capwap_element_wtpmactype.h @@ -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; diff --git a/src/common/capwap_element_wtpname.c b/src/common/capwap_element_wtpname.c index e229ac1..434fdb5 100644 --- a/src/common/capwap_element_wtpname.c +++ b/src/common/capwap_element_wtpname.c @@ -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); } diff --git a/src/common/capwap_element_wtpname.h b/src/common/capwap_element_wtpname.h index 34c82b8..b68399a 100644 --- a/src/common/capwap_element_wtpname.h +++ b/src/common/capwap_element_wtpname.h @@ -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; diff --git a/src/common/capwap_element_wtpradiostat.c b/src/common/capwap_element_wtpradiostat.c index 0ce9fa6..1521eaf 100644 --- a/src/common/capwap_element_wtpradiostat.c +++ b/src/common/capwap_element_wtpradiostat.c @@ -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, diff --git a/src/common/capwap_element_wtpradiostat.h b/src/common/capwap_element_wtpradiostat.h index 5d3b67f..998231b 100644 --- a/src/common/capwap_element_wtpradiostat.h +++ b/src/common/capwap_element_wtpradiostat.h @@ -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 diff --git a/src/common/capwap_element_wtprebootstat.c b/src/common/capwap_element_wtprebootstat.c index 835de79..7f5b776 100644 --- a/src/common/capwap_element_wtprebootstat.c +++ b/src/common/capwap_element_wtprebootstat.c @@ -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); diff --git a/src/common/capwap_element_wtpstaticipaddress.c b/src/common/capwap_element_wtpstaticipaddress.c index 8c2ddce..29efddc 100644 --- a/src/common/capwap_element_wtpstaticipaddress.c +++ b/src/common/capwap_element_wtpstaticipaddress.c @@ -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)); diff --git a/src/common/capwap_rfc.h b/src/common/capwap_rfc.h index 8f69d5b..4df807b 100644 --- a/src/common/capwap_rfc.h +++ b/src/common/capwap_rfc.h @@ -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__ */ diff --git a/src/wtp/wtp.c b/src/wtp/wtp.c index 0218d67..5188a1a 100644 --- a/src/wtp/wtp.c +++ b/src/wtp/wtp.c @@ -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; diff --git a/src/wtp/wtp_dfa_configure.c b/src/wtp/wtp_dfa_configure.c index cea8d73..07af168 100644 --- a/src/wtp/wtp_dfa_configure.c +++ b/src/wtp/wtp_dfa_configure.c @@ -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; } diff --git a/src/wtp/wtp_dfa_discovery.c b/src/wtp/wtp_dfa_discovery.c index 9f05744..88cb3fd 100644 --- a/src/wtp/wtp_dfa_discovery.c +++ b/src/wtp/wtp_dfa_discovery.c @@ -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) { diff --git a/src/wtp/wtp_dfa_dtls.c b/src/wtp/wtp_dfa_dtls.c index 9070fde..efa6c59 100644 --- a/src/wtp/wtp_dfa_dtls.c +++ b/src/wtp/wtp_dfa_dtls.c @@ -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(); diff --git a/src/wtp/wtp_dfa_join.c b/src/wtp/wtp_dfa_join.c index 5b37bd6..174aa21 100644 --- a/src/wtp/wtp_dfa_join.c +++ b/src/wtp/wtp_dfa_join.c @@ -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; } diff --git a/src/wtp/wtp_dfa_run.c b/src/wtp/wtp_dfa_run.c index 162df19..8e83efd 100644 --- a/src/wtp/wtp_dfa_run.c +++ b/src/wtp/wtp_dfa_run.c @@ -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);