The capwap data channel migrated from userspace to kernalspace
This commit is contained in:
@ -13,7 +13,6 @@
|
||||
#include "capwap_logging.h"
|
||||
#include "capwap_error.h"
|
||||
|
||||
#define CANARY 0xaaaaaaaa
|
||||
#define BACKTRACE_BUFFER 256
|
||||
|
||||
#ifndef DEBUG_BREAKPOINT
|
||||
@ -46,8 +45,8 @@ void* capwap_alloc_debug(size_t size, const char* file, const int line) {
|
||||
exit(CAPWAP_ASSERT_CONDITION);
|
||||
}
|
||||
|
||||
/* Alloc block with memory block and canary */
|
||||
block = (struct capwap_memory_block*)malloc(sizeof(struct capwap_memory_block) + size + 4);
|
||||
/* Alloc block with memory block */
|
||||
block = (struct capwap_memory_block*)malloc(sizeof(struct capwap_memory_block) + size);
|
||||
if (!block) {
|
||||
capwap_logging_debug("Out of memory %s(%d)", file, line);
|
||||
DEBUG_BREAKPOINT();
|
||||
@ -64,9 +63,6 @@ void* capwap_alloc_debug(size_t size, const char* file, const int line) {
|
||||
#endif
|
||||
block->next = g_memoryblocks;
|
||||
|
||||
/* Canary */
|
||||
*((unsigned long*)(((char*)block->item) + block->size)) = CANARY;
|
||||
|
||||
g_memoryblocks = block;
|
||||
|
||||
return block->item;
|
||||
@ -98,13 +94,6 @@ void capwap_free_debug(void* p, const char* file, const int line) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check canary */
|
||||
if (*((unsigned long*)(((char*)block->item) + block->size)) != CANARY) {
|
||||
capwap_logging_debug("%s(%d): Invalid canary allocted in %s(%d)", file, line, block->file, block->line);
|
||||
DEBUG_BREAKPOINT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find memory block */
|
||||
prevblock = NULL;
|
||||
findblock = g_memoryblocks;
|
||||
|
@ -22,7 +22,7 @@ void capwap_dump_memory(void);
|
||||
#ifdef USE_DEBUG_BACKTRACE
|
||||
void capwap_backtrace_callstack(void);
|
||||
#else
|
||||
#define capwap_backtrace_callstack() (0)
|
||||
#define capwap_backtrace_callstack()
|
||||
#endif
|
||||
|
||||
#else
|
||||
@ -34,9 +34,9 @@ void capwap_backtrace_callstack(void);
|
||||
/* Standard memory management */
|
||||
#define capwap_alloc(l) ({ void* __x = malloc(l); if (!__x) capwap_outofmemory(); __x; })
|
||||
#define capwap_free(x) free(x)
|
||||
#define capwap_check_memory_leak(x) (0)
|
||||
#define capwap_dump_memory() (0)
|
||||
#define capwap_backtrace_callstack() (0)
|
||||
#define capwap_check_memory_leak(x)
|
||||
#define capwap_dump_memory()
|
||||
#define capwap_backtrace_callstack()
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -72,7 +72,7 @@ static int capwap_bio_method_send(CYASSL* ssl, char* buffer, int length, void* c
|
||||
memcpy(&data[0] + sizeof(struct capwap_dtls_header), buffer, length);
|
||||
|
||||
/* Send packet */
|
||||
if (!dtls->send(dtls, data, length + sizeof(struct capwap_dtls_header), dtls->sendparam)) {
|
||||
if (capwap_sendto(dtls->sock, data, length + sizeof(struct capwap_dtls_header), &dtls->peeraddr) <= 0) {
|
||||
return CYASSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
|
||||
@ -196,18 +196,14 @@ static int capwap_crypt_createcookie(CYASSL* ssl, unsigned char* buffer, int siz
|
||||
}
|
||||
|
||||
/* Create buffer with peer's address and port */
|
||||
if (dtls->peeraddr.ss_family == AF_INET) {
|
||||
struct sockaddr_in* peeripv4 = (struct sockaddr_in*)&dtls->peeraddr;
|
||||
|
||||
if (dtls->peeraddr.ss.ss_family == AF_INET) {
|
||||
length = sizeof(struct in_addr) + sizeof(in_port_t);
|
||||
memcpy(temp, &peeripv4->sin_port, sizeof(in_port_t));
|
||||
memcpy(temp + sizeof(in_port_t), &peeripv4->sin_addr, sizeof(struct in_addr));
|
||||
} else if (dtls->peeraddr.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6* peeripv6 = (struct sockaddr_in6*)&dtls->peeraddr;
|
||||
|
||||
memcpy(temp, &dtls->peeraddr.sin.sin_port, sizeof(in_port_t));
|
||||
memcpy(temp + sizeof(in_port_t), &dtls->peeraddr.sin.sin_addr, sizeof(struct in_addr));
|
||||
} else if (dtls->peeraddr.ss.ss_family == AF_INET6) {
|
||||
length = sizeof(struct in6_addr) + sizeof(in_port_t);
|
||||
memcpy(temp, &peeripv6->sin6_port, sizeof(in_port_t));
|
||||
memcpy(temp + sizeof(in_port_t), &peeripv6->sin6_addr, sizeof(struct in6_addr));
|
||||
memcpy(temp, &dtls->peeraddr.sin6.sin6_port, sizeof(in_port_t));
|
||||
memcpy(temp + sizeof(in_port_t), &dtls->peeraddr.sin6.sin6_addr, sizeof(struct in6_addr));
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@ -376,14 +372,11 @@ void capwap_crypt_freecontext(struct capwap_dtls_context* dtlscontext) {
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_crypt_createsession(struct capwap_dtls* dtls, int sessiontype, struct capwap_dtls_context* dtlscontext, capwap_bio_send biosend, void* param) {
|
||||
int capwap_crypt_createsession(struct capwap_dtls* dtls, struct capwap_dtls_context* dtlscontext) {
|
||||
ASSERT(dtls != NULL);
|
||||
ASSERT(dtlscontext != NULL);
|
||||
ASSERT(dtlscontext->sslcontext != NULL);
|
||||
ASSERT(biosend != NULL);
|
||||
|
||||
memset(dtls, 0, sizeof(struct capwap_dtls));
|
||||
|
||||
/* Create ssl session */
|
||||
dtls->sslsession = (void*)CyaSSL_new((CYASSL_CTX*)dtlscontext->sslcontext);
|
||||
if (!dtls->sslsession) {
|
||||
@ -391,10 +384,6 @@ int capwap_crypt_createsession(struct capwap_dtls* dtls, int sessiontype, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send callback */
|
||||
dtls->send = biosend;
|
||||
dtls->sendparam = param;
|
||||
|
||||
/* */
|
||||
CyaSSL_set_using_nonblock((CYASSL*)dtls->sslsession, 1);
|
||||
CyaSSL_SetIOReadCtx((CYASSL*)dtls->sslsession, (void*)dtls);
|
||||
@ -403,10 +392,11 @@ int capwap_crypt_createsession(struct capwap_dtls* dtls, int sessiontype, struct
|
||||
|
||||
/* */
|
||||
dtls->action = CAPWAP_DTLS_ACTION_NONE;
|
||||
dtls->session = sessiontype;
|
||||
dtls->dtlscontext = dtlscontext;
|
||||
dtls->enable = 1;
|
||||
|
||||
dtls->buffer = NULL;
|
||||
dtls->length = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -445,8 +435,28 @@ static int capwap_crypt_handshake(struct capwap_dtls* dtls) {
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_crypt_open(struct capwap_dtls* dtls, struct sockaddr_storage* peeraddr) {
|
||||
memcpy(&dtls->peeraddr, peeraddr, sizeof(struct sockaddr_storage));
|
||||
void capwap_crypt_setconnection(struct capwap_dtls* dtls, int sock, union sockaddr_capwap* localaddr, union sockaddr_capwap* peeraddr) {
|
||||
ASSERT(sock >= 0);
|
||||
ASSERT(localaddr != NULL);
|
||||
ASSERT(peeraddr != NULL);
|
||||
|
||||
dtls->sock = sock;
|
||||
|
||||
/* */
|
||||
memcpy(&dtls->localaddr, localaddr, sizeof(union sockaddr_capwap));
|
||||
if (dtls->localaddr.ss.ss_family == AF_INET6) {
|
||||
capwap_ipv4_mapped_ipv6(&dtls->localaddr);
|
||||
}
|
||||
|
||||
/* */
|
||||
memcpy(&dtls->peeraddr, peeraddr, sizeof(union sockaddr_capwap));
|
||||
if (dtls->peeraddr.ss.ss_family == AF_INET6) {
|
||||
capwap_ipv4_mapped_ipv6(&dtls->peeraddr);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_crypt_open(struct capwap_dtls* dtls) {
|
||||
return capwap_crypt_handshake(dtls);
|
||||
}
|
||||
|
||||
@ -473,15 +483,15 @@ void capwap_crypt_freesession(struct capwap_dtls* dtls) {
|
||||
memset(dtls, 0, sizeof(struct capwap_dtls));
|
||||
}
|
||||
|
||||
/* TODO: con SSL vengono utilizzati gli indirizzi predefiniti invece quelli specificati nella funzione. Reingegnerizzarla basandosi sul concetto di connessione */
|
||||
int capwap_crypt_sendto(struct capwap_dtls* dtls, int sock, void* buffer, int size, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr) {
|
||||
ASSERT(sock >= 0);
|
||||
/* */
|
||||
int capwap_crypt_sendto(struct capwap_dtls* dtls, void* buffer, int size) {
|
||||
ASSERT(dtls != NULL);
|
||||
ASSERT(dtls->sock >= 0);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(size > 0);
|
||||
ASSERT(sendtoaddr != NULL);
|
||||
|
||||
if (!dtls || !dtls->enable) {
|
||||
return capwap_sendto(sock, buffer, size, sendfromaddr, sendtoaddr);
|
||||
if (!dtls->enable) {
|
||||
return capwap_sendto(dtls->sock, buffer, size, &dtls->peeraddr);
|
||||
}
|
||||
|
||||
/* Valid DTLS status */
|
||||
@ -493,12 +503,12 @@ int capwap_crypt_sendto(struct capwap_dtls* dtls, int sock, void* buffer, int si
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr) {
|
||||
int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, struct capwap_list* fragmentlist) {
|
||||
struct capwap_list_item* item;
|
||||
|
||||
ASSERT(sock >= 0);
|
||||
ASSERT(dtls != NULL);
|
||||
ASSERT(dtls->sock >= 0);
|
||||
ASSERT(fragmentlist != NULL);
|
||||
ASSERT(sendtoaddr != NULL);
|
||||
|
||||
item = fragmentlist->first;
|
||||
while (item) {
|
||||
@ -506,7 +516,7 @@ int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, int sock, struc
|
||||
ASSERT(fragmentpacket != NULL);
|
||||
ASSERT(fragmentpacket->offset > 0);
|
||||
|
||||
if (!capwap_crypt_sendto(dtls, sock, fragmentpacket->buffer, fragmentpacket->offset, sendfromaddr, sendtoaddr)) {
|
||||
if (!capwap_crypt_sendto(dtls, fragmentpacket->buffer, fragmentpacket->offset)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -536,7 +546,7 @@ int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size,
|
||||
if (!plainbuffer) {
|
||||
clone = capwap_clone(encrybuffer, size);
|
||||
}
|
||||
|
||||
|
||||
dtls->buffer = (clone ? clone : encrybuffer);
|
||||
dtls->length = size;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __CAPWAP_DTLS_HEADER__
|
||||
|
||||
#include "capwap_list.h"
|
||||
#include "capwap_network.h"
|
||||
|
||||
#define CAPWAP_DTLS_CLIENT 0
|
||||
#define CAPWAP_DTLS_SERVER 1
|
||||
@ -20,16 +21,12 @@
|
||||
#define CAPWAP_HANDSHAKE_CONTINUE 0
|
||||
#define CAPWAP_HANDSHAKE_COMPLETE 1
|
||||
|
||||
#define CAPWAP_DTLS_CONTROL_SESSION 0
|
||||
#define CAPWAP_DTLS_DATA_SESSION 1
|
||||
|
||||
#define CAPWAP_ERROR_AGAIN 0
|
||||
#define CAPWAP_ERROR_SHUTDOWN -1
|
||||
#define CAPWAP_ERROR_CLOSE -2
|
||||
|
||||
/* */
|
||||
struct capwap_dtls;
|
||||
typedef int(*capwap_bio_send)(struct capwap_dtls* dtls, char* buffer, int length, void* param);
|
||||
|
||||
/* */
|
||||
struct capwap_dtls_context {
|
||||
@ -51,15 +48,15 @@ struct capwap_dtls_context {
|
||||
struct capwap_dtls {
|
||||
int enable;
|
||||
int action;
|
||||
int session;
|
||||
|
||||
/* */
|
||||
void* sslsession;
|
||||
struct capwap_dtls_context* dtlscontext;
|
||||
|
||||
/* Send callback */
|
||||
struct sockaddr_storage peeraddr;
|
||||
capwap_bio_send send;
|
||||
void* sendparam;
|
||||
/* */
|
||||
int sock;
|
||||
union sockaddr_capwap localaddr;
|
||||
union sockaddr_capwap peeraddr;
|
||||
|
||||
/* Buffer read */
|
||||
void* buffer;
|
||||
@ -94,14 +91,15 @@ void capwap_crypt_free();
|
||||
int capwap_crypt_createcontext(struct capwap_dtls_context* dtlscontext, struct capwap_dtls_param* param);
|
||||
void capwap_crypt_freecontext(struct capwap_dtls_context* dtlscontext);
|
||||
|
||||
int capwap_crypt_createsession(struct capwap_dtls* dtls, int sessiontype, struct capwap_dtls_context* dtlscontext, capwap_bio_send biosend, void* param);
|
||||
void capwap_crypt_setconnection(struct capwap_dtls* dtls, int sock, union sockaddr_capwap* localaddr, union sockaddr_capwap* peeraddr);
|
||||
int capwap_crypt_createsession(struct capwap_dtls* dtls, struct capwap_dtls_context* dtlscontext);
|
||||
void capwap_crypt_freesession(struct capwap_dtls* dtls);
|
||||
|
||||
int capwap_crypt_open(struct capwap_dtls* dtls, struct sockaddr_storage* peeraddr);
|
||||
int capwap_crypt_open(struct capwap_dtls* dtls);
|
||||
void capwap_crypt_close(struct capwap_dtls* dtls);
|
||||
|
||||
int capwap_crypt_sendto(struct capwap_dtls* dtls, int sock, void* buffer, int size, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
|
||||
int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
|
||||
int capwap_crypt_sendto(struct capwap_dtls* dtls, void* buffer, int size);
|
||||
int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, struct capwap_list* fragmentlist);
|
||||
int capwap_decrypt_packet(struct capwap_dtls* dtls, void* encrybuffer, int size, void* plainbuffer, int maxsize);
|
||||
|
||||
int capwap_crypt_has_dtls_clienthello(void* buffer, int buffersize);
|
||||
|
@ -172,8 +172,9 @@ void* capwap_get_message_element_data(struct capwap_parsed_packet* packet, uint1
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, struct capwap_parsed_packet* packet) {
|
||||
int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap_parsed_packet* packet) {
|
||||
unsigned short binding;
|
||||
unsigned short bodylength;
|
||||
|
||||
ASSERT(rxmngpacket != NULL);
|
||||
ASSERT(packet != NULL);
|
||||
@ -181,7 +182,6 @@ 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);
|
||||
@ -189,179 +189,115 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
|
||||
/* Position reader to capwap body */
|
||||
memcpy(&rxmngpacket->readpos, &rxmngpacket->readbodypos, sizeof(struct read_block_from_pos));
|
||||
|
||||
if (rxmngpacket->isctrlpacket) {
|
||||
unsigned short bodylength = rxmngpacket->ctrlmsg.length - CAPWAP_CONTROL_MESSAGE_MIN_LENGTH;
|
||||
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 */
|
||||
rxmngpacket->readerpacketallowed = sizeof(struct capwap_message_element);
|
||||
if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &type) != sizeof(uint16_t)) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Check type */
|
||||
if (!IS_VALID_MESSAGE_ELEMENTS(type)) {
|
||||
return UNRECOGNIZED_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Check binding */
|
||||
if (IS_80211_MESSAGE_ELEMENTS(type) && (binding != CAPWAP_WIRELESS_BINDING_IEEE80211)) {
|
||||
return UNRECOGNIZED_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &msglength) != sizeof(uint16_t)) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Check length */
|
||||
if (msglength > bodylength) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Reader function */
|
||||
read_ops = capwap_get_message_element_ops(type);
|
||||
if (!read_ops) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Allowed to parsing only the size of message element */
|
||||
rxmngpacket->readerpacketallowed = msglength;
|
||||
|
||||
/* */
|
||||
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 INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* 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 INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* */
|
||||
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 INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* */
|
||||
memcpy(capwap_array_get_item_pointer(arraymessageelement, arraymessageelement->count), &datamsgelement, sizeof(void*));
|
||||
}
|
||||
|
||||
/* Check if read all data of message element */
|
||||
if (rxmngpacket->readerpacketallowed) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* */
|
||||
bodylength -= (msglength + sizeof(struct capwap_message_element));
|
||||
}
|
||||
} else if (IS_FLAG_K_HEADER(rxmngpacket->header)) {
|
||||
/* */
|
||||
bodylength = rxmngpacket->ctrlmsg.length - CAPWAP_CONTROL_MESSAGE_MIN_LENGTH;
|
||||
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;
|
||||
unsigned short bodylength = rxmngpacket->datamsg.length - CAPWAP_DATA_MESSAGE_KEEPALIVE_MIN_LENGTH;
|
||||
|
||||
/* Get type and length */
|
||||
rxmngpacket->readerpacketallowed = sizeof(struct capwap_message_element);
|
||||
rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &type);
|
||||
rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &msglength);
|
||||
if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &type) != sizeof(uint16_t)) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Check type */
|
||||
if (!IS_VALID_MESSAGE_ELEMENTS(type)) {
|
||||
return UNRECOGNIZED_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Check binding */
|
||||
if (IS_80211_MESSAGE_ELEMENTS(type) && (binding != CAPWAP_WIRELESS_BINDING_IEEE80211)) {
|
||||
return UNRECOGNIZED_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &msglength) != sizeof(uint16_t)) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Check length */
|
||||
if ((msglength + sizeof(struct capwap_message_element)) != bodylength) {
|
||||
if (msglength > bodylength) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Reader function */
|
||||
read_ops = capwap_get_message_element_ops(type);
|
||||
if (!read_ops) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* Allowed to parsing only the size of message element */
|
||||
rxmngpacket->readerpacketallowed = msglength;
|
||||
if (type != CAPWAP_ELEMENT_SESSIONID) {
|
||||
return UNRECOGNIZED_MESSAGE_ELEMENT;
|
||||
|
||||
/* */
|
||||
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 INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* 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 INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* */
|
||||
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 INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* */
|
||||
memcpy(capwap_array_get_item_pointer(arraymessageelement, arraymessageelement->count), &datamsgelement, sizeof(void*));
|
||||
}
|
||||
|
||||
/* Retrieve session id */
|
||||
read_ops = capwap_get_message_element_ops(CAPWAP_ELEMENT_SESSIONID);
|
||||
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 INVALID_MESSAGE_ELEMENT;
|
||||
/* Check if read all data of message element */
|
||||
if (rxmngpacket->readerpacketallowed) {
|
||||
return INVALID_MESSAGE_ELEMENT;
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_itemlist_insert_after(packet->messages, NULL, itemlist);
|
||||
bodylength -= (msglength + sizeof(struct capwap_message_element));
|
||||
}
|
||||
|
||||
return PARSING_COMPLETE;
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_packet_getdata(struct capwap_packet_rxmng* rxmngpacket, uint8_t* buffer, int maxlength) {
|
||||
int result;
|
||||
|
||||
ASSERT(rxmngpacket != NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(maxlength > 0);
|
||||
|
||||
/* Get only data packet */
|
||||
if (rxmngpacket->isctrlpacket || IS_FLAG_K_HEADER(rxmngpacket->header)) {
|
||||
return -1;
|
||||
} else if (rxmngpacket->packetlength > maxlength) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get data packet */
|
||||
rxmngpacket->readerpacketallowed = rxmngpacket->packetlength;
|
||||
result = rxmngpacket->read_ops.read_block((capwap_message_elements_handle)rxmngpacket, buffer, rxmngpacket->packetlength);
|
||||
if (result != rxmngpacket->packetlength) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct capwap_array* returnedmessage) {
|
||||
unsigned short binding;
|
||||
@ -372,350 +308,335 @@ int capwap_validate_parsed_packet(struct capwap_parsed_packet* packet, struct ca
|
||||
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
|
||||
if (packet->rxmngpacket->isctrlpacket) {
|
||||
switch (packet->rxmngpacket->ctrlmsg.type) {
|
||||
case CAPWAP_DISCOVERY_REQUEST: {
|
||||
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)) {
|
||||
switch (packet->rxmngpacket->ctrlmsg.type) {
|
||||
case CAPWAP_DISCOVERY_REQUEST: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DISCOVERY_RESPONSE: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_REQUEST: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_RESPONSE: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_STATUS_REQUEST: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_STATUS_RESPONSE: {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_UPDATE_REQUEST: {
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_UPDATE_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_REQUEST: {
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOOPRSTATE) &&
|
||||
capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_REQUEST: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_REQUEST: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_IMAGEIDENTIFIER)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_PRIMARY_DISCOVERY_REQUEST: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_PRIMARY_DISCOVERY_RESPONSE: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_REQUEST: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_STATION_CONFIGURATION_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ADDSTATION)) {
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_STATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETESTATION)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_STATION_CONFIGURATION_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_ADD_WLAN) ||
|
||||
capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_UPDATE_WLAN) ||
|
||||
capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_DELETE_WLAN)) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Keep alive data message require session id */
|
||||
if (IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_SESSIONID)) {
|
||||
|
||||
case CAPWAP_DISCOVERY_RESPONSE: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Validate Radio ID */
|
||||
uint8_t radioid = GET_RID_HEADER(packet->rxmngpacket->header);
|
||||
if (IS_VALID_RADIOID(radioid)) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_REQUEST: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_JOIN_RESPONSE: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_STATUS_REQUEST: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_STATUS_RESPONSE: {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_UPDATE_REQUEST: {
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CONFIGURATION_UPDATE_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_REQUEST: {
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RADIOOPRSTATE) &&
|
||||
capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_REQUEST: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_REQUEST: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_IMAGE_DATA_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_IMAGEIDENTIFIER)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_RESET_RESPONSE: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_PRIMARY_DISCOVERY_REQUEST: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_PRIMARY_DISCOVERY_RESPONSE: {
|
||||
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 (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if packet contains Result Code with Error Message */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_REQUEST: {
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_REQUEST: {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_STATION_CONFIGURATION_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_ADDSTATION)) {
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_STATION)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (capwap_get_message_element(packet, CAPWAP_ELEMENT_DELETESTATION)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_STATION_CONFIGURATION_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IEEE80211_WLAN_CONFIGURATION_REQUEST: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_ADD_WLAN) ||
|
||||
capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_UPDATE_WLAN) ||
|
||||
capwap_get_message_element(packet, CAPWAP_ELEMENT_80211_DELETE_WLAN)) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_IEEE80211_WLAN_CONFIGURATION_RESPONSE: {
|
||||
if (capwap_get_message_element(packet, CAPWAP_ELEMENT_RESULTCODE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -761,7 +682,4 @@ void capwap_free_parsed_packet(struct capwap_parsed_packet* packet) {
|
||||
capwap_list_free(packet->messages);
|
||||
packet->messages = NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
packet->connection = NULL;
|
||||
}
|
||||
|
@ -131,7 +131,6 @@ struct capwap_message_element_itemlist {
|
||||
|
||||
struct capwap_parsed_packet {
|
||||
struct capwap_packet_rxmng* rxmngpacket;
|
||||
struct capwap_connection* connection;
|
||||
struct capwap_list* messages;
|
||||
};
|
||||
|
||||
@ -140,13 +139,11 @@ struct capwap_parsed_packet {
|
||||
#define UNRECOGNIZED_MESSAGE_ELEMENT 1
|
||||
#define INVALID_MESSAGE_ELEMENT 2
|
||||
|
||||
int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, struct capwap_parsed_packet* packet);
|
||||
int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, 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);
|
||||
|
||||
int capwap_packet_getdata(struct capwap_packet_rxmng* rxmngpacket, uint8_t* buffer, int maxlength);
|
||||
|
||||
#endif /* __CAPWAP_ELEMENT_HEADER__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,87 +12,62 @@
|
||||
#define CAPWAP_MACADDRESS_EUI48_BUFFER 18
|
||||
#define CAPWAP_MACADDRESS_EUI64_BUFFER 24
|
||||
|
||||
/* Helper */
|
||||
#define CAPWAP_GET_NETWORK_PORT(address) ntohs((((address)->ss_family == AF_INET) ? ((struct sockaddr_in*)(address))->sin_port : ((struct sockaddr_in6*)(address))->sin6_port))
|
||||
#define CAPWAP_SET_NETWORK_PORT(address, port) if ((address)->ss_family == AF_INET) { \
|
||||
((struct sockaddr_in*)(address))->sin_port = htons(port); \
|
||||
} else if ((address)->ss_family == AF_INET6) { \
|
||||
((struct sockaddr_in6*)(address))->sin6_port = htons(port); \
|
||||
}
|
||||
|
||||
/* */
|
||||
#define CAPWAP_MAX_SOCKETS 4
|
||||
#define CAPWAP_SOCKET_IPV4_UDP 0
|
||||
#define CAPWAP_SOCKET_IPV4_UDPLITE 1
|
||||
#define CAPWAP_SOCKET_IPV6_UDP 2
|
||||
#define CAPWAP_SOCKET_IPV6_UDPLITE 3
|
||||
union sockaddr_capwap {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_storage ss;
|
||||
};
|
||||
|
||||
/* Helper */
|
||||
#define CAPWAP_GET_NETWORK_PORT(addr) ntohs((((addr)->ss.ss_family == AF_INET) ? (addr)->sin.sin_port : (addr)->sin6.sin6_port))
|
||||
#define CAPWAP_SET_NETWORK_PORT(addr, port) if ((addr)->ss.ss_family == AF_INET) { \
|
||||
(addr)->sin.sin_port = htons(port); \
|
||||
} else if ((addr)->ss.ss_family == AF_INET6) { \
|
||||
(addr)->sin6.sin6_port = htons(port); \
|
||||
}
|
||||
#define CAPWAP_COPY_NETWORK_PORT(addr1, addr2) if ((addr1)->ss.ss_family == (addr2)->ss.ss_family) { \
|
||||
if ((addr1)->ss.ss_family == AF_INET) { \
|
||||
(addr1)->sin.sin_port = (addr2)->sin.sin_port; \
|
||||
} else if ((addr1)->ss.ss_family == AF_INET6) { \
|
||||
(addr1)->sin6.sin6_port = (addr2)->sin6.sin6_port; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* */
|
||||
#define CAPWAP_RECV_ERROR_SOCKET -1
|
||||
#define CAPWAP_RECV_ERROR_TIMEOUT -2
|
||||
#define CAPWAP_RECV_ERROR_INTR -3
|
||||
|
||||
/* Socket Flags */
|
||||
#define CAPWAP_IPV6ONLY_FLAG 0x00000001
|
||||
|
||||
/* Network struct */
|
||||
struct capwap_network {
|
||||
int sock_family; /* Address family used by the server. */
|
||||
unsigned short bind_sock_ctrl_port; /* Port number to listen control protocol. */
|
||||
char bind_interface[IFNAMSIZ];
|
||||
|
||||
int sock_ctrl[CAPWAP_MAX_SOCKETS];
|
||||
int bind_ctrl_flags;
|
||||
|
||||
int sock_data[CAPWAP_MAX_SOCKETS];
|
||||
int bind_data_flags;
|
||||
};
|
||||
|
||||
#define CAPWAP_SOCKET_UDP 0
|
||||
#define CAPWAP_SOCKET_UDPLITE 1
|
||||
|
||||
/* Network socket */
|
||||
struct capwap_socket {
|
||||
int type;
|
||||
int family;
|
||||
int socket[2];
|
||||
int isctrlsocket;
|
||||
};
|
||||
|
||||
/* Network connection info */
|
||||
struct capwap_connection {
|
||||
struct capwap_socket socket;
|
||||
struct sockaddr_storage localaddr;
|
||||
struct sockaddr_storage remoteaddr;
|
||||
union sockaddr_capwap localaddr;
|
||||
char bindiface[IFNAMSIZ];
|
||||
int socket;
|
||||
};
|
||||
|
||||
void capwap_network_init(struct capwap_network* net);
|
||||
|
||||
int capwap_network_set_pollfd(struct capwap_network* net, struct pollfd* fds, int fdscount);
|
||||
void capwap_interface_list(struct capwap_network* net, struct capwap_list* list);
|
||||
|
||||
int capwap_get_macaddress_from_interface(const char* interface, char* macaddress);
|
||||
|
||||
#define CAPWAP_DATA_SOCKET 0
|
||||
#define CAPWAP_CTRL_SOCKET 1
|
||||
int capwap_get_socket(struct capwap_network* net, int socketfamily, int socketprotocol, int isctrlsocket);
|
||||
void capwap_get_network_socket(struct capwap_network* net, struct capwap_socket* sock, int fd);
|
||||
int capwap_network_get_localaddress(union sockaddr_capwap* localaddr, union sockaddr_capwap* peeraddr, char* iface);
|
||||
|
||||
int capwap_bind_sockets(struct capwap_network* net);
|
||||
void capwap_close_sockets(struct capwap_network* net);
|
||||
|
||||
int capwap_compare_ip(struct sockaddr_storage* addr1, struct sockaddr_storage* addr2);
|
||||
int capwap_ipv4_mapped_ipv6(union sockaddr_capwap* addr);
|
||||
int capwap_compare_ip(union sockaddr_capwap* addr1, union sockaddr_capwap* addr2);
|
||||
|
||||
int capwap_sendto(int sock, void* buffer, int size, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
|
||||
int capwap_sendto_fragmentpacket(int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
|
||||
int capwap_sendto(int sock, void* buffer, int size, union sockaddr_capwap* toaddr);
|
||||
int capwap_sendto_fragmentpacket(int sock, struct capwap_list* fragmentlist, union sockaddr_capwap* toaddr);
|
||||
|
||||
int capwap_wait_recvready(struct pollfd* fds, int fdscount, struct capwap_timeout* timeout);
|
||||
int capwap_recvfrom_fd(int fd, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr);
|
||||
int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct capwap_timeout* timeout);
|
||||
int capwap_recvfrom(int sock, void* buffer, int* size, union sockaddr_capwap* fromaddr, union sockaddr_capwap* toaddr);
|
||||
|
||||
int capwap_ipv4_mapped_ipv6(struct sockaddr_storage* source, struct sockaddr_storage* dest);
|
||||
int capwap_address_from_string(const char* ip, struct sockaddr_storage* address);
|
||||
|
||||
int capwap_get_localaddress_by_remoteaddress(struct sockaddr_storage* local, struct sockaddr_storage* remote, char* oif, int ipv6dualstack);
|
||||
int capwap_address_from_string(const char* ip, union sockaddr_capwap* sockaddr);
|
||||
|
||||
char* capwap_printf_macaddress(char* buffer, const uint8_t* macaddress, int type);
|
||||
int capwap_scanf_macaddress(uint8_t* macaddress, const char* buffer, int type);
|
||||
|
@ -4,10 +4,9 @@
|
||||
#include "capwap_dfa.h"
|
||||
#include "capwap_list.h"
|
||||
#include "capwap_array.h"
|
||||
#include "md5.h"
|
||||
|
||||
/* Check valid packet */
|
||||
int capwap_sanity_check(int isctrlsocket, int state, void* buffer, int buffersize, int dtlsctrlenable, int dtlsdataenable) {
|
||||
int capwap_sanity_check(int state, void* buffer, int buffersize, int dtlsenable) {
|
||||
struct capwap_preamble* preamble;
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
@ -18,43 +17,28 @@ int capwap_sanity_check(int isctrlsocket, int state, void* buffer, int buffersiz
|
||||
return CAPWAP_WRONG_PACKET;
|
||||
}
|
||||
|
||||
if (isctrlsocket) {
|
||||
if (dtlsctrlenable) {
|
||||
if ((preamble->type == CAPWAP_PREAMBLE_DTLS_HEADER) && (buffersize >= sizeof(struct capwap_dtls_header))) {
|
||||
if (state == CAPWAP_DISCOVERY_STATE) {
|
||||
if (dtlsenable) {
|
||||
if ((preamble->type == CAPWAP_PREAMBLE_DTLS_HEADER) && (buffersize >= sizeof(struct capwap_dtls_header))) {
|
||||
if (state == CAPWAP_DISCOVERY_STATE) {
|
||||
return CAPWAP_WRONG_PACKET;
|
||||
}
|
||||
|
||||
return CAPWAP_DTLS_PACKET;
|
||||
} else if ((preamble->type == CAPWAP_PREAMBLE_HEADER) && (buffersize >= sizeof(struct capwap_header))) {
|
||||
struct capwap_header* header = (struct capwap_header*)preamble;
|
||||
if (buffersize >= GET_HLEN_HEADER(header) * 4) {
|
||||
if ((state != CAPWAP_DISCOVERY_STATE) && (state != CAPWAP_UNDEF_STATE)) {
|
||||
return CAPWAP_WRONG_PACKET;
|
||||
}
|
||||
|
||||
return CAPWAP_DTLS_PACKET;
|
||||
} else if ((preamble->type == CAPWAP_PREAMBLE_HEADER) && (buffersize >= sizeof(struct capwap_header))) {
|
||||
struct capwap_header* header = (struct capwap_header*)preamble;
|
||||
if (buffersize >= GET_HLEN_HEADER(header) * 4) {
|
||||
if ((state != CAPWAP_DISCOVERY_STATE) && (state != CAPWAP_UNDEF_STATE)) {
|
||||
return CAPWAP_WRONG_PACKET;
|
||||
}
|
||||
|
||||
return CAPWAP_PLAIN_PACKET;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((preamble->type == CAPWAP_PREAMBLE_HEADER) && (buffersize >= sizeof(struct capwap_header))) {
|
||||
struct capwap_header* header = (struct capwap_header*)preamble;
|
||||
if (buffersize >= GET_HLEN_HEADER(header) * 4) {
|
||||
return CAPWAP_PLAIN_PACKET;
|
||||
}
|
||||
return CAPWAP_PLAIN_PACKET;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dtlsdataenable) {
|
||||
if ((preamble->type == CAPWAP_PREAMBLE_DTLS_HEADER) && (buffersize >= sizeof(struct capwap_dtls_header))) {
|
||||
return CAPWAP_DTLS_PACKET;
|
||||
}
|
||||
} else {
|
||||
if ((preamble->type == CAPWAP_PREAMBLE_HEADER) && (buffersize >= sizeof(struct capwap_header))) {
|
||||
struct capwap_header* header = (struct capwap_header*)preamble;
|
||||
if (buffersize >= GET_HLEN_HEADER(header) * 4) {
|
||||
return CAPWAP_PLAIN_PACKET;
|
||||
}
|
||||
if ((preamble->type == CAPWAP_PREAMBLE_HEADER) && (buffersize >= sizeof(struct capwap_header))) {
|
||||
struct capwap_header* header = (struct capwap_header*)preamble;
|
||||
if (buffersize >= GET_HLEN_HEADER(header) * 4) {
|
||||
return CAPWAP_PLAIN_PACKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,79 +70,13 @@ int capwap_is_request_type(unsigned long type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve packet digest */
|
||||
void capwap_get_packet_digest(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, unsigned char packetdigest[16]) {
|
||||
MD5_CTX mdContext;
|
||||
struct capwap_list_item* item;
|
||||
struct capwap_fragment_packet_item* packet;
|
||||
|
||||
ASSERT(rxmngpacket != NULL);
|
||||
ASSERT(rxmngpacket->packetlength > 0);
|
||||
ASSERT(connection != NULL);
|
||||
|
||||
MD5Init(&mdContext);
|
||||
|
||||
/* Address */
|
||||
if ((connection->localaddr.ss_family == AF_INET) && ((connection->remoteaddr.ss_family == AF_INET))) {
|
||||
struct sockaddr_in* localaddr_in = (struct sockaddr_in*)&connection->localaddr;
|
||||
struct sockaddr_in* remoteaddr_in = (struct sockaddr_in*)&connection->remoteaddr;
|
||||
|
||||
MD5Update(&mdContext, (unsigned char*)&localaddr_in->sin_addr.s_addr, sizeof(unsigned long));
|
||||
MD5Update(&mdContext, (unsigned char*)&localaddr_in->sin_port, sizeof(unsigned short));
|
||||
MD5Update(&mdContext, (unsigned char*)&remoteaddr_in->sin_addr.s_addr, sizeof(unsigned long));
|
||||
MD5Update(&mdContext, (unsigned char*)&remoteaddr_in->sin_port, sizeof(unsigned short));
|
||||
} else if ((connection->localaddr.ss_family == AF_INET6) && ((connection->remoteaddr.ss_family == AF_INET6))) {
|
||||
struct sockaddr_in6* localaddr_in6 = (struct sockaddr_in6*)&connection->localaddr;
|
||||
struct sockaddr_in6* remoteaddr_in6 = (struct sockaddr_in6*)&connection->remoteaddr;
|
||||
|
||||
MD5Update(&mdContext, (unsigned char*)&localaddr_in6->sin6_addr, sizeof(struct in6_addr));
|
||||
MD5Update(&mdContext, (unsigned char*)&localaddr_in6->sin6_port, sizeof(unsigned short));
|
||||
MD5Update(&mdContext, (unsigned char*)&remoteaddr_in6->sin6_addr, sizeof(struct in6_addr));
|
||||
MD5Update(&mdContext, (unsigned char*)&remoteaddr_in6->sin6_port, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
/* Packet */
|
||||
item = rxmngpacket->fragmentlist->first;
|
||||
while (item) {
|
||||
packet = (struct capwap_fragment_packet_item*)item->item;
|
||||
MD5Update(&mdContext, (unsigned char*)packet->buffer, packet->offset);
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
MD5Final(&mdContext);
|
||||
|
||||
memcpy(&packetdigest[0], &mdContext.digest[0], 16);
|
||||
}
|
||||
|
||||
/* Verify duplicate packet */
|
||||
int capwap_recv_retrasmitted_request(struct capwap_dtls* dtls, struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, unsigned char packetdigest[16], struct capwap_list* txfragmentpacket) {
|
||||
unsigned char recvpacketdigest[16];
|
||||
|
||||
ASSERT(rxmngpacket != NULL);
|
||||
ASSERT(connection != NULL);
|
||||
ASSERT(txfragmentpacket != NULL);
|
||||
|
||||
/* Check packet digest */
|
||||
capwap_get_packet_digest(rxmngpacket, connection, recvpacketdigest);
|
||||
if (!memcmp(&recvpacketdigest[0], &packetdigest[0], 16)) {
|
||||
/* Retransmit response */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(dtls, connection->socket.socket[connection->socket.type], txfragmentpacket, &connection->localaddr, &connection->remoteaddr)) {
|
||||
capwap_logging_debug("Warning: error to resend response packet");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check valid message type */
|
||||
int capwap_check_message_type(struct capwap_packet_rxmng* rxmngpacket) {
|
||||
unsigned short lengthpayload;
|
||||
|
||||
ASSERT(rxmngpacket != NULL);
|
||||
|
||||
if (rxmngpacket->isctrlpacket && rxmngpacket->fragmentlist->first) {
|
||||
if (rxmngpacket->fragmentlist->first) {
|
||||
struct capwap_fragment_packet_item* packet = (struct capwap_fragment_packet_item*)rxmngpacket->fragmentlist->first->item;
|
||||
struct capwap_header* header = (struct capwap_header*)packet->buffer;
|
||||
unsigned short binding = GET_WBID_HEADER(rxmngpacket->header);
|
||||
@ -176,8 +94,6 @@ int capwap_check_message_type(struct capwap_packet_rxmng* rxmngpacket) {
|
||||
return INVALID_REQUEST_MESSAGE_TYPE;
|
||||
}
|
||||
}
|
||||
} else if (!rxmngpacket->isctrlpacket && rxmngpacket->fragmentlist->first) {
|
||||
return VALID_MESSAGE_TYPE;
|
||||
}
|
||||
|
||||
return INVALID_MESSAGE_TYPE;
|
||||
@ -420,11 +336,7 @@ static int capwap_fragment_write_block_from_pos(struct capwap_packet_txmng* txmn
|
||||
unsigned short oldoffset = fragmentpacket->offset;
|
||||
|
||||
fragmentpacket->offset = available + packetpos;
|
||||
if (txmngpacket->isctrlpacket) {
|
||||
txmngpacket->ctrlmsg->length = htons(ntohs(txmngpacket->ctrlmsg->length) + (fragmentpacket->offset - oldoffset));
|
||||
} else if (IS_FLAG_K_HEADER(txmngpacket->header)) {
|
||||
txmngpacket->datamsg->length = htons(ntohs(txmngpacket->datamsg->length) + (fragmentpacket->offset - oldoffset));
|
||||
}
|
||||
txmngpacket->ctrlmsg->length = htons(ntohs(txmngpacket->ctrlmsg->length) + (fragmentpacket->offset - oldoffset));
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,8 +472,6 @@ struct capwap_packet_txmng* capwap_packet_txmng_create_ctrl_message(struct capwa
|
||||
ASSERT((fragmentpacket->offset + sizeof(struct capwap_control_message)) < fragmentpacket->size);
|
||||
|
||||
/* Create message */
|
||||
txmngpacket->isctrlpacket = 1;
|
||||
|
||||
txmngpacket->ctrlmsg = (struct capwap_control_message*)&fragmentpacket->buffer[fragmentpacket->offset];
|
||||
txmngpacket->ctrlmsg->type = htonl(type);
|
||||
txmngpacket->ctrlmsg->seq = seq;
|
||||
@ -574,52 +484,6 @@ struct capwap_packet_txmng* capwap_packet_txmng_create_ctrl_message(struct capwa
|
||||
return txmngpacket;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct capwap_packet_txmng* capwap_packet_txmng_create_data_message(struct capwap_header_data* data, unsigned short mtu) {
|
||||
unsigned short length;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct capwap_fragment_packet_item* fragmentpacket;
|
||||
|
||||
ASSERT(data != NULL);
|
||||
ASSERT(mtu > 0);
|
||||
|
||||
length = GET_HLEN_HEADER((struct capwap_header*)data->headerbuffer) * 4;
|
||||
|
||||
/* Check MTU */
|
||||
if ((mtu > 0) && (mtu < (length + sizeof(struct capwap_data_message)))) {
|
||||
capwap_logging_debug("The mtu is too small: %hu", mtu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create management packets */
|
||||
txmngpacket = capwap_packet_txmng_create(data, mtu);
|
||||
if (!txmngpacket) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get single fragment */
|
||||
fragmentpacket = (struct capwap_fragment_packet_item*)txmngpacket->fragmentlist->last->item;
|
||||
ASSERT((fragmentpacket->offset + sizeof(struct capwap_data_message)) < fragmentpacket->size);
|
||||
|
||||
/* */
|
||||
txmngpacket->isctrlpacket = 0;
|
||||
if (IS_FLAG_K_HEADER(txmngpacket->header)) {
|
||||
txmngpacket->datamsg = (struct capwap_data_message*)&fragmentpacket->buffer[fragmentpacket->offset];
|
||||
txmngpacket->datamsg->length = htons(CAPWAP_DATA_MESSAGE_KEEPALIVE_MIN_LENGTH); /* sizeof(Msg Element Length) */
|
||||
fragmentpacket->offset += sizeof(struct capwap_data_message);
|
||||
}
|
||||
|
||||
return txmngpacket;
|
||||
}
|
||||
|
||||
/* */
|
||||
void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, const uint8_t* data, unsigned short length) {
|
||||
ASSERT(txmngpacket != NULL);
|
||||
ASSERT(txmngpacket->isctrlpacket == 0);
|
||||
|
||||
txmngpacket->write_ops.write_block((capwap_message_elements_handle)txmngpacket, data, length);
|
||||
}
|
||||
|
||||
/* */
|
||||
void capwap_packet_txmng_add_message_element(struct capwap_packet_txmng* txmngpacket, unsigned short type, void* data) {
|
||||
struct capwap_message_elements_ops* func;
|
||||
@ -807,15 +671,13 @@ static int capwap_fragment_read_u32(capwap_message_elements_handle handle, uint3
|
||||
}
|
||||
|
||||
/* */
|
||||
struct capwap_packet_rxmng* capwap_packet_rxmng_create_message(int isctrlpacket) {
|
||||
struct capwap_packet_rxmng* capwap_packet_rxmng_create_message(void) {
|
||||
struct capwap_packet_rxmng* rxmngpacket;
|
||||
|
||||
/* */
|
||||
rxmngpacket = (struct capwap_packet_rxmng*)capwap_alloc(sizeof(struct capwap_packet_rxmng));
|
||||
memset(rxmngpacket, 0, sizeof(struct capwap_packet_rxmng));
|
||||
|
||||
rxmngpacket->isctrlpacket = isctrlpacket;
|
||||
|
||||
/* Fragment bucket */
|
||||
rxmngpacket->fragmentlist = capwap_list_create();
|
||||
|
||||
@ -839,16 +701,11 @@ static void capwap_packet_rxmng_complete(struct capwap_packet_rxmng* rxmngpacket
|
||||
rxmngpacket->readpos.pos = GET_HLEN_HEADER(rxmngpacket->header) * 4;
|
||||
|
||||
/* Read message type */
|
||||
if (rxmngpacket->isctrlpacket) {
|
||||
rxmngpacket->readerpacketallowed = sizeof(struct capwap_control_message);
|
||||
rxmngpacket->read_ops.read_u32((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.type);
|
||||
rxmngpacket->read_ops.read_u8((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.seq);
|
||||
rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.length);
|
||||
rxmngpacket->read_ops.read_u8((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.flags);
|
||||
} else if (IS_FLAG_K_HEADER(rxmngpacket->header)) {
|
||||
rxmngpacket->readerpacketallowed = sizeof(struct capwap_data_message);
|
||||
rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->datamsg.length);
|
||||
}
|
||||
rxmngpacket->readerpacketallowed = sizeof(struct capwap_control_message);
|
||||
rxmngpacket->read_ops.read_u32((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.type);
|
||||
rxmngpacket->read_ops.read_u8((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.seq);
|
||||
rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.length);
|
||||
rxmngpacket->read_ops.read_u8((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->ctrlmsg.flags);
|
||||
|
||||
/* Position of capwap body */
|
||||
memcpy(&rxmngpacket->readbodypos, &rxmngpacket->readpos, sizeof(struct read_block_from_pos));
|
||||
@ -1016,7 +873,7 @@ struct capwap_packet_rxmng* capwap_packet_rxmng_create_from_requestfragmentpacke
|
||||
}
|
||||
|
||||
/* */
|
||||
rxmngpacket = capwap_packet_rxmng_create_message(CAPWAP_CONTROL_PACKET);
|
||||
rxmngpacket = capwap_packet_rxmng_create_message();
|
||||
|
||||
/* */
|
||||
fragment = requestfragmentpacket->first;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define CAPWAP_NONE_PACKET 0
|
||||
#define CAPWAP_PLAIN_PACKET 1
|
||||
#define CAPWAP_DTLS_PACKET 2
|
||||
int capwap_sanity_check(int isctrlsocket, int state, void* buffer, int buffersize, int dtlsctrlenable, int dtlsdataenable);
|
||||
int capwap_sanity_check(int state, void* buffer, int buffersize, int dtlsenable);
|
||||
|
||||
/* Fragment management */
|
||||
struct capwap_fragment_packet_item {
|
||||
@ -50,11 +50,7 @@ struct capwap_packet_txmng {
|
||||
struct capwap_header* header;
|
||||
|
||||
/* Capwap message */
|
||||
int isctrlpacket;
|
||||
union {
|
||||
struct capwap_control_message* ctrlmsg;
|
||||
struct capwap_data_message* datamsg;
|
||||
};
|
||||
struct capwap_control_message* ctrlmsg;
|
||||
|
||||
/* Write functions */
|
||||
struct capwap_write_message_elements_ops write_ops;
|
||||
@ -63,8 +59,6 @@ struct capwap_packet_txmng {
|
||||
|
||||
/* */
|
||||
struct capwap_packet_txmng* capwap_packet_txmng_create_ctrl_message(struct capwap_header_data* data, unsigned long type, unsigned char seq, unsigned short mtu);
|
||||
struct capwap_packet_txmng* capwap_packet_txmng_create_data_message(struct capwap_header_data* data, unsigned short mtu);
|
||||
void capwap_packet_txmng_add_data(struct capwap_packet_txmng* txmngpacket, const uint8_t* data, unsigned short length);
|
||||
void capwap_packet_txmng_add_message_element(struct capwap_packet_txmng* txmngpacket, unsigned short type, void* data);
|
||||
void capwap_packet_txmng_get_fragment_packets(struct capwap_packet_txmng* txmngpacket, struct capwap_list* fragmentlist, unsigned short fragmentid);
|
||||
void capwap_packet_txmng_free(struct capwap_packet_txmng* txmngpacket);
|
||||
@ -83,11 +77,7 @@ struct capwap_packet_rxmng {
|
||||
struct capwap_header* header;
|
||||
|
||||
/* Capwap message */
|
||||
int isctrlpacket;
|
||||
union {
|
||||
struct capwap_control_message ctrlmsg;
|
||||
struct capwap_data_message datamsg;
|
||||
};
|
||||
struct capwap_control_message ctrlmsg;
|
||||
|
||||
/* Position of message elements or binding data */
|
||||
struct read_block_from_pos readbodypos;
|
||||
@ -106,10 +96,7 @@ struct capwap_packet_rxmng {
|
||||
#define CAPWAP_REQUEST_MORE_FRAGMENT 0
|
||||
#define CAPWAP_RECEIVE_COMPLETE_PACKET 1
|
||||
|
||||
#define CAPWAP_CONTROL_PACKET 1
|
||||
#define CAPWAP_DATA_PACKET 0
|
||||
|
||||
struct capwap_packet_rxmng* capwap_packet_rxmng_create_message(int isctrlpacket);
|
||||
struct capwap_packet_rxmng* capwap_packet_rxmng_create_message(void);
|
||||
int capwap_packet_rxmng_add_recv_packet(struct capwap_packet_rxmng* rxmngpacket, void* data, int length);
|
||||
void capwap_packet_rxmng_free(struct capwap_packet_rxmng* rxmngpacket);
|
||||
|
||||
@ -125,8 +112,4 @@ int capwap_is_request_type(unsigned long type);
|
||||
#define INVALID_REQUEST_MESSAGE_TYPE 2
|
||||
int capwap_check_message_type(struct capwap_packet_rxmng* rxmngpacket);
|
||||
|
||||
/* Retransmission function */
|
||||
void capwap_get_packet_digest(struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, unsigned char packetdigest[16]);
|
||||
int capwap_recv_retrasmitted_request(struct capwap_dtls* dtls, struct capwap_packet_rxmng* rxmngpacket, struct capwap_connection* connection, unsigned char packetdigest[16], struct capwap_list* txfragmentpacket);
|
||||
|
||||
#endif /* __CAPWAP_PROTOCOL_HEADER__ */
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "capwap.h"
|
||||
#include "capwap_network.h"
|
||||
#include "capwap_socket.h"
|
||||
|
||||
#include <cyassl/options.h>
|
||||
@ -30,7 +31,7 @@ static int capwap_socket_nonblocking(int sock, int nonblocking) {
|
||||
}
|
||||
|
||||
/* */
|
||||
int capwap_socket_connect(int sock, struct sockaddr_storage* address, int timeout) {
|
||||
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout) {
|
||||
int result;
|
||||
struct pollfd fds;
|
||||
socklen_t size;
|
||||
@ -44,7 +45,7 @@ int capwap_socket_connect(int sock, struct sockaddr_storage* address, int timeou
|
||||
}
|
||||
|
||||
/* */
|
||||
result = connect(sock, (struct sockaddr*)address, sizeof(struct sockaddr_storage));
|
||||
result = connect(sock, &address->sa, sizeof(union sockaddr_capwap));
|
||||
if (result < 0) {
|
||||
if (errno == EINPROGRESS) {
|
||||
/* Wait to connection complete */
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define __CAPWAP_SOCKET_HEADER__
|
||||
|
||||
/* */
|
||||
int capwap_socket_connect(int sock, struct sockaddr_storage* address, int timeout);
|
||||
int capwap_socket_connect(int sock, union sockaddr_capwap* address, int timeout);
|
||||
void capwap_socket_shutdown(int sock);
|
||||
void capwap_socket_close(int sock);
|
||||
|
||||
|
264
src/common/md5.c
264
src/common/md5.c
@ -1,264 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
** md5.c **
|
||||
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
/* -- include the following line if the md5.h header file is separate -- */
|
||||
#include "md5.h"
|
||||
|
||||
/* forward declaration */
|
||||
static void Transform(UINT4* buf, UINT4* in);
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* F, G and H are basic MD5 functions: selection, majority, parity */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s, ac) \
|
||||
{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) \
|
||||
{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) \
|
||||
{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) \
|
||||
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
void MD5Init(MD5_CTX* mdContext)
|
||||
{
|
||||
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
|
||||
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
mdContext->buf[0] = (UINT4)0x67452301;
|
||||
mdContext->buf[1] = (UINT4)0xefcdab89;
|
||||
mdContext->buf[2] = (UINT4)0x98badcfe;
|
||||
mdContext->buf[3] = (UINT4)0x10325476;
|
||||
}
|
||||
|
||||
void MD5Update(MD5_CTX* mdContext, unsigned char* inBuf, unsigned int inLen)
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* update number of bits */
|
||||
if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
|
||||
mdContext->i[1]++;
|
||||
mdContext->i[0] += ((UINT4)inLen << 3);
|
||||
mdContext->i[1] += ((UINT4)inLen >> 29);
|
||||
|
||||
while (inLen--) {
|
||||
/* add new character to buffer, increment mdi */
|
||||
mdContext->in[mdi++] = *inBuf++;
|
||||
|
||||
/* transform if necessary */
|
||||
if (mdi == 0x40) {
|
||||
for (i = 0, ii = 0; i < 16; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
mdi = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MD5Final(MD5_CTX* mdContext)
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
unsigned int padLen;
|
||||
|
||||
/* save number of bits */
|
||||
in[14] = mdContext->i[0];
|
||||
in[15] = mdContext->i[1];
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* pad out to 56 mod 64 */
|
||||
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
|
||||
MD5Update (mdContext, PADDING, padLen);
|
||||
|
||||
/* append length in bits and transform */
|
||||
for (i = 0, ii = 0; i < 14; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
|
||||
/* store buffer in digest */
|
||||
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
|
||||
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
|
||||
mdContext->digest[ii+1] =
|
||||
(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
|
||||
mdContext->digest[ii+2] =
|
||||
(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
|
||||
mdContext->digest[ii+3] =
|
||||
(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Basic MD5 step. Transform buf based on in.
|
||||
*/
|
||||
static void Transform(UINT4* buf, UINT4* in)
|
||||
{
|
||||
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
|
||||
|
||||
/* Round 1 */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
|
||||
FF ( a, b, c, d, in[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF ( d, a, b, c, in[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF ( c, d, a, b, in[ 2], S13, 0x242070db); /* 3 */
|
||||
FF ( b, c, d, a, in[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF ( a, b, c, d, in[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF ( d, a, b, c, in[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF ( c, d, a, b, in[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF ( b, c, d, a, in[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF ( a, b, c, d, in[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF ( d, a, b, c, in[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF ( c, d, a, b, in[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF ( b, c, d, a, in[11], S14, 0x895cd7be); /* 12 */
|
||||
FF ( a, b, c, d, in[12], S11, 0x6b901122); /* 13 */
|
||||
FF ( d, a, b, c, in[13], S12, 0xfd987193); /* 14 */
|
||||
FF ( c, d, a, b, in[14], S13, 0xa679438e); /* 15 */
|
||||
FF ( b, c, d, a, in[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
GG ( a, b, c, d, in[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG ( d, a, b, c, in[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG ( c, d, a, b, in[11], S23, 0x265e5a51); /* 19 */
|
||||
GG ( b, c, d, a, in[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG ( a, b, c, d, in[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG ( d, a, b, c, in[10], S22, 0x02441453); /* 22 */
|
||||
GG ( c, d, a, b, in[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG ( b, c, d, a, in[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG ( a, b, c, d, in[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG ( d, a, b, c, in[14], S22, 0xc33707d6); /* 26 */
|
||||
GG ( c, d, a, b, in[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG ( b, c, d, a, in[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG ( a, b, c, d, in[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG ( d, a, b, c, in[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG ( c, d, a, b, in[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG ( b, c, d, a, in[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
HH ( a, b, c, d, in[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH ( d, a, b, c, in[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH ( c, d, a, b, in[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH ( b, c, d, a, in[14], S34, 0xfde5380c); /* 36 */
|
||||
HH ( a, b, c, d, in[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH ( d, a, b, c, in[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH ( c, d, a, b, in[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH ( b, c, d, a, in[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH ( a, b, c, d, in[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH ( d, a, b, c, in[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH ( c, d, a, b, in[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH ( b, c, d, a, in[ 6], S34, 0x04881d05); /* 44 */
|
||||
HH ( a, b, c, d, in[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH ( d, a, b, c, in[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH ( c, d, a, b, in[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH ( b, c, d, a, in[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
II ( a, b, c, d, in[ 0], S41, 0xf4292244); /* 49 */
|
||||
II ( d, a, b, c, in[ 7], S42, 0x432aff97); /* 50 */
|
||||
II ( c, d, a, b, in[14], S43, 0xab9423a7); /* 51 */
|
||||
II ( b, c, d, a, in[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II ( a, b, c, d, in[12], S41, 0x655b59c3); /* 53 */
|
||||
II ( d, a, b, c, in[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II ( c, d, a, b, in[10], S43, 0xffeff47d); /* 55 */
|
||||
II ( b, c, d, a, in[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II ( a, b, c, d, in[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II ( d, a, b, c, in[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II ( c, d, a, b, in[ 6], S43, 0xa3014314); /* 59 */
|
||||
II ( b, c, d, a, in[13], S44, 0x4e0811a1); /* 60 */
|
||||
II ( a, b, c, d, in[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II ( d, a, b, c, in[11], S42, 0xbd3af235); /* 62 */
|
||||
II ( c, d, a, b, in[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II ( b, c, d, a, in[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
** md5.h -- Header file for implementation of MD5 **
|
||||
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
|
||||
** Revised (for MD5): RLR 4/27/91 **
|
||||
** -- G modified to have y&~z instead of y&z **
|
||||
** -- FF, GG, HH modified to add in last register done **
|
||||
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
|
||||
** -- distinct additive constant for each step **
|
||||
** -- round 4 added, working mod 7 **
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
/* typedef a 32 bit type */
|
||||
typedef unsigned long int UINT4;
|
||||
|
||||
/* Data structure for MD5 (Message Digest) computation */
|
||||
typedef struct {
|
||||
UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
|
||||
UINT4 buf[4]; /* scratch buffer */
|
||||
unsigned char in[64]; /* input buffer */
|
||||
unsigned char digest[16]; /* actual digest after MD5Final call */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init(MD5_CTX* mdContext);
|
||||
void MD5Update(MD5_CTX* mdContext, unsigned char* inBuf, unsigned int inLen);
|
||||
void MD5Final(MD5_CTX* mdContext);
|
Reference in New Issue
Block a user