diff --git a/src/common/capwap_element.c b/src/common/capwap_element.c index a946ee3..c3af749 100644 --- a/src/common/capwap_element.c +++ b/src/common/capwap_element.c @@ -93,7 +93,8 @@ 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) }; #undef element_ops diff --git a/src/common/capwap_element_vendor_travelping_80211_encryption_capability.c b/src/common/capwap_element_vendor_travelping_80211_encryption_capability.c new file mode 100644 index 0000000..6c71b40 --- /dev/null +++ b/src/common/capwap_element_vendor_travelping_80211_encryption_capability.c @@ -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 +}; diff --git a/src/common/capwap_element_vendor_travelping_80211_encryption_capability.h b/src/common/capwap_element_vendor_travelping_80211_encryption_capability.h new file mode 100644 index 0000000..45ba410 --- /dev/null +++ b/src/common/capwap_element_vendor_travelping_80211_encryption_capability.h @@ -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__ */ diff --git a/src/common/capwap_element_wtpdescriptor.c b/src/common/capwap_element_wtpdescriptor.c index 19a1cb5..ac451b2 100644 --- a/src/common/capwap_element_wtpdescriptor.c +++ b/src/common/capwap_element_wtpdescriptor.c @@ -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; diff --git a/src/common/capwap_vendor_travelping.h b/src/common/capwap_vendor_travelping.h index 85949fc..4540857 100644 --- a/src/common/capwap_vendor_travelping.h +++ b/src/common/capwap_vendor_travelping.h @@ -4,6 +4,7 @@ #define CAPWAP_VENDOR_TRAVELPING_ID 18681 #include "capwap_element_vendor_travelping_wtp_timestamp.h" +#include "capwap_element_vendor_travelping_80211_encryption_capability.h" /* draft-ietf-opsawg-capwap-extension-06 */ #include "capwap_element_80211n_radioconf.h" diff --git a/src/wtp/binding/ieee80211/wifi_drivers.c b/src/wtp/binding/ieee80211/wifi_drivers.c index 84217a8..87ee900 100644 --- a/src/wtp/binding/ieee80211/wifi_drivers.c +++ b/src/wtp/binding/ieee80211/wifi_drivers.c @@ -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); diff --git a/src/wtp/binding/ieee80211/wifi_drivers.h b/src/wtp/binding/ieee80211/wifi_drivers.h index 05ff4e4..861ab90 100644 --- a/src/wtp/binding/ieee80211/wifi_drivers.h +++ b/src/wtp/binding/ieee80211/wifi_drivers.h @@ -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 @@ -189,11 +180,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 +203,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; diff --git a/src/wtp/binding/ieee80211/wifi_nl80211.c b/src/wtp/binding/ieee80211/wifi_nl80211.c index bdef277..f453ca3 100644 --- a/src/wtp/binding/ieee80211/wifi_nl80211.c +++ b/src/wtp/binding/ieee80211/wifi_nl80211.c @@ -1768,49 +1768,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, diff --git a/src/wtp/wtp.h b/src/wtp/wtp.h index 03abd67..4020a1e 100644 --- a/src/wtp/wtp.h +++ b/src/wtp/wtp.h @@ -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__ */ diff --git a/src/wtp/wtp_dfa_configure.c b/src/wtp/wtp_dfa_configure.c index 029ba1d..3dc5051 100644 --- a/src/wtp/wtp_dfa_configure.c +++ b/src/wtp/wtp_dfa_configure.c @@ -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); diff --git a/src/wtp/wtp_dfa_discovery.c b/src/wtp/wtp_dfa_discovery.c index f254100..e69d9ca 100644 --- a/src/wtp/wtp_dfa_discovery.c +++ b/src/wtp/wtp_dfa_discovery.c @@ -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 */ diff --git a/src/wtp/wtp_dfa_join.c b/src/wtp/wtp_dfa_join.c index b2afbef..37a746f 100644 --- a/src/wtp/wtp_dfa_join.c +++ b/src/wtp/wtp_dfa_join.c @@ -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); diff --git a/src/wtp/wtp_element_helper.c b/src/wtp/wtp_element_helper.c index c4d42db..b8d7bd6 100644 --- a/src/wtp/wtp_element_helper.c +++ b/src/wtp/wtp_element_helper.c @@ -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); + } +}