162 lines
5.5 KiB
C
162 lines
5.5 KiB
C
|
#include "capwap.h"
|
||
|
#include "capwap_array.h"
|
||
|
#include "capwap_element.h"
|
||
|
|
||
|
/********************************************************************
|
||
|
|
||
|
0 1 2 3
|
||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
| Vendor Identifier |
|
||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
| Board Data Sub-Element...
|
||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
|
||
|
0 1 2 3
|
||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
| Board Data Type | Board Data Length |
|
||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
| Board Data Value...
|
||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
|
||
|
Type: 38 for WTP Board Data
|
||
|
Length: >=14
|
||
|
|
||
|
********************************************************************/
|
||
|
|
||
|
struct capwap_wtpboarddata_raw_element {
|
||
|
unsigned long vendor;
|
||
|
char data[0];
|
||
|
} __attribute__((__packed__));
|
||
|
|
||
|
struct capwap_wtpboarddata_raw_board_subelement {
|
||
|
unsigned short type;
|
||
|
unsigned short length;
|
||
|
char data[0];
|
||
|
} __attribute__((__packed__));
|
||
|
|
||
|
/* */
|
||
|
struct capwap_message_element* capwap_wtpboarddata_element_create(void* data, unsigned long datalength) {
|
||
|
char* pos;
|
||
|
unsigned long i;
|
||
|
unsigned short length;
|
||
|
struct capwap_message_element* element;
|
||
|
struct capwap_wtpboarddata_raw_element* dataraw;
|
||
|
struct capwap_wtpboarddata_element* dataelement = (struct capwap_wtpboarddata_element*)data;
|
||
|
|
||
|
ASSERT(data != NULL);
|
||
|
ASSERT(datalength >= sizeof(struct capwap_wtpboarddata_element));
|
||
|
ASSERT(dataelement->boardsubelement != NULL);
|
||
|
|
||
|
/* Calc length packet */
|
||
|
length = sizeof(struct capwap_wtpboarddata_raw_element);
|
||
|
for (i = 0; i < dataelement->boardsubelement->count; i++) {
|
||
|
struct capwap_wtpboarddata_board_subelement* board = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(dataelement->boardsubelement, i);
|
||
|
length += sizeof(struct capwap_wtpboarddata_raw_board_subelement) + board->length;
|
||
|
}
|
||
|
|
||
|
/* Alloc block of memory */
|
||
|
element = capwap_alloc(sizeof(struct capwap_message_element) + length);
|
||
|
if (!element) {
|
||
|
capwap_outofmemory();
|
||
|
}
|
||
|
|
||
|
/* Create message element */
|
||
|
memset(element, 0, sizeof(struct capwap_message_element) + length);
|
||
|
element->type = htons(CAPWAP_ELEMENT_WTPBOARDDATA);
|
||
|
element->length = htons(length);
|
||
|
|
||
|
/* */
|
||
|
dataraw = (struct capwap_wtpboarddata_raw_element*)element->data;
|
||
|
dataraw->vendor = htonl(dataelement->vendor);
|
||
|
pos = dataraw->data;
|
||
|
|
||
|
/* Board Sub-Element */
|
||
|
for (i = 0; i < dataelement->boardsubelement->count; i++) {
|
||
|
struct capwap_wtpboarddata_raw_board_subelement* boardraw = (struct capwap_wtpboarddata_raw_board_subelement*)pos;
|
||
|
struct capwap_wtpboarddata_board_subelement* board = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(dataelement->boardsubelement, i);
|
||
|
|
||
|
boardraw->type = htons(board->type);
|
||
|
boardraw->length = htons(board->length);
|
||
|
memcpy(boardraw->data, board->data, board->length);
|
||
|
|
||
|
pos += sizeof(struct capwap_wtpboarddata_raw_board_subelement) + board->length;
|
||
|
}
|
||
|
|
||
|
return element;
|
||
|
}
|
||
|
|
||
|
/* */
|
||
|
int capwap_wtpboarddata_element_validate(struct capwap_message_element* element) {
|
||
|
/* TODO */
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* */
|
||
|
void* capwap_wtpboarddata_element_parsing(struct capwap_message_element* element) {
|
||
|
long i;
|
||
|
char* pos;
|
||
|
long length;
|
||
|
struct capwap_wtpboarddata_element* data;
|
||
|
struct capwap_wtpboarddata_raw_element* dataraw;
|
||
|
|
||
|
ASSERT(element);
|
||
|
ASSERT(ntohs(element->type) == CAPWAP_ELEMENT_WTPBOARDDATA);
|
||
|
|
||
|
length = (long)ntohs(element->length);
|
||
|
if (length < 14) {
|
||
|
capwap_logging_debug("Invalid WTP Board Data element");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/* */
|
||
|
dataraw = (struct capwap_wtpboarddata_raw_element*)element->data;
|
||
|
data = (struct capwap_wtpboarddata_element*)capwap_alloc(sizeof(struct capwap_wtpboarddata_element));
|
||
|
data->boardsubelement = capwap_array_create(sizeof(struct capwap_wtpboarddata_board_subelement), 0);
|
||
|
|
||
|
/* */
|
||
|
data->vendor = ntohl(dataraw->vendor);
|
||
|
|
||
|
pos = dataraw->data;
|
||
|
length -= sizeof(struct capwap_wtpboarddata_raw_element);
|
||
|
|
||
|
/* Board Subelement */
|
||
|
i = 0;
|
||
|
while (length > 0) {
|
||
|
struct capwap_wtpboarddata_board_subelement* board = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(data->boardsubelement, i);
|
||
|
struct capwap_wtpboarddata_raw_board_subelement* boardraw = (struct capwap_wtpboarddata_raw_board_subelement*)pos;
|
||
|
unsigned short boardlength = ntohs(boardraw->length);
|
||
|
unsigned short boardrawlength = sizeof(struct capwap_wtpboarddata_raw_board_subelement) + boardlength;
|
||
|
|
||
|
if ((boardlength > CAPWAP_BOARD_SUBELEMENT_MAXDATA) || (length < boardrawlength)) {
|
||
|
capwap_logging_debug("Invalid WTP Board Data element");
|
||
|
capwap_wtpboarddata_element_free(data);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/* */
|
||
|
board->type = ntohs(boardraw->type);
|
||
|
board->length = boardlength;
|
||
|
memcpy(board->data, boardraw->data, boardlength);
|
||
|
|
||
|
/* */
|
||
|
i++;
|
||
|
pos += boardrawlength;
|
||
|
length -= boardrawlength;
|
||
|
}
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
/* */
|
||
|
void capwap_wtpboarddata_element_free(void* data) {
|
||
|
struct capwap_wtpboarddata_element* dataelement = (struct capwap_wtpboarddata_element*)data;
|
||
|
|
||
|
ASSERT(dataelement != NULL);
|
||
|
ASSERT(dataelement->boardsubelement != NULL);
|
||
|
|
||
|
capwap_array_free(dataelement->boardsubelement);
|
||
|
capwap_free(dataelement);
|
||
|
}
|