From 75dcf5149686e53eeef2fb5aafb5f2979ebee1db Mon Sep 17 00:00:00 2001 From: vemax78 Date: Tue, 18 Jun 2013 22:38:56 +0200 Subject: [PATCH] Rejects the join with the same identifier of the WTP --- src/ac/ac.h | 4 ++ src/ac/ac_dfa_join.c | 33 +++++++++-- src/ac/ac_execute.c | 72 ++++++++++++++++++++++-- src/ac/ac_session.c | 12 ++++ src/ac/ac_session.h | 5 +- src/common/capwap_element_wtpboarddata.c | 19 +++++++ src/common/capwap_element_wtpboarddata.h | 3 + 7 files changed, 135 insertions(+), 13 deletions(-) diff --git a/src/ac/ac.h b/src/ac/ac.h index a29edb4..228f39f 100644 --- a/src/ac/ac.h +++ b/src/ac/ac.h @@ -115,4 +115,8 @@ int ac_execute(void); int ac_valid_binding(unsigned short binding); void ac_update_statistics(void); +int ac_has_sessionid(struct capwap_sessionid_element* sessionid); +int ac_has_wtpid(unsigned char* id, unsigned short length); + + #endif /* __CAPWAP_AC_HEADER__ */ diff --git a/src/ac/ac_dfa_join.c b/src/ac/ac_dfa_join.c index 40a4131..3e48979 100644 --- a/src/ac/ac_dfa_join.c +++ b/src/ac/ac_dfa_join.c @@ -8,6 +8,9 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* int i; struct capwap_header_data capwapheader; struct capwap_packet_txmng* txmngpacket; + struct capwap_sessionid_element* sessionid; + struct capwap_wtpboarddata_element* wtpboarddata; + struct capwap_wtpboarddata_board_subelement* wtpboarddatamacaddress; int status = AC_DFA_ACCEPT_PACKET; struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE }; @@ -20,13 +23,31 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* binding = GET_WBID_HEADER(packet->rxmngpacket->header); if (ac_valid_binding(binding)) { if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_JOIN_REQUEST) { - resultcode.code = CAPWAP_RESULTCODE_SUCCESS; + /* Get sessionid and verify unique id */ + sessionid = (struct capwap_sessionid_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID); + if (!ac_has_sessionid(sessionid)) { + /* Checking macaddress for detect if WTP already connected */ + wtpboarddata = (struct capwap_wtpboarddata_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPBOARDDATA); + wtpboarddatamacaddress = capwap_wtpboarddata_get_subelement(wtpboarddata, CAPWAP_BOARD_SUBELEMENT_MACADDRESS); + if (wtpboarddatamacaddress && !ac_has_wtpid((unsigned char*)wtpboarddatamacaddress->data, (unsigned short)wtpboarddatamacaddress->length)) { + /* Valid WTP id */ + session->wtpid = capwap_clone(wtpboarddatamacaddress->data, wtpboarddatamacaddress->length); + session->wtpidlength = wtpboarddatamacaddress->length; - /* Get sessionid */ - memcpy(&session->sessionid, capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID), sizeof(struct capwap_sessionid_element)); - - /* Get binding */ - session->binding = binding; + /* Valid session id */ + memcpy(&session->sessionid, sessionid, sizeof(struct capwap_sessionid_element)); + + /* Get binding */ + session->binding = binding; + + /* Valid Join */ + resultcode.code = CAPWAP_RESULTCODE_SUCCESS; + } else { + resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_UNKNOWN_SOURCE; + } + } else { + resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_ID_ALREADY_IN_USE; + } } else { resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE; } diff --git a/src/ac/ac_execute.c b/src/ac/ac_execute.c index 3d130f3..956ffe5 100644 --- a/src/ac/ac_execute.c +++ b/src/ac/ac_execute.c @@ -32,11 +32,11 @@ static void ac_session_add_packet(struct ac_session_t* session, char* buffer, in static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_storage* address, int isctrlsocket) { struct ac_session_t* result = NULL; struct capwap_list_item* search; - + ASSERT(address != NULL); - + capwap_lock_enter(&g_ac.sessionslock); - + search = g_ac.sessions->first; while (search != NULL) { struct ac_session_t* session = (struct ac_session_t*)search->item; @@ -47,12 +47,72 @@ static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_st result = session; break; } - + search = search->next; } - + capwap_lock_exit(&g_ac.sessionslock); - + + return result; +} + +/* */ +int ac_has_sessionid(struct capwap_sessionid_element* sessionid) { + int result = 0; + struct capwap_list_item* search; + + ASSERT(sessionid != NULL); + + capwap_lock_enter(&g_ac.sessionslock); + + search = g_ac.sessions->first; + while (search != NULL) { + struct ac_session_t* session = (struct ac_session_t*)search->item; + + ASSERT(session != NULL); + + if (!memcmp(sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) { + result = 1; + break; + } + + search = search->next; + } + + capwap_lock_exit(&g_ac.sessionslock); + + return result; +} + +/* */ +int ac_has_wtpid(unsigned char* wtpid, unsigned short length) { + int result = 0; + struct capwap_list_item* search; + + if (!wtpid || !length) { + return -1; + } + + capwap_lock_enter(&g_ac.sessionslock); + + search = g_ac.sessions->first; + while (search != NULL) { + struct ac_session_t* session = (struct ac_session_t*)search->item; + + ASSERT(session != NULL); + + if (session->wtpidlength == length) { + if (!memcmp(wtpid, session->wtpid, length)) { + result = 1; + break; + } + } + + search = search->next; + } + + capwap_lock_exit(&g_ac.sessionslock); + return result; } diff --git a/src/ac/ac_session.c b/src/ac/ac_session.c index 99e9964..b04a3c9 100644 --- a/src/ac/ac_session.c +++ b/src/ac/ac_session.c @@ -568,6 +568,14 @@ int ac_session_release_reference(struct ac_session_t* session) { while (search != NULL) { struct ac_session_t* item = (struct ac_session_t*)search->item; if (session == item) { +#ifdef DEBUG + char sessionname[33]; + + /* */ + capwap_sessionid_printf(&session->sessionid, sessionname); + capwap_logging_debug("Release Session AC %s", sessionname); +#endif + /* Free DTSL Control */ capwap_crypt_freesession(&session->ctrldtls); @@ -591,6 +599,10 @@ int ac_session_release_reference(struct ac_session_t* session) { capwap_array_free(session->dfa.acipv4list.addresses); capwap_array_free(session->dfa.acipv6list.addresses); + if (session->wtpid) { + capwap_free(session->wtpid); + } + /* Remove item from list */ remove = 1; capwap_itemlist_free(capwap_itemlist_remove(g_ac.sessions, search)); diff --git a/src/ac/ac_session.h b/src/ac/ac_session.h index 337d120..4ddffa5 100644 --- a/src/ac/ac_session.h +++ b/src/ac/ac_session.h @@ -23,7 +23,10 @@ struct ac_session_control { /* AC sessions */ struct ac_session_t { struct ac_state dfa; - + + unsigned char* wtpid; + unsigned short wtpidlength; + unsigned long count; struct sockaddr_storage acctrladdress; struct sockaddr_storage acdataaddress; diff --git a/src/common/capwap_element_wtpboarddata.c b/src/common/capwap_element_wtpboarddata.c index a953c94..819b237 100644 --- a/src/common/capwap_element_wtpboarddata.c +++ b/src/common/capwap_element_wtpboarddata.c @@ -140,3 +140,22 @@ struct capwap_message_elements_ops capwap_element_wtpboarddata_ops = { .parsing_message_element = capwap_wtpboarddata_element_parsing, .free_parsed_message_element = capwap_wtpboarddata_element_free }; + +/* */ +struct capwap_wtpboarddata_board_subelement* capwap_wtpboarddata_get_subelement(struct capwap_wtpboarddata_element* wtpboarddata, int subelement) { + int i; + + ASSERT(wtpboarddata != NULL); + ASSERT((subelement >= CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST) && (subelement <= CAPWAP_BOARD_SUBELEMENT_TYPE_LAST)); + + /* */ + for (i = 0; i < wtpboarddata->boardsubelement->count; i++) { + struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(wtpboarddata->boardsubelement, i); + + if (desc->type == subelement) { + return desc; + } + } + + return NULL; +} diff --git a/src/common/capwap_element_wtpboarddata.h b/src/common/capwap_element_wtpboarddata.h index 81665e7..ac3f517 100644 --- a/src/common/capwap_element_wtpboarddata.h +++ b/src/common/capwap_element_wtpboarddata.h @@ -26,4 +26,7 @@ struct capwap_wtpboarddata_board_subelement { extern struct capwap_message_elements_ops capwap_element_wtpboarddata_ops; +/* Helper function */ +struct capwap_wtpboarddata_board_subelement* capwap_wtpboarddata_get_subelement(struct capwap_wtpboarddata_element* wtpboarddata, int subelement); + #endif /* __CAPWAP_ELEMENT_WTPBOARDDATA_HEADER__ */