[wtp] implement vendor specific elements

This commit is contained in:
Andreas Schultz 2016-03-08 12:00:01 +01:00
parent 471d1058c4
commit 730f110a25
11 changed files with 157 additions and 123 deletions

View File

@ -101,7 +101,8 @@ capwap_SOURCES = $(top_srcdir)/src/common/capwap.c \
$(top_srcdir)/src/common/capwap_element_80211_wtpradioconf.c \ $(top_srcdir)/src/common/capwap_element_80211_wtpradioconf.c \
$(top_srcdir)/src/common/capwap_element_80211_wtpradiofailalarm.c \ $(top_srcdir)/src/common/capwap_element_80211_wtpradiofailalarm.c \
$(top_srcdir)/src/common/capwap_element_80211_wtpradioinformation.c \ $(top_srcdir)/src/common/capwap_element_80211_wtpradioinformation.c \
$(top_srcdir)/src/common/capwap_element_80211n_radioconf.c $(top_srcdir)/src/common/capwap_element_80211n_radioconf.c \
$(top_srcdir)/src/common/capwap_element_80211n_station_information.c
if DEBUG_BUILD if DEBUG_BUILD
capwap_SOURCES += $(top_srcdir)/src/common/capwap_debug.c capwap_SOURCES += $(top_srcdir)/src/common/capwap_debug.c

View File

