The capwap data channel migrated from userspace to kernalspace

This commit is contained in:
vemax78
2014-09-10 21:58:23 +02:00
parent 71006a9121
commit 8d9985fdea
104 changed files with 6967 additions and 4840 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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__ */

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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);