3 Commits

Author SHA1 Message Date
76cd5d7484 release 1.3.2 2016-08-15 15:39:06 +02:00
a488af66cf add vendor VSA to set additional key and IGTK support
IGTK == Management Frame Protection
2016-08-15 15:30:29 +02:00
ac135e16c4 add VSA to report supported ciphers per radio 2016-08-12 12:08:06 +02:00
19 changed files with 499 additions and 95 deletions

View File

@ -3,6 +3,11 @@ SmartCAPWAP
CAPWAP WTP and AC implementation
Version 1.3.2 - 15 Aug 2016
---------------------------
* support management frame protection
Version 1.3.1 - 11 Aug 2016
---------------------------

View File

@ -9,14 +9,14 @@ include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=smartcapwap
PKG_VERSION:=1.2.1
PKG_VERSION:=1.3.2
PKG_RELEASE:=1
SRC_SMARTCAPWAP := /usr/src/tplino/components/smartcapwap
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=git://github.com/travelping/smartcapwap.git
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=v1.2.1
PKG_SOURCE_VERSION:=v1.3.2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

View File

@ -423,6 +423,23 @@ struct ieee80211_ie_erp {
/* 802.11 RSN information element */
#define IEEE80211_IE_RSN_INFORMATION 48
/* cipher suite selectors */
#define IEEE80211_CIPHER_SUITE_USE_GROUP 0x000FAC00
#define IEEE80211_CIPHER_SUITE_WEP40 0x000FAC01
#define IEEE80211_CIPHER_SUITE_TKIP 0x000FAC02
/* reserved: 0x000FAC03 */
#define IEEE80211_CIPHER_SUITE_CCMP 0x000FAC04
#define IEEE80211_CIPHER_SUITE_WEP104 0x000FAC05
#define IEEE80211_CIPHER_SUITE_AES_CMAC 0x000FAC06
#define IEEE80211_CIPHER_SUITE_NO_GROUP_ADDR 0x000FAC07
#define IEEE80211_CIPHER_SUITE_GCMP 0x000FAC08
#define IEEE80211_CIPHER_SUITE_GCMP_256 0x000FAC09
#define IEEE80211_CIPHER_SUITE_CCMP_256 0x000FAC0A
#define IEEE80211_CIPHER_SUITE_BIP_GMAC_128 0x000FAC0B
#define IEEE80211_CIPHER_SUITE_BIP_GMAC_256 0x000FAC0C
#define IEEE80211_CIPHER_SUITE_BIP_CMAC_256 0x000FAC0D
/* 802.11 Extended Supported Rates information element */
#define IEEE80211_IE_EXTENDED_SUPPORTED_RATES 50
#define IEEE80211_IE_EXTENDED_SUPPORTED_MIN_LENGTH 1

View File

@ -93,7 +93,9 @@ static const struct capwap_message_elements_ops * capwap_80211_message_elements[
static const struct capwap_message_elements_ops * capwap_vendor_travelping_message_elements[] = {
element_ops(CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_TYPE, capwap_element_vendor_travelping_wtp_timestamp_ops),
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)
element_ops(CAPWAP_ELEMENT_80211N_STATION_INFO_TYPE, capwap_element_80211n_station_info_ops),
element_ops(CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_TYPE, capwap_element_vendor_travelping_80211_encryption_capability_ops),
element_ops(CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_TYPE, capwap_element_vendor_travelping_80211_update_key_ops)
};
#undef element_ops

View File

@ -0,0 +1,103 @@
#include "capwap.h"
#include "capwap_element.h"
/*
* The IEEE 802.11 Encryption Capability message element is used by
* the WTP to inform the AC of the support cipher suites. It contains
* a list of suites as defined by IEEE 802.11 Sect. 8.4.2.27.2.
* The message element contains the following fields.
*
* 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 | Cipher Suites... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* IEEE 802.11 Encryption Capability
*
* Vendor Id: 18681 (Travelping GmbH)
* Type: 18
*
*/
/* */
static void
capwap_vendor_travelping_80211_encryption_capability_element_create(void *data,
capwap_message_elements_handle handle,
struct capwap_write_message_elements_ops *func)
{
int i;
struct capwap_vendor_travelping_80211_encryption_capability_element *element =
(struct capwap_vendor_travelping_80211_encryption_capability_element *)data;
ASSERT(data != NULL);
func->write_u8(handle, element->radioid);
for (i = 0; i < element->suites_count; i++)
func->write_u32(handle, element->suites[i]);
}
/* */
static void *
capwap_vendor_travelping_80211_encryption_capability_element_parsing(capwap_message_elements_handle handle,
struct capwap_read_message_elements_ops *func)
{
struct capwap_vendor_travelping_80211_encryption_capability_element *data;
int suites_length, i;
ASSERT(handle != NULL);
ASSERT(func != NULL);
if (func->read_ready(handle) < 1) {
log_printf(LOG_DEBUG, "Invalid Vendor Travelping WTP 802.11 Encryption Capability element");
return NULL;
}
suites_length = func->read_ready(handle) - 1;
if ((suites_length % sizeof(uint32_t)) != 0) {
log_printf(LOG_DEBUG, "Invalid Vendor Travelping WTP 802.11 Encryption Capability element");
return NULL;
}
/* */
data = (struct capwap_vendor_travelping_80211_encryption_capability_element *)
capwap_alloc(sizeof(struct capwap_vendor_travelping_80211_encryption_capability_element) + suites_length);
/* Retrieve data */
func->read_u8(handle, &data->radioid);
data->suites_count = suites_length / sizeof(uint32_t);
for (i = 0; i < data->suites_count; i++)
func->read_u32(handle, &data->suites[i]);
return data;
}
/* */
static void *
capwap_vendor_travelping_80211_encryption_capability_element_clone(void *data)
{
struct capwap_vendor_travelping_80211_encryption_capability_element *element =
(struct capwap_vendor_travelping_80211_encryption_capability_element *)data;
ASSERT(data != NULL);
return capwap_clone(data, sizeof(struct capwap_vendor_travelping_80211_encryption_capability_element)
+ element->suites_count * sizeof(uint32_t));
}
/* */
static void
capwap_vendor_travelping_80211_encryption_capability_element_free(void* data)
{
ASSERT(data != NULL);
capwap_free(data);
}
/* */
const struct capwap_message_elements_ops capwap_element_vendor_travelping_80211_encryption_capability_ops = {
.category = CAPWAP_MESSAGE_ELEMENT_ARRAY,
.create = capwap_vendor_travelping_80211_encryption_capability_element_create,
.parse = capwap_vendor_travelping_80211_encryption_capability_element_parsing,
.clone = capwap_vendor_travelping_80211_encryption_capability_element_clone,
.free = capwap_vendor_travelping_80211_encryption_capability_element_free
};

View File

@ -0,0 +1,21 @@
#ifndef __CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_HEADER__
#define __CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_HEADER__
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_VENDOR CAPWAP_VENDOR_TRAVELPING_ID
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_TYPE 18
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY \
(struct capwap_message_element_id){ \
.vendor = CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_VENDOR, \
.type = CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_TYPE \
}
struct capwap_vendor_travelping_80211_encryption_capability_element {
uint8_t radioid;
size_t suites_count;
uint32_t suites[];
};
extern const struct capwap_message_elements_ops capwap_element_vendor_travelping_80211_encryption_capability_ops;
#endif /* __CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY_HEADER__ */

View File

@ -0,0 +1,108 @@
#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 | WLAN ID | Key Index | Key Status |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Cipher Suite |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Key... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* IEEE 802.11 Update Key
*
* Vendor Id: 18681 (Travelping GmbH)
* Type: 19
*
* Length: >= 6
*
*/
/* */
static void
capwap_vendor_travelping_80211_update_key_element_create(void *data,
capwap_message_elements_handle handle,
struct capwap_write_message_elements_ops *func)
{
struct capwap_vendor_travelping_80211_update_key_element *element =
(struct capwap_vendor_travelping_80211_update_key_element*)data;
ASSERT(data != NULL);
func->write_u8(handle, element->radioid);
func->write_u8(handle, element->wlanid);
func->write_u8(handle, element->keyindex);
func->write_u8(handle, element->keystatus);
func->write_u32(handle, element->ciphersuite);
if (element->keylength > 0)
func->write_block(handle, element->key, element->keylength);
}
/* */
static void *
capwap_vendor_travelping_80211_update_key_element_parsing(capwap_message_elements_handle handle,
struct capwap_read_message_elements_ops *func)
{
unsigned short length;
struct capwap_vendor_travelping_80211_update_key_element *data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
length = func->read_ready(handle);
if (length < 8) {
log_printf(LOG_DEBUG, "Invalid Vendor Travelping IEEE 802.11 Update Key element");
return NULL;
}
length -= 8;
/* */
data = (struct capwap_vendor_travelping_80211_update_key_element *)
capwap_alloc(sizeof(struct capwap_vendor_travelping_80211_update_key_element) + length);
memset(data, 0, sizeof(struct capwap_vendor_travelping_80211_update_key_element) + length);
/* Retrieve data */
func->read_u8(handle, &data->radioid);
func->read_u8(handle, &data->wlanid);
func->read_u8(handle, &data->keyindex);
func->read_u8(handle, &data->keystatus);
func->read_u32(handle, &data->ciphersuite);
data->keylength = length;
func->read_block(handle, data->key, data->keylength);
return data;
}
/* */
static void *capwap_vendor_travelping_80211_update_key_element_clone(void *data)
{
struct capwap_vendor_travelping_80211_update_key_element *element =
(struct capwap_vendor_travelping_80211_update_key_element*)data;
ASSERT(data != NULL);
return capwap_clone(data, sizeof(struct capwap_vendor_travelping_80211_update_key_element) +
element->keylength);
}
/* */
static void capwap_vendor_travelping_80211_update_key_element_free(void *data)
{
ASSERT(data != NULL);
capwap_free(data);
}
/* */
const struct capwap_message_elements_ops capwap_element_vendor_travelping_80211_update_key_ops = {
.category = CAPWAP_MESSAGE_ELEMENT_ARRAY,
.create = capwap_vendor_travelping_80211_update_key_element_create,
.parse = capwap_vendor_travelping_80211_update_key_element_parsing,
.clone = capwap_vendor_travelping_80211_update_key_element_clone,
.free = capwap_vendor_travelping_80211_update_key_element_free
};

View File

@ -0,0 +1,27 @@
#ifndef __CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_HEADER__
#define __CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_HEADER__
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_VENDOR CAPWAP_VENDOR_TRAVELPING_ID
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_TYPE 19
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY \
(struct capwap_message_element_id){ \
.vendor = CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_VENDOR, \
.type = CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_TYPE \
}
#define CAPWAP_UPDATE_WLAN_KEY_STATUS_REKEYING 2
#define CAPWAP_UPDATE_WLAN_KEY_STATUS_COMPLETE 3
struct capwap_vendor_travelping_80211_update_key_element {
uint8_t radioid;
uint8_t wlanid;
uint8_t keyindex;
uint8_t keystatus;
uint32_t ciphersuite;
uint16_t keylength;
uint8_t key[];
};
extern const struct capwap_message_elements_ops capwap_element_vendor_travelping_80211_update_key_ops;
#endif /* __CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY_HEADER__ */

View File

@ -35,9 +35,11 @@ Length: >= 33
********************************************************************/
/* */
static void capwap_wtpdescriptor_element_create(void* data, capwap_message_elements_handle handle, struct capwap_write_message_elements_ops* func) {
static void capwap_wtpdescriptor_element_create(void *data, capwap_message_elements_handle handle,
struct capwap_write_message_elements_ops *func)
{
int i;
struct capwap_wtpdescriptor_element* element = (struct capwap_wtpdescriptor_element*)data;
struct capwap_wtpdescriptor_element *element = (struct capwap_wtpdescriptor_element *)data;
ASSERT(data != NULL);
ASSERT(element->maxradios >= element->radiosinuse);
@ -51,7 +53,9 @@ static void capwap_wtpdescriptor_element_create(void* data, capwap_message_eleme
/* */
for (i = 0; i < element->encryptsubelement->count; i++) {
struct capwap_wtpdescriptor_encrypt_subelement* desc = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(element->encryptsubelement, i);
struct capwap_wtpdescriptor_encrypt_subelement *desc =
(struct capwap_wtpdescriptor_encrypt_subelement *)
capwap_array_get_item_pointer(element->encryptsubelement, i);
ASSERT((desc->wbid & CAPWAP_WTPDESC_SUBELEMENT_WBID_MASK) == desc->wbid);
@ -62,9 +66,12 @@ static void capwap_wtpdescriptor_element_create(void* data, capwap_message_eleme
/* */
for (i = 0; i < element->descsubelement->count; i++) {
uint16_t length;
struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
struct capwap_wtpdescriptor_desc_subelement *desc =
(struct capwap_wtpdescriptor_desc_subelement *)
capwap_array_get_item_pointer(element->descsubelement, i);
ASSERT((desc->type >= CAPWAP_WTPDESC_SUBELEMENT_TYPE_FIRST) && (desc->type <= CAPWAP_WTPDESC_SUBELEMENT_TYPE_LAST));
ASSERT((desc->type >= CAPWAP_WTPDESC_SUBELEMENT_TYPE_FIRST) &&
(desc->type <= CAPWAP_WTPDESC_SUBELEMENT_TYPE_LAST));
length = strlen((char*)desc->data);
ASSERT(length > 0);
@ -77,38 +84,48 @@ static void capwap_wtpdescriptor_element_create(void* data, capwap_message_eleme
}
/* */
static void* capwap_wtpdescriptor_element_clone(void* data) {
static void *capwap_wtpdescriptor_element_clone(void *data)
{
int i;
struct capwap_wtpdescriptor_element* cloneelement;
struct capwap_wtpdescriptor_element* element = (struct capwap_wtpdescriptor_element*)data;
struct capwap_wtpdescriptor_element *cloneelement;
struct capwap_wtpdescriptor_element *element = (struct capwap_wtpdescriptor_element*)data;
ASSERT(data != NULL);
cloneelement = capwap_clone(data, sizeof(struct capwap_wtpdescriptor_element));
cloneelement->encryptsubelement = capwap_array_create(sizeof(struct capwap_wtpdescriptor_encrypt_subelement), 0, 0);
for (i = 0; i < element->encryptsubelement->count; i++) {
memcpy(capwap_array_get_item_pointer(cloneelement->encryptsubelement, i), capwap_array_get_item_pointer(element->encryptsubelement, i), sizeof(struct capwap_wtpdescriptor_encrypt_subelement));
}
cloneelement->encryptsubelement =
capwap_array_create(sizeof(struct capwap_wtpdescriptor_encrypt_subelement), 0, 0);
for (i = 0; i < element->encryptsubelement->count; i++)
memcpy(capwap_array_get_item_pointer(cloneelement->encryptsubelement, i),
capwap_array_get_item_pointer(element->encryptsubelement, i),
sizeof(struct capwap_wtpdescriptor_encrypt_subelement));
cloneelement->descsubelement =
capwap_array_create(sizeof(struct capwap_wtpdescriptor_desc_subelement), 0, 1);
cloneelement->descsubelement = capwap_array_create(sizeof(struct capwap_wtpdescriptor_desc_subelement), 0, 1);
for (i = 0; i < element->descsubelement->count; i++) {
struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
struct capwap_wtpdescriptor_desc_subelement* clonedesc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(cloneelement->descsubelement, i);
struct capwap_wtpdescriptor_desc_subelement *desc =
(struct capwap_wtpdescriptor_desc_subelement *)
capwap_array_get_item_pointer(element->descsubelement, i);
struct capwap_wtpdescriptor_desc_subelement *clonedesc =
(struct capwap_wtpdescriptor_desc_subelement *)
capwap_array_get_item_pointer(cloneelement->descsubelement, i);
memcpy(clonedesc, desc, sizeof(struct capwap_wtpdescriptor_desc_subelement));
if (desc->data) {
clonedesc->data = (uint8_t*)capwap_duplicate_string((char*)desc->data);
}
if (desc->data)
clonedesc->data = (uint8_t*)capwap_duplicate_string((char *)desc->data);
}
return cloneelement;
}
/* */
static void capwap_wtpdescriptor_element_free(void* data) {
static void capwap_wtpdescriptor_element_free(void *data)
{
int i;
struct capwap_wtpdescriptor_element* element = (struct capwap_wtpdescriptor_element*)data;
struct capwap_wtpdescriptor_element *element = (struct capwap_wtpdescriptor_element *)data;
ASSERT(data != NULL);
ASSERT(element->encryptsubelement != NULL);
@ -116,11 +133,12 @@ static void capwap_wtpdescriptor_element_free(void* data) {
/* */
for (i = 0; i < element->descsubelement->count; i++) {
struct capwap_wtpdescriptor_desc_subelement* desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(element->descsubelement, i);
struct capwap_wtpdescriptor_desc_subelement *desc =
(struct capwap_wtpdescriptor_desc_subelement *)
capwap_array_get_item_pointer(element->descsubelement, i);
if (desc->data) {
if (desc->data)
capwap_free(desc->data);
}
}
capwap_array_free(element->encryptsubelement);
@ -129,10 +147,12 @@ static void capwap_wtpdescriptor_element_free(void* data) {
}
/* */
static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
static void *capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle handle,
struct capwap_read_message_elements_ops *func)
{
uint8_t i;
uint8_t encryptlength;
struct capwap_wtpdescriptor_element* data;
struct capwap_wtpdescriptor_element *data;
ASSERT(handle != NULL);
ASSERT(func != NULL);
@ -165,7 +185,7 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
/* Encryption Subelement */
for (i = 0; i < encryptlength; i++) {
struct capwap_wtpdescriptor_encrypt_subelement* desc;
struct capwap_wtpdescriptor_encrypt_subelement *desc;
/* Check */
if (func->read_ready(handle) < 3) {
@ -175,7 +195,8 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
}
/* */
desc = (struct capwap_wtpdescriptor_encrypt_subelement*)capwap_array_get_item_pointer(data->encryptsubelement, data->encryptsubelement->count);
desc = (struct capwap_wtpdescriptor_encrypt_subelement *)
capwap_array_get_item_pointer(data->encryptsubelement, data->encryptsubelement->count);
func->read_u8(handle, &desc->wbid);
func->read_u16(handle, &desc->capabilities);
@ -190,7 +211,7 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
while (func->read_ready(handle) > 0) {
unsigned short length;
uint16_t lengthdesc;
struct capwap_wtpdescriptor_desc_subelement* desc;
struct capwap_wtpdescriptor_desc_subelement *desc;
/* Check */
if (func->read_ready(handle) < 8) {
@ -200,12 +221,14 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
}
/* */
desc = (struct capwap_wtpdescriptor_desc_subelement*)capwap_array_get_item_pointer(data->descsubelement, data->descsubelement->count);
desc = (struct capwap_wtpdescriptor_desc_subelement *)
capwap_array_get_item_pointer(data->descsubelement, data->descsubelement->count);
func->read_u32(handle, &desc->vendor);
func->read_u16(handle, &desc->type);
func->read_u16(handle, &lengthdesc);
if ((desc->type < CAPWAP_WTPDESC_SUBELEMENT_TYPE_FIRST) || (desc->type > CAPWAP_WTPDESC_SUBELEMENT_TYPE_LAST)) {
if ((desc->type < CAPWAP_WTPDESC_SUBELEMENT_TYPE_FIRST) ||
(desc->type > CAPWAP_WTPDESC_SUBELEMENT_TYPE_LAST)) {
log_printf(LOG_DEBUG, "Invalid WTP Descriptor subelement: invalid type");
capwap_wtpdescriptor_element_free(data);
return NULL;
@ -213,7 +236,9 @@ static void* capwap_wtpdescriptor_element_parsing(capwap_message_elements_handle
/* Check buffer size */
length = func->read_ready(handle);
if (!length || (length > CAPWAP_WTPDESC_SUBELEMENT_MAXDATA) || (length < lengthdesc)) {
if (!length ||
(length > CAPWAP_WTPDESC_SUBELEMENT_MAXDATA) ||
(length < lengthdesc)) {
log_printf(LOG_DEBUG, "Invalid WTP Descriptor element");
capwap_wtpdescriptor_element_free(data);
return NULL;

View File

@ -4,6 +4,8 @@
#define CAPWAP_VENDOR_TRAVELPING_ID 18681
#include "capwap_element_vendor_travelping_wtp_timestamp.h"
#include "capwap_element_vendor_travelping_80211_encryption_capability.h"
#include "capwap_element_vendor_travelping_80211_update_key.h"
/* draft-ietf-opsawg-capwap-extension-06 */
#include "capwap_element_80211n_radioconf.h"

View File

@ -1665,7 +1665,7 @@ void wifi_driver_free(void)
}
if (device->capability->ciphers)
capwap_array_free(device->capability->ciphers);
capwap_free(device->capability->ciphers);
capwap_free(device->capability);
}
@ -1761,7 +1761,6 @@ struct wifi_device* wifi_device_connect(const char* ifname, const char* driver)
device->capability = (struct wifi_capability*)capwap_alloc(sizeof(struct wifi_capability));
memset(device->capability, 0, sizeof(struct wifi_capability));
device->capability->bands = capwap_array_create(sizeof(struct wifi_band_capability), 0, 1);
device->capability->ciphers = capwap_array_create(sizeof(struct wifi_cipher_capability), 0, 1);
/* Retrieve device capability */
device_getcapability(device, device->capability);
@ -2124,6 +2123,41 @@ static struct ieee80211_ie *rsn_from_ie(uint8_t radioid, uint8_t wlanid,
return NULL;
}
#define broadcast_ether_addr (const uint8_t *) "\xff\xff\xff\xff\xff\xff"
static int update_keys(struct wifi_wlan* wlan, struct capwap_array *keys)
{
int i, result = 0;
log_printf(LOG_DEBUG, "Wifi Update Keys: %p", keys);
if (!keys)
return 0;
log_printf(LOG_DEBUG, "Wifi Update Keys: #%ld", keys->count);
for (i = 0; i < keys->count; i++) {
struct capwap_vendor_travelping_80211_update_key_element *key =
*(struct capwap_vendor_travelping_80211_update_key_element **)
capwap_array_get_item_pointer(keys, i);
log_printf(LOG_DEBUG, "Wifi Update Keys: Update: Status: %d, CipherSuite: %08x, Index: %d, Len: %d",
key->keystatus, key->ciphersuite, key->keyindex, key->keylength);
switch (key->keystatus) {
case 3:
result = wlan_set_key(wlan, key->ciphersuite, broadcast_ether_addr,
key->keyindex, 1, NULL, 0,
key->keylength ? key->key : NULL, key->keylength);
log_printf(LOG_INFO, "Update KEY on interface: %s, SSID: '%s', result: %d",
wlan->virtname, wlan->ssid, result);
break;
default:
break;
}
}
return result;
}
/* */
int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params)
{
@ -2168,18 +2202,19 @@ int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params
/* Start AP */
result = wlan_startap(wlan);
if (!result) {
wlan->device->wlanactive++;
log_printf(LOG_INFO, "Configured interface: %s, SSID: '%s'", wlan->virtname, wlan->ssid);
} else {
if (result) {
wifi_wlan_stopap(wlan);
return result;
}
update_keys(wlan, params->updatekeys);
wlan->device->wlanactive++;
log_printf(LOG_INFO, "Configured interface: %s, SSID: '%s'", wlan->virtname, wlan->ssid);
return result;
}
#define broadcast_ether_addr (const uint8_t *) "\xff\xff\xff\xff\xff\xff"
/* */
int wifi_wlan_updateap(struct wifi_wlan* wlan, struct wlan_updateap_params* params)
{
@ -2238,6 +2273,9 @@ int wifi_wlan_updateap(struct wifi_wlan* wlan, struct wlan_updateap_params* para
break;
}
if (!result)
update_keys(wlan, params->updatekeys);
return result;
}

View File

@ -50,15 +50,6 @@
#define RATE_CAPABILITY_SHORTPREAMBLE 0x00000001
#define CIPHER_CAPABILITY_UNKNOWN 0
#define CIPHER_CAPABILITY_WEP40 1
#define CIPHER_CAPABILITY_WEP104 2
#define CIPHER_CAPABILITY_TKIP 3
#define CIPHER_CAPABILITY_CCMP 4
#define CIPHER_CAPABILITY_CMAC 5
#define CIPHER_CAPABILITY_GCMP 6
#define CIPHER_CAPABILITY_WPI_SMS4 7
#define IEEE80211_DFS_USABLE 0
#define IEEE80211_DFS_UNAVAILABLE 1
#define IEEE80211_DFS_AVAILABLE 2
@ -112,6 +103,7 @@ struct wlan_startap_params {
uint8_t *key;
struct capwap_array *ie;
struct capwap_array *updatekeys;
};
struct wlan_updateap_params {
@ -127,6 +119,7 @@ struct wlan_updateap_params {
uint8_t *key;
struct capwap_array *ie;
struct capwap_array *updatekeys;
};
/* */
@ -189,11 +182,6 @@ struct wifi_commands_capability {
unsigned int poll_command_supported:1;
};
/* */
struct wifi_cipher_capability {
unsigned long cipher;
};
/* */
struct wifi_capability {
struct wifi_device* device;
@ -217,7 +205,8 @@ struct wifi_capability {
struct wifi_commands_capability supp_cmds;
/* WIFI_CAPABILITY_CIPHERS */
struct capwap_array* ciphers;
int ciphers_count;
uint32_t *ciphers;
/* WIFI_CAPABILITY_MAX_SCAN_SSIDS */
uint8_t maxscanssids;

View File

@ -1060,7 +1060,12 @@ static int nl80211_set_key(struct wifi_wlan* wlan,
msg = nl80211_wlan_msg(wlan, 0, NL80211_CMD_SET_KEY);
if (!msg ||
nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx) ||
nla_put_flag(msg, NL80211_ATTR_KEY_DEFAULT))
nla_put_flag(msg, (alg == IEEE80211_CIPHER_SUITE_AES_CMAC ||
alg == IEEE80211_CIPHER_SUITE_BIP_GMAC_128 ||
alg == IEEE80211_CIPHER_SUITE_BIP_GMAC_256 ||
alg == IEEE80211_CIPHER_SUITE_BIP_CMAC_256) ?
NL80211_ATTR_KEY_DEFAULT_MGMT :
NL80211_ATTR_KEY_DEFAULT))
goto fail;
types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
@ -1768,49 +1773,21 @@ static void phydevice_capability_supp_cmds(struct wifi_commands_capability *cmd_
static void phydevice_capability_cipher_suites(struct wifi_capability *capability,
struct nlattr *tb)
{
int count, i;
uint32_t *ciphers;
size_t size;
if (tb == NULL)
return;
/* */
count = nla_len(tb) / sizeof(uint32_t);
if (count == 0)
size = nla_len(tb);
if (size == 0 || (size % sizeof(uint32_t)) != 0)
return;
capability->ciphers = capwap_clone(nla_data(tb), size);
if (!capability->ciphers)
return;
capability->ciphers_count = size / sizeof(uint32_t);
capability->flags |= WIFI_CAPABILITY_CIPHERS;
ciphers = (uint32_t *)nla_data(tb);
for (i = 0; i < count; i++) {
struct wifi_cipher_capability *ciphercap = (struct wifi_cipher_capability *)
capwap_array_get_item_pointer(capability->ciphers, capability->ciphers->count);
switch (ciphers[i]) {
case 0x000fac01:
ciphercap->cipher = CIPHER_CAPABILITY_WEP40;
case 0x000fac05:
ciphercap->cipher = CIPHER_CAPABILITY_WEP104;
case 0x000fac02:
ciphercap->cipher = CIPHER_CAPABILITY_TKIP;
case 0x000fac04:
ciphercap->cipher = CIPHER_CAPABILITY_CCMP;
case 0x000fac06:
ciphercap->cipher = CIPHER_CAPABILITY_CMAC;
case 0x000fac08:
ciphercap->cipher = CIPHER_CAPABILITY_GCMP;
case 0x00147201:
ciphercap->cipher = CIPHER_CAPABILITY_WPI_SMS4;
default:
ciphercap->cipher = CIPHER_CAPABILITY_UNKNOWN;
}
}
}
static void phydevice_capability_freq(struct wifi_capability *capability,

View File

@ -172,5 +172,11 @@ int wtp_update_radio_in_use();
void wtp_create_radioadmstate_element(struct capwap_packet_txmng* txmngpacket);
void wtp_create_radioopsstate_element(struct capwap_packet_txmng* txmngpacket);
void wtp_create_80211_wtpradioinformation_element(struct capwap_packet_txmng* txmngpacket);
void wtp_create_80211_encryption_capability_elements(struct capwap_packet_txmng *txmngpacket);
struct wtp_radio;
void wtp_create_80211_encryption_capability_element(struct capwap_packet_txmng *txmngpacket,
struct wtp_radio *radio);
#endif /* __CAPWAP_WTP_HEADER__ */

View File

@ -28,6 +28,8 @@ static void cfg_binding_add_ieee80211(struct capwap_packet_txmng* txmngpacket)
CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION,
&radio->radioinformation);
wtp_create_80211_encryption_capability_element(txmngpacket, radio);
if (radio->radioid == radio->radioinformation.radioid)
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ANTENNA, &radio->antenna);

View File

@ -50,6 +50,7 @@ static void wtp_send_discovery_request()
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
wtp_create_80211_wtpradioinformation_element(txmngpacket);
wtp_create_80211_encryption_capability_elements(txmngpacket);
}
/* CAPWAP_ELEMENT_MTUDISCOVERY */ /* TODO */

View File

@ -45,8 +45,10 @@ void wtp_dfa_state_join_enter(void)
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPFRAMETUNNELMODE, &g_wtp.mactunnel);
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPMACTYPE, &g_wtp.mactype);
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211)
if (g_wtp.binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
wtp_create_80211_wtpradioinformation_element(txmngpacket);
wtp_create_80211_encryption_capability_elements(txmngpacket);
}
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ECNSUPPORT, &g_wtp.ecn);

View File

@ -63,3 +63,39 @@ void wtp_create_80211_wtpradioinformation_element(struct capwap_packet_txmng* tx
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, &element);
}
}
/* */
void wtp_create_80211_encryption_capability_element(struct capwap_packet_txmng *txmngpacket,
struct wtp_radio *radio)
{
struct capwap_vendor_travelping_80211_encryption_capability_element *element;
if (!radio->devicehandle->capability->ciphers ||
radio->devicehandle->capability->ciphers_count == 0)
return;
element = alloca(sizeof(struct capwap_vendor_travelping_80211_encryption_capability_element) +
32 * sizeof(uint32_t));
/* Set message element */
element->radioid = radio->radioid;
element->suites_count = radio->devicehandle->capability->ciphers_count;
memcpy(element->suites, radio->devicehandle->capability->ciphers,
radio->devicehandle->capability->ciphers_count * sizeof(uint32_t));
capwap_packet_txmng_add_message_element(txmngpacket,
CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_ENCRYPTION_CAPABILITY, element);
}
/* */
void wtp_create_80211_encryption_capability_elements(struct capwap_packet_txmng *txmngpacket)
{
int i;
struct wtp_radio* radio;
for (i = 0; i < g_wtp.radios->count; i++) {
radio = (struct wtp_radio*)capwap_array_get_item_pointer(g_wtp.radios, i);
wtp_create_80211_encryption_capability_element(txmngpacket, radio);
}
}

View File

@ -652,6 +652,47 @@ void wtp_radio_receive_data_packet(uint8_t radioid, unsigned short binding, cons
}
}
static struct capwap_array *wtp_radio_set_update_keys(struct capwap_parsed_packet *packet,
uint8_t radioid, uint8_t wlanid)
{
int i;
struct capwap_array *keys;
struct capwap_array *updatekeys = NULL;
ASSERT(packet != NULL);
keys = (struct capwap_array *)
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY);
log_printf(LOG_DEBUG, "Set Update Keys: %p", keys);
if (!keys)
return NULL;
log_printf(LOG_DEBUG, "Set Update Keys: #%ld", keys->count);
for (i = 0; i < keys->count; i++) {
struct capwap_vendor_travelping_80211_update_key_element *key =
*(struct capwap_vendor_travelping_80211_update_key_element **)
capwap_array_get_item_pointer(keys, i);
log_printf(LOG_DEBUG, "RadioId: %d .. %d, WlanId: %d .. %d",
key->radioid, radioid,
key->wlanid, wlanid);
if (key->radioid != radioid || key->wlanid != wlanid)
continue;
if (!updatekeys)
updatekeys = capwap_array_create(sizeof(void *), 0, 0);
if (!updatekeys) {
log_printf(LOG_DEBUG, "Update WLAN: Out of Memory");
return NULL;
}
*(void **)capwap_array_get_item_pointer(updatekeys, updatekeys->count) = key;
log_printf(LOG_DEBUG, "Set Update Keys: Update #%ld", updatekeys->count);
}
return updatekeys;
}
/* source http://stackoverflow.com/a/16994674 */
static uint16_t reverse(register uint16_t x)
{
@ -721,6 +762,7 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
params.key = addwlan->key;
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
params.updatekeys = wtp_radio_set_update_keys(packet, addwlan->radioid, addwlan->wlanid);
/* Start AP */
if (wifi_wlan_startap(wlan->wlanhandle, &params)) {
@ -788,6 +830,7 @@ uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet)
params.key = updatewlan->key;
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
params.updatekeys = wtp_radio_set_update_keys(packet, updatewlan->radioid, updatewlan->wlanid);
/* Update AP */
if (wifi_wlan_updateap(wlan->wlanhandle, &params)) {