@ -88,20 +88,41 @@ static const struct capwap_message_elements_ops * capwap_80211_message_elements[
}; };
#undef element_ops #undef element_ops
/* */
#define element_ops(Id, Ops) [(Id) - 1] = &(Ops)
static const struct capwap_message_elements_ops * capwap_vendor_travelping_message_elements[] = {
element_ops(CAPWAP_ELEMENT_80211N_RADIO_CONF_TYPE, capwap_element_80211n_radioconf_ops),
element_ops(CAPWAP_ELEMENT_80211N_STATION_INFO_TYPE, capwap_element_80211n_station_info_ops)
};
#undef element_ops
/* */ /* */
const struct capwap_message_elements_ops * const struct capwap_message_elements_ops *
capwap_get_message_element_ops(const struct capwap_message_element_id id) capwap_get_message_element_ops(const struct capwap_message_element_id id)
{ {
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
switch (id.vendor) { switch (id.vendor) {
case 0: case 0:
if (IS_MESSAGE_ELEMENTS(id)) { if (id.type >= CAPWAP_MESSAGE_ELEMENTS_START &&
id.type - CAPWAP_MESSAGE_ELEMENTS_START < ARRAY_SIZE(capwap_message_elements)) {
return capwap_message_elements[id.type - CAPWAP_MESSAGE_ELEMENTS_START]; return capwap_message_elements[id.type - CAPWAP_MESSAGE_ELEMENTS_START];
} else if (IS_80211_MESSAGE_ELEMENTS(id)) { }
else if (id.type >= CAPWAP_80211_MESSAGE_ELEMENTS_START &&
id.type - CAPWAP_80211_MESSAGE_ELEMENTS_START < ARRAY_SIZE(capwap_80211_message_elements)) {
return capwap_80211_message_elements[id.type - CAPWAP_80211_MESSAGE_ELEMENTS_START]; return capwap_80211_message_elements[id.type - CAPWAP_80211_MESSAGE_ELEMENTS_START];
} }
break;
case CAPWAP_VENDOR_TRAVELPING_ID:
if (id.type >= 1 &&
id.type - 1 < ARRAY_SIZE(capwap_vendor_travelping_message_elements))
return capwap_vendor_travelping_message_elements[id.type - 1];
break;
} }
return NULL; return NULL;
#undef ARRAY_SIZE
} }
/* */ /* */
@ -169,7 +190,7 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
/* */ /* */
bodylength = rxmngpacket->ctrlmsg.length - CAPWAP_CONTROL_MESSAGE_MIN_LENGTH; bodylength = rxmngpacket->ctrlmsg.length - CAPWAP_CONTROL_MESSAGE_MIN_LENGTH;
while (bodylength > 0) { while (bodylength > 0) {
struct capwap_message_element_id id; struct capwap_message_element_id id = { .vendor = 0 };
uint16_t msglength; uint16_t msglength;
struct capwap_list_item* itemlist; struct capwap_list_item* itemlist;
struct capwap_message_element_itemlist* messageelement; struct capwap_message_element_itemlist* messageelement;
@ -178,45 +199,60 @@ int capwap_parsing_packet(struct capwap_packet_rxmng* rxmngpacket, struct capwap
/* Get type and length */ /* Get type and length */
rxmngpacket->readerpacketallowed = sizeof(struct capwap_message_element); rxmngpacket->readerpacketallowed = sizeof(struct capwap_message_element);
if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &id.type) != sizeof(uint16_t)) { if (rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &id.type) != sizeof(uint16_t) ||
rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &msglength) != sizeof(uint16_t) ||
msglength > bodylength)
return INVALID_MESSAGE_ELEMENT; return INVALID_MESSAGE_ELEMENT;
}
/* TODO: implement actual vendor handling */
id.vendor = 0;
/* Check type */
capwap_logging_debug("MESSAGE ELEMENT: %06x:%d", id.vendor, id.type);
if (!IS_VALID_MESSAGE_ELEMENTS(id)) {
return UNRECOGNIZED_MESSAGE_ELEMENT;
}
/* Check binding */
if (IS_80211_MESSAGE_ELEMENTS(id) && (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(id);
capwap_logging_debug("read_ops: %p", read_ops);
if (!read_ops) {
return INVALID_MESSAGE_ELEMENT;
}
/* Allowed to parsing only the size of message element */ /* Allowed to parsing only the size of message element */
rxmngpacket->readerpacketallowed = msglength; rxmngpacket->readerpacketallowed = msglength;
/* Get message element */ /* Check binding */
element = read_ops->parse((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops); if (IS_80211_MESSAGE_ELEMENTS(id) &&
(binding != CAPWAP_WIRELESS_BINDING_IEEE80211))
return UNRECOGNIZED_MESSAGE_ELEMENT;
capwap_logging_debug("MESSAGE ELEMENT: %d", id.type);
if (id.type == CAPWAP_ELEMENT_VENDORPAYLOAD_TYPE) {
struct capwap_message_element_id vendor_id;
if (msglength < 7) {
capwap_logging_debug("Invalid Vendor Specific Payload element: underbuffer");
return INVALID_MESSAGE_ELEMENT;
}
if ((msglength - 6) > CAPWAP_VENDORPAYLOAD_MAXLENGTH) {
capwap_logging_debug("Invalid Vendor Specific Payload element: overbuffer");
return INVALID_MESSAGE_ELEMENT;
}
rxmngpacket->read_ops.read_u32((capwap_message_elements_handle)rxmngpacket, &vendor_id.vendor);
rxmngpacket->read_ops.read_u16((capwap_message_elements_handle)rxmngpacket, &vendor_id.type);
capwap_logging_debug("VENDOR MESSAGE ELEMENT: %06x:%d", id.vendor, id.type);
read_ops = capwap_get_message_element_ops(vendor_id);
capwap_logging_debug("vendor read_ops: %p", read_ops);
if (read_ops) {
id = vendor_id;
element = read_ops->parse((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops);
} else {
read_ops = capwap_get_message_element_ops(id);
element = capwap_unknown_vendorpayload_element_parsing((capwap_message_elements_handle)rxmngpacket,
&rxmngpacket->read_ops, msglength - 6, vendor_id);
}
} else {
/* Reader function */
read_ops = capwap_get_message_element_ops(id);
capwap_logging_debug("read_ops: %p", read_ops);
if (!read_ops)
return UNRECOGNIZED_MESSAGE_ELEMENT;
/* Get message element */
element = read_ops->parse((capwap_message_elements_handle)rxmngpacket, &rxmngpacket->read_ops);
}
if (!element) if (!element)
return INVALID_MESSAGE_ELEMENT; return INVALID_MESSAGE_ELEMENT;

View File

@ -45,6 +45,7 @@ struct capwap_message_elements_ops
const struct capwap_message_elements_ops *capwap_get_message_element_ops(const struct capwap_message_element_id id); const struct capwap_message_elements_ops *capwap_get_message_element_ops(const struct capwap_message_element_id id);
/*********************************************************************************************************************/ /*********************************************************************************************************************/
/* Standard message elements */ /* Standard message elements */
#include "capwap_element_acdescriptor.h" /* 00001 */ #include "capwap_element_acdescriptor.h" /* 00001 */
#include "capwap_element_acipv4list.h" /* 00002 */ #include "capwap_element_acipv4list.h" /* 00002 */
@ -127,9 +128,7 @@ const struct capwap_message_elements_ops *capwap_get_message_element_ops(const s
#include "capwap_element_80211_wtpradiofailalarm.h" /* 01047 */ #include "capwap_element_80211_wtpradiofailalarm.h" /* 01047 */
#include "capwap_element_80211_wtpradioinformation.h" /* 01048 */ #include "capwap_element_80211_wtpradioinformation.h" /* 01048 */
/* draft-ietf-opsawg-capwap-extension-06 */ #include "capwap_vendor_travelping.h"
#include "capwap_element_80211n_radioconf.h"
#include "capwap_element_80211n_station_information.h"
/*********************************************************************************************************************/ /*********************************************************************************************************************/
#define CAPWAP_MESSAGE_ELEMENT_SINGLE 0 #define CAPWAP_MESSAGE_ELEMENT_SINGLE 0

View File

@ -40,7 +40,7 @@ capwap_80211n_radioconf_element_parsing(capwap_message_elements_handle handle,
{ {
struct capwap_80211n_radioconf_element *data; struct capwap_80211n_radioconf_element *data;
uint16_t reserved; uint16_t reserved;
ASSERT(handle != NULL); ASSERT(handle != NULL);
ASSERT(func != NULL); ASSERT(func != NULL);
@ -79,7 +79,7 @@ static void
capwap_80211n_radioconf_element_free(void* data) capwap_80211n_radioconf_element_free(void* data)
{ {
ASSERT(data != NULL); ASSERT(data != NULL);
capwap_free(data); capwap_free(data);
} }

View File

@ -1,9 +1,9 @@
#ifndef __CAPWAP_ELEMENT_80211N_RADIO_CONF_HEADER__ #ifndef __CAPWAP_ELEMENT_80211N_RADIO_CONF_HEADER__
#define __CAPWAP_ELEMENT_80211N_RADIO_CONF_HEADER__ #define __CAPWAP_ELEMENT_80211N_RADIO_CONF_HEADER__
#define CAPWAP_ELEMENT_80211N_RADIO_CONF_VENDOR 0 #define CAPWAP_ELEMENT_80211N_RADIO_CONF_VENDOR CAPWAP_VENDOR_TRAVELPING_ID
#define CAPWAP_ELEMENT_80211N_RADIO_CONF_TYPE 1046 #define CAPWAP_ELEMENT_80211N_RADIO_CONF_TYPE 8
#define CAPWAP_ELEMENT_80211N_RADIO_CONF (struct capwap_message_element_id){ .vendor = CAPWAP_ELEMENT_80211N_RADIO_CONF_VENDOR, .type = CAPWAP_ELEMENT_80211N_RADIO_CONF_TYPE } #define CAPWAP_ELEMENT_80211N_RADIO_CONF (struct capwap_message_element_id){ .vendor = CAPWAP_ELEMENT_80211N_RADIO_CONF_VENDOR, .type = CAPWAP_ELEMENT_80211N_RADIO_CONF_TYPE }
#define CAPWAP_80211N_RADIO_CONF_A_MSDU (1 << 7) #define CAPWAP_80211N_RADIO_CONF_A_MSDU (1 << 7)

View File

@ -32,14 +32,14 @@ capwap_80211n_station_info_element_create(void *data,
ASSERT(data != NULL); ASSERT(data != NULL);
func->write_block(handle, &element->address, MACADDRESS_EUI48_LENGTH); func->write_block(handle, element->address, MACADDRESS_EUI48_LENGTH);
func->write_u8(handle, element->flags); func->write_u8(handle, element->flags);
func->write_u8(handle, element->maxrxfactor); func->write_u8(handle, element->maxrxfactor);
func->write_u8(handle, element->minstaspaceing); func->write_u8(handle, element->minstaspaceing);
func->write_u16(handle, element->hisuppdatarate); func->write_u16(handle, element->hisuppdatarate);
func->write_u16(handle, element->ampdubufsize); func->write_u16(handle, element->ampdubufsize);
func->write_u8(handle, element->htcsupp); func->write_u8(handle, element->htcsupp);
func->write_block(handle, &element->mcsset, MCS_SET_LENGTH); func->write_block(handle, element->mcsset, MCS_SET_LENGTH);
} }
/* */ /* */
@ -48,8 +48,7 @@ capwap_80211n_station_info_element_parsing(capwap_message_elements_handle handle
struct capwap_read_message_elements_ops *func) struct capwap_read_message_elements_ops *func)
{ {
struct capwap_80211n_station_info_element *data; struct capwap_80211n_station_info_element *data;
uint16_t reserved;
ASSERT(handle != NULL); ASSERT(handle != NULL);
ASSERT(func != NULL); ASSERT(func != NULL);
@ -63,14 +62,14 @@ capwap_80211n_station_info_element_parsing(capwap_message_elements_handle handle
memset(data, 0, sizeof(struct capwap_80211n_station_info_element)); memset(data, 0, sizeof(struct capwap_80211n_station_info_element));
/* Retrieve data */ /* Retrieve data */
func->read_block(handle, &data->address, MACADDRESS_EUI48_LENGTH); func->read_block(handle, data->address, MACADDRESS_EUI48_LENGTH);
func->read_u8(handle, &data->flags); func->read_u8(handle, &data->flags);
func->read_u8(handle, &data->maxrxfactor); func->read_u8(handle, &data->maxrxfactor);
func->read_u8(handle, &data->minstaspaceing); func->read_u8(handle, &data->minstaspaceing);
func->read_u16(handle, &data->hisuppdatarate); func->read_u16(handle, &data->hisuppdatarate);
func->read_u16(handle, &data->ampdubufsize); func->read_u16(handle, &data->ampdubufsize);
func->read_u8(handle, &data->htcsupp); func->read_u8(handle, &data->htcsupp);
func->read_block(handle, &data->mcsset, MCS_SET_LENGTH); func->read_block(handle, data->mcsset, MCS_SET_LENGTH);
return data; return data;
} }
@ -89,7 +88,7 @@ static void
capwap_80211n_station_info_element_free(void* data) capwap_80211n_station_info_element_free(void* data)
{ {
ASSERT(data != NULL); ASSERT(data != NULL);
capwap_free(data); capwap_free(data);
} }

View File

@ -1,9 +1,9 @@
#ifndef __CAPWAP_ELEMENT_80211N_STATION_INFO_HEADER__ #ifndef __CAPWAP_ELEMENT_80211N_STATION_INFO_HEADER__
#define __CAPWAP_ELEMENT_80211N_STATION_INFO_HEADER__ #define __CAPWAP_ELEMENT_80211N_STATION_INFO_HEADER__
#define CAPWAP_ELEMENT_80211N_STATION_INFO_VENDOR 0 #define CAPWAP_ELEMENT_80211N_STATION_INFO_VENDOR CAPWAP_VENDOR_TRAVELPING_ID
#define CAPWAP_ELEMENT_80211N_STATION_INFO_TYPE 1046 #define CAPWAP_ELEMENT_80211N_STATION_INFO_TYPE 9
#define CAPWAP_ELEMENT_80211N_STATION_INFO (struct capwap_message_element_id){ .vendor = CAPWAP_ELEMENT_80211N_STATION_INFO_VENDOR, .type = CAPWAP_ELEMENT_80211N_STATION_INFO_TYPE } #define CAPWAP_ELEMENT_80211N_STATION_INFO (struct capwap_message_element_id){ .vendor = CAPWAP_ELEMENT_80211N_STATION_INFO_VENDOR, .type = CAPWAP_ELEMENT_80211N_STATION_INFO_TYPE }
#define CAPWAP_80211N_STATION_INFO_40MHZ_BANDWITH (1 << 7) #define CAPWAP_80211N_STATION_INFO_40MHZ_BANDWITH (1 << 7)

View File

@ -1,25 +1,28 @@
#include "capwap.h" #include "capwap.h"
#include "capwap_element.h" #include "capwap_element.h"
/******************************************************************** /*
*
0 1 2 3 * 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 * 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 | * | Vendor Identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Element ID | Data... * | Element ID | Data...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
Type: 37 for Vendor Specific Payload * Type: 37 for Vendor Specific Payload
*
Length: >= 7 * Length: >= 7
*
********************************************************************/ */
/* */ /* */
static void capwap_vendorpayload_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { static void capwap_vendorpayload_element_create(void* data,
struct capwap_vendorpayload_element* element = (struct capwap_vendorpayload_element*)data; capwap_message_elements_handle handle,
struct capwap_write_message_elements_ops* func)
{
struct capwap_vendorpayload_element* element = (struct capwap_vendorpayload_element *)data;
ASSERT(data != NULL); ASSERT(data != NULL);
ASSERT(element->datalength > 0); ASSERT(element->datalength > 0);
@ -30,45 +33,38 @@ static void capwap_vendorpayload_element_create(void* data, capwap_message_eleme
} }
/* */ /* */
static void* capwap_vendorpayload_element_clone(void* data) { static void* capwap_vendorpayload_element_clone(void *data)
struct capwap_vendorpayload_element* cloneelement; {
struct capwap_vendorpayload_element* element = (struct capwap_vendorpayload_element *)data;
ASSERT(data != NULL); ASSERT(data != NULL);
cloneelement = capwap_clone(data, sizeof(struct capwap_vendorpayload_element)); return capwap_clone(data, sizeof(struct capwap_vendorpayload_element) + element->datalength);
if (cloneelement->datalength > 0) {
cloneelement->data = capwap_clone(((struct capwap_vendorpayload_element*)data)->data, cloneelement->datalength);
}
return cloneelement;
} }
/* */ /* */
static void capwap_vendorpayload_element_free(void* data) { static void capwap_vendorpayload_element_free(void *data)
struct capwap_vendorpayload_element* element = (struct capwap_vendorpayload_element*)data; {
ASSERT(data != NULL); ASSERT(data != NULL);
if (element->data) {
capwap_free(element->data);
}
capwap_free(data); capwap_free(data);
} }
/* */ /* */
static void * void *
capwap_unknown_vendorpayload_element_parsing(capwap_message_elements_handle handle, capwap_unknown_vendorpayload_element_parsing(capwap_message_elements_handle handle,
struct capwap_read_message_elements_ops *func, struct capwap_read_message_elements_ops *func,
unsigned short length, unsigned short length,
uint32_t vendorid, uint16_t elementid) const struct capwap_message_element_id vendor_id)
{ {
struct capwap_vendorpayload_element* data;
/* Retrieve data */ /* Retrieve data */
data = (struct capwap_vendorpayload_element*)capwap_alloc(sizeof(struct capwap_vendorpayload_element)); data = (struct capwap_vendorpayload_element *)capwap_alloc(sizeof(struct capwap_vendorpayload_element)
data->data = (uint8_t*)capwap_alloc(length); + length);
data->vendorid = vendorid; data->vendorid = vendor_id.vendor;
data->elementid = elementid; data->elementid = vendor_id.type;
data->datalength = length; data->datalength = length;
func->read_block(handle, data->data, length); func->read_block(handle, data->data, length);
@ -81,9 +77,7 @@ capwap_vendorpayload_element_parsing(capwap_message_elements_handle handle,
struct capwap_read_message_elements_ops *func) struct capwap_read_message_elements_ops *func)
{ {
unsigned short length; unsigned short length;
uint32_t vendorid; struct capwap_message_element_id vendor_id;
uint16_t elementid;
struct capwap_vendorpayload_element* data;
ASSERT(handle != NULL); ASSERT(handle != NULL);
ASSERT(func != NULL); ASSERT(func != NULL);
@ -100,27 +94,11 @@ capwap_vendorpayload_element_parsing(capwap_message_elements_handle handle,
return NULL; return NULL;
} }
func->read_u32(handle, &vendorid); /* Retrieve data */
func->read_u16(handle, &elementid); func->read_u32(handle, &vendor_id.vendor);
func->read_u16(handle, &vendor_id.type);
switch (vendorid) { return capwap_unknown_vendorpayload_element_parsing(handle, func, length, vendor_id);
case VENDOR_TRAVELPING:
switch (elementid) {
case VENDOR_TRAVELPING_ELEMENT_80211N_RADIO_CONF:
case VENDOR_TRAVELPING_ELEMENT_80211N_STATION_INFO:
default:
data = capwap_unknown_vendorpayload_element_parsing(handle, func, length,
vendorid, elementid);
break;
}
break;
default:
data = capwap_unknown_vendorpayload_element_parsing(handle, func, length,
vendorid, elementid);
break;
}
return data;
} }
/* */ /* */

View File

@ -1,10 +1,6 @@
#ifndef __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ #ifndef __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__
#define __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ #define __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__
#define VENDOR_TRAVELPING 18681
#define VENDOR_TRAVELPING_ELEMENT_80211N_RADIO_CONF 123
#define VENDOR_TRAVELPING_ELEMENT_80211N_STATION_INFO 124
#define CAPWAP_ELEMENT_VENDORPAYLOAD_VENDOR 0 #define CAPWAP_ELEMENT_VENDORPAYLOAD_VENDOR 0
#define CAPWAP_ELEMENT_VENDORPAYLOAD_TYPE 37 #define CAPWAP_ELEMENT_VENDORPAYLOAD_TYPE 37
#define CAPWAP_ELEMENT_VENDORPAYLOAD (struct capwap_message_element_id){ .vendor = CAPWAP_ELEMENT_VENDORPAYLOAD_VENDOR, .type = CAPWAP_ELEMENT_VENDORPAYLOAD_TYPE } #define CAPWAP_ELEMENT_VENDORPAYLOAD (struct capwap_message_element_id){ .vendor = CAPWAP_ELEMENT_VENDORPAYLOAD_VENDOR, .type = CAPWAP_ELEMENT_VENDORPAYLOAD_TYPE }
@ -16,9 +12,15 @@ struct capwap_vendorpayload_element {
uint32_t vendorid; uint32_t vendorid;
uint16_t elementid; uint16_t elementid;
uint16_t datalength; uint16_t datalength;
uint8_t* data; uint8_t data[];
}; };
void *
capwap_unknown_vendorpayload_element_parsing(capwap_message_elements_handle handle,
struct capwap_read_message_elements_ops *func,
unsigned short length,
const struct capwap_message_element_id vendor_id);
extern const struct capwap_message_elements_ops capwap_element_vendorpayload_ops; extern const struct capwap_message_elements_ops capwap_element_vendorpayload_ops;
#endif /* __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ */ #endif /* __CAPWAP_ELEMENT_VENDORPAYLOAD_HEADER__ */

View File

@ -513,7 +513,10 @@ void capwap_packet_txmng_add_message_element(struct capwap_packet_txmng *txmngpa
Type and Length is add to this function, only custom create write Value message element Type and Length is add to this function, only custom create write Value message element
*/ */
txmngpacket->write_ops.write_u16((capwap_message_elements_handle)txmngpacket, id.type); if (id.vendor != 0)
txmngpacket->write_ops.write_u16((capwap_message_elements_handle)txmngpacket, CAPWAP_ELEMENT_VENDORPAYLOAD_TYPE);
else
txmngpacket->write_ops.write_u16((capwap_message_elements_handle)txmngpacket, id.type);
/* Length of message element is calculate after create function */ /* Length of message element is calculate after create function */
writepos.item = txmngpacket->fragmentlist->last; writepos.item = txmngpacket->fragmentlist->last;
@ -521,6 +524,12 @@ void capwap_packet_txmng_add_message_element(struct capwap_packet_txmng *txmngpa
txmngpacket->write_ops.write_u16((capwap_message_elements_handle)txmngpacket, 0); txmngpacket->write_ops.write_u16((capwap_message_elements_handle)txmngpacket, 0);
txmngpacket->writerpacketsize = 0; txmngpacket->writerpacketsize = 0;
if (id.vendor != 0) {
/* Write vendor header */
txmngpacket->write_ops.write_u32((capwap_message_elements_handle)txmngpacket, id.vendor);
txmngpacket->write_ops.write_u16((capwap_message_elements_handle)txmngpacket, id.type);
}
/* Build message element */ /* Build message element */
func->create(data, (capwap_message_elements_handle)txmngpacket, &txmngpacket->write_ops); func->create(data, (capwap_message_elements_handle)txmngpacket, &txmngpacket->write_ops);

View File

@ -0,0 +1,10 @@
#ifndef __CAPWAP_VENDOR_TRAVELPING_HEADER__
#define __CAPWAP_VENDOR_TRAVELPING_HEADER__
#define CAPWAP_VENDOR_TRAVELPING_ID 18681
/* draft-ietf-opsawg-capwap-extension-06 */
#include "capwap_element_80211n_radioconf.h"
#include "capwap_element_80211n_station_information.h"
#endif /* __CAPWAP_VENDOR_TRAVELPING_HEADER__ */