diff --git a/build/Makefile_common.am b/build/Makefile_common.am index 30ed261..caa6f29 100755 --- a/build/Makefile_common.am +++ b/build/Makefile_common.am @@ -29,7 +29,12 @@ capwap_SOURCES = \ $(top_srcdir)/src/common/capwap_dfa.c \ $(top_srcdir)/src/common/capwap_element.c \ $(top_srcdir)/src/common/capwap_element_acdescriptor.c \ + $(top_srcdir)/src/common/capwap_element_actimestamp.c \ + $(top_srcdir)/src/common/capwap_element_addmacacl.c \ + $(top_srcdir)/src/common/capwap_element_addstation.c \ $(top_srcdir)/src/common/capwap_element_discoverytype.c \ + $(top_srcdir)/src/common/capwap_element_datatransferdata.c \ + $(top_srcdir)/src/common/capwap_element_datatransfermode.c \ $(top_srcdir)/src/common/capwap_element_wtpboarddata.c \ $(top_srcdir)/src/common/capwap_element_wtpdescriptor.c \ $(top_srcdir)/src/common/capwap_element_wtpframetunnelmode.c \ diff --git a/src/common/capwap_element.c b/src/common/capwap_element.c index 8b6a4b7..2456bfb 100644 --- a/src/common/capwap_element.c +++ b/src/common/capwap_element.c @@ -40,15 +40,15 @@ static struct capwap_message_elements_ops* capwap_message_elements[CAPWAP_MESSAG /* CAPWAP_ELEMENT_ACIPV6LIST */ &capwap_element_acipv6list_ops, /* CAPWAP_ELEMENT_ACNAME */ &capwap_element_acname_ops, /* CAPWAP_ELEMENT_ACNAMEPRIORITY */ &capwap_element_acnamepriority_ops, - /* */ NULL, - /* */ NULL, - /* */ NULL, + /* CAPWAP_ELEMENT_ACTIMESTAMP */ &capwap_element_actimestamp_ops, + /* CAPWAP_ELEMENT_ADDMACACL */ &capwap_element_addmacacl_ops, + /* CAPWAP_ELEMENT_ADDSTATION */ &capwap_element_addstation_ops, /* Reserved */ NULL, /* CAPWAP_ELEMENT_CONTROLIPV4 */ &capwap_element_controlipv4_ops, /* CAPWAP_ELEMENT_CONTROLIPV6 */ &capwap_element_controlipv6_ops, /* CAPWAP_ELEMENT_TIMERS */ &capwap_element_timers_ops, - /* */ NULL, - /* */ NULL, + /* CAPWAP_ELEMENT_DATATRANSFERDATA */ &capwap_element_datatransferdata_ops, + /* CAPWAP_ELEMENT_DATATRANSFERMODE */ &capwap_element_datatransfermode_ops, /* */ NULL, /* CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD */ &capwap_element_decrypterrorreportperiod_ops, /* */ NULL, @@ -81,7 +81,7 @@ static struct capwap_message_elements_ops* capwap_message_elements[CAPWAP_MESSAG /* CAPWAP_ELEMENT_WTPMACTYPE */ &capwap_element_wtpmactype_ops, /* CAPWAP_ELEMENT_WTPNAME */ &capwap_element_wtpname_ops, /* Reserved */ NULL, - /* */ NULL, + /* */ NULL, /* CAPWAP_ELEMENT_WTPREBOOTSTAT */ &capwap_element_wtprebootstat_ops, /* CAPWAP_ELEMENT_WTPSTATICIPADDRESS */ &capwap_element_wtpstaticipaddress_ops, /* CAPWAP_ELEMENT_LOCALIPV6 */ &capwap_element_localipv6_ops, diff --git a/src/common/capwap_element.h b/src/common/capwap_element.h index 086e182..ab12804 100644 --- a/src/common/capwap_element.h +++ b/src/common/capwap_element.h @@ -52,15 +52,15 @@ struct capwap_message_elements_ops* capwap_get_message_element_ops(unsigned shor #include "capwap_element_acipv6list.h" /* 00003 */ #include "capwap_element_acname.h" /* 00004 */ #include "capwap_element_acnamepriority.h" /* 00005 */ -/* 00006 */ -/* 00007 */ -/* 00008 */ +#include "capwap_element_actimestamp.h" /* 00006 */ +#include "capwap_element_addmacacl.h" /* 00007 */ +#include "capwap_element_addstation.h" /* 00008 */ /* Reserved */ /* 00009 */ #include "capwap_element_controlipv4.h" /* 00010 */ #include "capwap_element_controlipv6.h" /* 00011 */ #include "capwap_element_timers.h" /* 00012 */ -/* 00013 */ -/* 00014 */ +#include "capwap_element_datatransferdata.h" /* 00013 */ +#include "capwap_element_datatransfermode.h" /* 00014 */ /* 00015 */ #include "capwap_element_decrypterrorreportperiod.h" /* 00016 */ /* 00017 */ diff --git a/src/common/capwap_element_actimestamp.c b/src/common/capwap_element_actimestamp.c new file mode 100644 index 0000000..d07cc25 --- /dev/null +++ b/src/common/capwap_element_actimestamp.c @@ -0,0 +1,65 @@ +#include "capwap.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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Timestamp | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 6 for AC Timestamp + +Length: 4 + +********************************************************************/ + +/* */ +static void capwap_actimestamp_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { + struct capwap_actimestamp_element* element = (struct capwap_actimestamp_element*)data; + + ASSERT(data != NULL); + + /* */ + func->write_u32(handle, element->timestamp); +} + +/* */ +static void* capwap_actimestamp_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { + struct capwap_actimestamp_element* data; + + ASSERT(handle != NULL); + ASSERT(func != NULL); + + if (func->read_ready(handle) != 4) { + capwap_logging_debug("Invalid AC Timestamp element"); + return NULL; + } + + /* */ + data = (struct capwap_actimestamp_element*)capwap_alloc(sizeof(struct capwap_actimestamp_element)); + if (!data) { + capwap_outofmemory(); + } + + /* Retrieve data */ + memset(data, 0, sizeof(struct capwap_actimestamp_element)); + func->read_u32(handle, &data->timestamp); + + return data; +} + +/* */ +static void capwap_actimestamp_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} + +/* */ +struct capwap_message_elements_ops capwap_element_actimestamp_ops = { + .create_message_element = capwap_actimestamp_element_create, + .parsing_message_element = capwap_actimestamp_element_parsing, + .free_parsed_message_element = capwap_actimestamp_element_free +}; diff --git a/src/common/capwap_element_actimestamp.h b/src/common/capwap_element_actimestamp.h new file mode 100644 index 0000000..ba895ce --- /dev/null +++ b/src/common/capwap_element_actimestamp.h @@ -0,0 +1,13 @@ +#ifndef __CAPWAP_ELEMENT_AC_TIMESTAMP_HEADER__ +#define __CAPWAP_ELEMENT_AC_TIMESTAMP_HEADER__ + +#define CAPWAP_ELEMENT_ACTIMESTAMP 6 + + +struct capwap_actimestamp_element { + uint32_t timestamp; +}; + +extern struct capwap_message_elements_ops capwap_element_actimestamp_ops; + +#endif /* __CAPWAP_ELEMENT_AC_TIMESTAMP_HEADER__ */ diff --git a/src/common/capwap_element_addmacacl.c b/src/common/capwap_element_addmacacl.c new file mode 100644 index 0000000..7049cf5 --- /dev/null +++ b/src/common/capwap_element_addmacacl.c @@ -0,0 +1,95 @@ +#include "capwap.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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Num of Entries| Length | MAC Address ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +Type: 7 for Add MAC ACL Entry + +Length: >= 8 + +********************************************************************/ + +/* */ +static void capwap_addmacacl_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { + struct capwap_addmacacl_element* element = (struct capwap_addmacacl_element*)data; + + ASSERT(data != NULL); + + func->write_u8(handle, element->entry); + func->write_u8(handle, element->length); + func->write_block(handle, element->address, element->entry * element->length); +} + +/* */ +static void capwap_addmacacl_element_free(void* data) { + struct capwap_addmacacl_element* element = (struct capwap_addmacacl_element*)data; + + ASSERT(data != NULL); + + if (element->address) { + capwap_free(element->address); + } + + capwap_free(element); +} + +/* */ +static void* capwap_addmacacl_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { + unsigned short length; + struct capwap_addmacacl_element* data; + + ASSERT(handle != NULL); + ASSERT(func != NULL); + + length = func->read_ready(handle); + if (length < 8) { + capwap_logging_debug("Invalid Add MAC ACL Entry element"); + return NULL; + } + + length -= 2; + if ((length % 6) && (length % 8)) { + capwap_logging_debug("Invalid Add MAC ACL Entry element"); + return NULL; + } + + /* */ + data = (struct capwap_addmacacl_element*)capwap_alloc(sizeof(struct capwap_addmacacl_element)); + if (!data) { + capwap_outofmemory(); + } + + /* Retrieve data */ + memset(data, 0, sizeof(struct capwap_addmacacl_element)); + + func->read_u8(handle, &data->entry); + func->read_u8(handle, &data->length); + + if (length != (data->entry * data->length)) { + capwap_addmacacl_element_free((void*)data); + capwap_logging_debug("Invalid Add MAC ACL Entry element"); + return NULL; + } + + data->address = (uint8_t*)capwap_alloc(length); + if (!data->address) { + capwap_outofmemory(); + } + + func->read_block(handle, data->address, length); + + return data; +} + +/* */ +struct capwap_message_elements_ops capwap_element_addmacacl_ops = { + .create_message_element = capwap_addmacacl_element_create, + .parsing_message_element = capwap_addmacacl_element_parsing, + .free_parsed_message_element = capwap_addmacacl_element_free +}; diff --git a/src/common/capwap_element_addmacacl.h b/src/common/capwap_element_addmacacl.h new file mode 100644 index 0000000..951eeb9 --- /dev/null +++ b/src/common/capwap_element_addmacacl.h @@ -0,0 +1,14 @@ +#ifndef __CAPWAP_ELEMENT_80211_ADD_MAC_ACL__HEADER__ +#define __CAPWAP_ELEMENT_80211_ADD_MAC_ACL__HEADER__ + +#define CAPWAP_ELEMENT_ADDMACACL 7 + +struct capwap_addmacacl_element { + uint8_t entry; + uint8_t length; + uint8_t* address; +}; + +extern struct capwap_message_elements_ops capwap_element_addmacacl_ops; + +#endif /* __CAPWAP_ELEMENT_80211_ADD_MAC_ACL__HEADER__ */ diff --git a/src/common/capwap_element_addstation.c b/src/common/capwap_element_addstation.c new file mode 100644 index 0000000..12df16d --- /dev/null +++ b/src/common/capwap_element_addstation.c @@ -0,0 +1,107 @@ +#include "capwap.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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Radio ID | Length | MAC Address ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| VLAN Name... ++-+-+-+-+-+-+-+-+ + +Type: 8 for Add Station + +Length: >= 8 + +********************************************************************/ + +/* */ +static void capwap_addstation_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { + struct capwap_addstation_element* element = (struct capwap_addstation_element*)data; + + ASSERT(data != NULL); + + func->write_u8(handle, element->radioid); + func->write_u8(handle, element->length); + func->write_block(handle, element->address, element->length); + if (element->vlan && *element->vlan) { + func->write_block(handle, element->vlan, strlen((char*)element->vlan)); + } +} + +/* */ +static void capwap_addstation_element_free(void* data) { + struct capwap_addstation_element* element = (struct capwap_addstation_element*)data; + + ASSERT(data != NULL); + + if (element->address) { + capwap_free(element->address); + } + + capwap_free(element); +} + +/* */ +static void* capwap_addstation_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { + unsigned short length; + struct capwap_addstation_element* data; + + ASSERT(handle != NULL); + ASSERT(func != NULL); + + length = func->read_ready(handle); + if (length < 8) { + capwap_logging_debug("Invalid Add Station element"); + return NULL; + } + + length -= 2; + + /* */ + data = (struct capwap_addstation_element*)capwap_alloc(sizeof(struct capwap_addstation_element)); + if (!data) { + capwap_outofmemory(); + } + + /* Retrieve data */ + memset(data, 0, sizeof(struct capwap_addstation_element)); + + func->read_u8(handle, &data->radioid); + func->read_u8(handle, &data->length); + + if (length < data->length) { + capwap_addstation_element_free((void*)data); + capwap_logging_debug("Invalid Add Station element"); + return NULL; + } + + data->address = (uint8_t*)capwap_alloc(data->length); + if (!data->address) { + capwap_outofmemory(); + } + + func->read_block(handle, data->address, data->length); + length -= data->length; + + if (length) { + data->vlan = (uint8_t*)capwap_alloc(length + 1); + if (!data->vlan) { + capwap_outofmemory(); + } + + func->read_block(handle, data->vlan, length); + data->vlan[length] = 0; + } + + return data; +} + +/* */ +struct capwap_message_elements_ops capwap_element_addstation_ops = { + .create_message_element = capwap_addstation_element_create, + .parsing_message_element = capwap_addstation_element_parsing, + .free_parsed_message_element = capwap_addstation_element_free +}; diff --git a/src/common/capwap_element_addstation.h b/src/common/capwap_element_addstation.h new file mode 100644 index 0000000..6b64313 --- /dev/null +++ b/src/common/capwap_element_addstation.h @@ -0,0 +1,15 @@ +#ifndef __CAPWAP_ELEMENT_80211_ADD_STATION__HEADER__ +#define __CAPWAP_ELEMENT_80211_ADD_STATION__HEADER__ + +#define CAPWAP_ELEMENT_ADDSTATION 8 + +struct capwap_addstation_element { + uint8_t radioid; + uint8_t length; + uint8_t* address; + uint8_t* vlan; +}; + +extern struct capwap_message_elements_ops capwap_element_addstation_ops; + +#endif /* __CAPWAP_ELEMENT_80211_ADD_STATION__HEADER__ */ diff --git a/src/common/capwap_element_datatransferdata.c b/src/common/capwap_element_datatransferdata.c new file mode 100644 index 0000000..485d360 --- /dev/null +++ b/src/common/capwap_element_datatransferdata.c @@ -0,0 +1,95 @@ +#include "capwap.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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Data Type | Data Mode | Data Length | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Data .... ++-+-+-+-+-+-+-+-+ + +Type: 13 for Data Transfer Data + +Length: >= 5 + +********************************************************************/ + +/* */ +static void capwap_datatransferdata_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { + struct capwap_datatransferdata_element* element = (struct capwap_datatransferdata_element*)data; + + ASSERT(data != NULL); + + func->write_u8(handle, element->type); + func->write_u8(handle, element->mode); + func->write_u16(handle, element->length); + func->write_block(handle, element->data, element->length); +} + +/* */ +static void capwap_datatransferdata_element_free(void* data) { + struct capwap_datatransferdata_element* element = (struct capwap_datatransferdata_element*)data; + + ASSERT(data != NULL); + + if (element->data) { + capwap_free(element->data); + } + + capwap_free(element); +} + +/* */ +static void* capwap_datatransferdata_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { + unsigned short length; + struct capwap_datatransferdata_element* data; + + ASSERT(handle != NULL); + ASSERT(func != NULL); + + length = func->read_ready(handle); + if (length < 5) { + capwap_logging_debug("Invalid Data Transfer Data element"); + return NULL; + } + + length -= 4; + + /* */ + data = (struct capwap_datatransferdata_element*)capwap_alloc(sizeof(struct capwap_datatransferdata_element)); + if (!data) { + capwap_outofmemory(); + } + + /* Retrieve data */ + memset(data, 0, sizeof(struct capwap_datatransferdata_element)); + + func->read_u8(handle, &data->type); + func->read_u8(handle, &data->mode); + func->read_u16(handle, &data->length); + + if (length != data->length) { + capwap_datatransferdata_element_free((void*)data); + capwap_logging_debug("Invalid Data Transfer Data element"); + return NULL; + } + + data->data = (uint8_t*)capwap_alloc(length); + if (!data->data) { + capwap_outofmemory(); + } + + func->read_block(handle, data->data, length); + + return data; +} + +/* */ +struct capwap_message_elements_ops capwap_element_datatransferdata_ops = { + .create_message_element = capwap_datatransferdata_element_create, + .parsing_message_element = capwap_datatransferdata_element_parsing, + .free_parsed_message_element = capwap_datatransferdata_element_free +}; diff --git a/src/common/capwap_element_datatransferdata.h b/src/common/capwap_element_datatransferdata.h new file mode 100644 index 0000000..6774965 --- /dev/null +++ b/src/common/capwap_element_datatransferdata.h @@ -0,0 +1,22 @@ +#ifndef __CAPWAP_ELEMENT_80211_DATA_TRANSFER_DATA_HEADER__ +#define __CAPWAP_ELEMENT_80211_DATA_TRANSFER_DATA_HEADER__ + +#define CAPWAP_ELEMENT_DATATRANSFERDATA 13 + +#define CAPWAP_DATATRANSFERDATA_TYPE_DATA_IS_INCLUDED 1 +#define CAPWAP_DATATRANSFERDATA_TYPE_DATA_EOF 2 +#define CAPWAP_DATATRANSFERDATA_TYPE_ERROR 5 + +#define CAPWAP_DATATRANSFERDATA_MODE_CRASH_DUMP 1 +#define CAPWAP_DATATRANSFERDATA_MODE_MEMORY_DUMP 2 + +struct capwap_datatransferdata_element { + uint8_t type; + uint8_t mode; + uint16_t length; + uint8_t* data; +}; + +extern struct capwap_message_elements_ops capwap_element_datatransferdata_ops; + +#endif /* __CAPWAP_ELEMENT_80211_DATA_TRANSFER_DATA_HEADER__ */ diff --git a/src/common/capwap_element_datatransfermode.c b/src/common/capwap_element_datatransfermode.c new file mode 100644 index 0000000..2fb2090 --- /dev/null +++ b/src/common/capwap_element_datatransfermode.c @@ -0,0 +1,65 @@ +#include "capwap.h" +#include "capwap_element.h" + +/******************************************************************** + + 0 + 0 1 2 3 4 5 6 7 ++-+-+-+-+-+-+-+-+ +| Data Mode | ++-+-+-+-+-+-+-+-+ + +Type: 14 for Data Transfer Mode + +Length: 1 + +********************************************************************/ + +/* */ +static void capwap_datatransfermode_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) { + struct capwap_datatransfermode_element* element = (struct capwap_datatransfermode_element*)data; + + ASSERT(data != NULL); + + /* */ + func->write_u8(handle, element->mode); +} + +/* */ +static void* capwap_datatransfermode_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) { + struct capwap_datatransfermode_element* data; + + ASSERT(handle != NULL); + ASSERT(func != NULL); + + if (func->read_ready(handle) != 1) { + capwap_logging_debug("Invalid Data Transfer Mode element"); + return NULL; + } + + /* */ + data = (struct capwap_datatransfermode_element*)capwap_alloc(sizeof(struct capwap_datatransfermode_element)); + if (!data) { + capwap_outofmemory(); + } + + /* Retrieve data */ + memset(data, 0, sizeof(struct capwap_datatransfermode_element)); + func->read_u8(handle, &data->mode); + + return data; +} + +/* */ +static void capwap_datatransfermode_element_free(void* data) { + ASSERT(data != NULL); + + capwap_free(data); +} + +/* */ +struct capwap_message_elements_ops capwap_element_datatransfermode_ops = { + .create_message_element = capwap_datatransfermode_element_create, + .parsing_message_element = capwap_datatransfermode_element_parsing, + .free_parsed_message_element = capwap_datatransfermode_element_free +}; diff --git a/src/common/capwap_element_datatransfermode.h b/src/common/capwap_element_datatransfermode.h new file mode 100644 index 0000000..14a6f57 --- /dev/null +++ b/src/common/capwap_element_datatransfermode.h @@ -0,0 +1,15 @@ +#ifndef __CAPWAP_ELEMENT_80211_DATA_TRANSFER_MODE_HEADER__ +#define __CAPWAP_ELEMENT_80211_DATA_TRANSFER_MODE_HEADER__ + +#define CAPWAP_ELEMENT_DATATRANSFERMODE 14 + +#define CAPWAP_DATATRANSFERMODE_MODE_CRASH_DUMP 1 +#define CAPWAP_DATATRANSFERMODE_MODE_MEMORY_DUMP 2 + +struct capwap_datatransfermode_element { + uint8_t mode; +}; + +extern struct capwap_message_elements_ops capwap_element_datatransfermode_ops; + +#endif /* __CAPWAP_ELEMENT_80211_DATA_TRANSFER_MODE_HEADER__ */ diff --git a/src/common/capwap_rfc.h b/src/common/capwap_rfc.h index c1a7322..e035539 100644 --- a/src/common/capwap_rfc.h +++ b/src/common/capwap_rfc.h @@ -181,4 +181,14 @@ struct capwap_data_message { #define IS_SEQUENCE_SMALLER(s1, s2) (((((s1) < (s2)) && (((s2) - (s1)) < 128)) || (((s1) > (s2)) && (((s1) - (s2)) > 128))) ? 1 : 0) +/* */ +struct capwap_macaddress_eui48 { + uint8_t macaddress[6]; +} STRUCT_PACKED; + +/* */ +struct capwap_macaddress_eui64 { + uint8_t macaddress[8]; +} STRUCT_PACKED; + #endif /* __CAPWAP_RFC_HEADER__ */