Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
76cd5d7484 | |||
a488af66cf | |||
ac135e16c4 | |||
6f7c26d0af | |||
fdf256553c | |||
ecf7a24eac | |||
57bcb0e183 |
11
NEWS.md
11
NEWS.md
@ -3,6 +3,17 @@ SmartCAPWAP
|
||||
|
||||
CAPWAP WTP and AC implementation
|
||||
|
||||
Version 1.3.2 - 15 Aug 2016
|
||||
---------------------------
|
||||
|
||||
* support management frame protection
|
||||
|
||||
Version 1.3.1 - 11 Aug 2016
|
||||
---------------------------
|
||||
|
||||
* fix hw queue selection for 802.11 raw frame injection
|
||||
* initial Linux ftrace support
|
||||
|
||||
Version 1.3.0 - 08 Aug 2016
|
||||
---------------------------
|
||||
|
||||
|
24
README.md
24
README.md
@ -68,3 +68,27 @@ SmartCAPWAP:
|
||||
./configure --disable-ac
|
||||
make
|
||||
make install
|
||||
|
||||
### Debugging / Traceing
|
||||
|
||||
The smartcapwap kernel module defines a number of static ftrace events. For a detailed
|
||||
guide on how to use those, see: https://www.kernel.org/doc/Documentation/trace/ftrace.txt
|
||||
|
||||
A sample trace session might lock like this:
|
||||
|
||||
# echo 1 > /sys/kernel/debug/tracing/events/capwap/enable
|
||||
# echo 1 > /sys/kernel/debug/tracing/tracing_on
|
||||
# cat /sys/kernel/debug/tracing/trace_pipe
|
||||
<...>-890 [000] ...1 12030.725012: sc_capwap_create: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
<...>-890 [000] ...1 12030.725048: sc_capwap_sendkeepalive: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
<...>-890 [000] ...1 12030.725052: sc_capwap_createkeepalive: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
<...>-890 [000] ...1 12030.725053: sc_capwap_send: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
ksoftirqd/0-3 [000] ..s1 12030.727270: sc_capwap_parsingpacket: session:9e04b10c75b3c6537da18d38da5bc70d skb:ffff8802306c8900
|
||||
wtp-890 [001] ...1 12060.764008: sc_capwap_sendkeepalive: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
wtp-890 [001] ...1 12060.764530: sc_capwap_createkeepalive: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
wtp-890 [001] ...1 12060.764637: sc_capwap_send: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
<idle>-0 [000] ..s2 12060.787527: sc_capwap_parsingpacket: session:9e04b10c75b3c6537da18d38da5bc70d skb:ffff8800b8a85900
|
||||
wtp-890 [001] ...1 12082.953847: sc_capwap_resetsession: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
wtp-890 [001] ...1 12082.954005: sc_capwap_close: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
wtp-890 [001] ...1 12082.954130: sc_capwap_freesession: session:9e04b10c75b3c6537da18d38da5bc70d
|
||||
# echo 0 > /sys/kernel/debug/tracing/tracing_on
|
||||
|
@ -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)
|
||||
|
@ -1,4 +1,4 @@
|
||||
From c26411bf0d00a6ceed42e85d66812b591b7c4c83 Mon Sep 17 00:00:00 2001
|
||||
From 664ed7a49f0d9f879e22e7e3da904a2e5793c33d Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schultz <aschultz@tpip.net>
|
||||
Date: Thu, 4 Feb 2016 15:57:11 +0100
|
||||
Subject: [PATCH] support patch for smartcapwap
|
||||
@ -7,10 +7,10 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
||||
---
|
||||
include/net/mac80211.h | 25 ++++
|
||||
net/mac80211/ieee80211_i.h | 6 +
|
||||
net/mac80211/iface.c | 56 ++++++++
|
||||
net/mac80211/rx.c | 81 ++++++++++--
|
||||
net/mac80211/tx.c | 312 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 468 insertions(+), 12 deletions(-)
|
||||
net/mac80211/iface.c | 56 +++++++++
|
||||
net/mac80211/rx.c | 81 +++++++++++--
|
||||
net/mac80211/tx.c | 279 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 435 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
|
||||
index 760bc4d..6722da6 100644
|
||||
@ -334,10 +334,10 @@ index 82af407..29cc59b 100644
|
||||
rcu_read_unlock();
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index bdc224d..fd48ccf 100644
|
||||
index bdc224d..5da49f0 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -2939,6 +2939,144 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
@@ -2939,6 +2939,111 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
@ -353,8 +353,9 @@ index bdc224d..fd48ccf 100644
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ struct ieee80211_sub_if_data *tmp_sdata, *sdata;
|
||||
+ struct ieee80211_sub_if_data *sdata;
|
||||
+ struct cfg80211_chan_def *chandef;
|
||||
+ int tid;
|
||||
+ int hdrlen;
|
||||
+
|
||||
+ /* check for not even having the fixed 802.11 header */
|
||||
@ -367,13 +368,13 @@ index bdc224d..fd48ccf 100644
|
||||
+ if (unlikely(skb->len < hdrlen))
|
||||
+ goto fail; /* skb too short for claimed header length */
|
||||
+
|
||||
+ skb_reset_mac_header(skb);
|
||||
+ skb_set_mac_header(skb, 0);
|
||||
+ /*
|
||||
+ * these are just fixed to the end of the rt area since we
|
||||
+ * don't have any better information and at this point, nobody cares
|
||||
+ */
|
||||
+ skb_reset_network_header(skb);
|
||||
+ skb_reset_transport_header(skb);
|
||||
+ skb_set_network_header(skb, hdrlen);
|
||||
+ skb_set_transport_header(skb, hdrlen);
|
||||
+
|
||||
+ /*
|
||||
+ * Initialize skb->protocol if the injected frame is a data frame
|
||||
@ -393,13 +394,12 @@ index bdc224d..fd48ccf 100644
|
||||
+
|
||||
+ skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
+ }
|
||||
+ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
|
||||
+
|
||||
+ memset(info, 0, sizeof(*info));
|
||||
+
|
||||
+ info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
|
||||
+ IEEE80211_TX_CTL_INJECTED;
|
||||
+
|
||||
+
|
||||
+ /*
|
||||
+ * we might have set these flags later.....
|
||||
+ * info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
||||
@ -411,46 +411,17 @@ index bdc224d..fd48ccf 100644
|
||||
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
+ if (!chanctx_conf) {
|
||||
+ tmp_sdata = rcu_dereference(local->monitor_sdata);
|
||||
+ if (tmp_sdata)
|
||||
+ chanctx_conf =
|
||||
+ rcu_dereference(tmp_sdata->vif.chanctx_conf);
|
||||
+ }
|
||||
+
|
||||
+ if (chanctx_conf)
|
||||
+ chandef = &chanctx_conf->def;
|
||||
+ else if (!local->use_chanctx)
|
||||
+ chandef = &local->_oper_chandef;
|
||||
+ else
|
||||
+ if (!chanctx_conf)
|
||||
+ goto fail_rcu;
|
||||
+
|
||||
+ /*
|
||||
+ * Frame injection is not allowed if beaconing is not allowed
|
||||
+ * or if we need radar detection. Beaconing is usually not allowed when
|
||||
+ * the mode or operation (Adhoc, AP, Mesh) does not support DFS.
|
||||
+ * Passive scan is also used in world regulatory domains where
|
||||
+ * your country is not known and as such it should be treated as
|
||||
+ * NO TX unless the channel is explicitly allowed in which case
|
||||
+ * your current regulatory domain would not have the passive scan
|
||||
+ * flag.
|
||||
+ *
|
||||
+ * Since AP mode uses monitor interfaces to inject/TX management
|
||||
+ * frames we can make AP mode the exception to this rule once it
|
||||
+ * supports radar detection as its implementation can deal with
|
||||
+ * radar detection by itself. We can do that later by adding a
|
||||
+ * monitor flag interfaces used for AP support.
|
||||
+ */
|
||||
+ if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
|
||||
+ sdata->vif.type))
|
||||
+ goto fail_rcu;
|
||||
+ info->band = chanctx_conf->def.chan->band;
|
||||
+
|
||||
+ ieee80211_tx_stats(dev, skb->len);
|
||||
+
|
||||
+ info->band = chandef->chan->band;
|
||||
+ ieee80211_xmit(sdata, NULL, skb);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return;
|
||||
+
|
||||
+fail_rcu:
|
||||
+ rcu_read_unlock();
|
||||
+fail:
|
||||
@ -467,10 +438,6 @@ index bdc224d..fd48ccf 100644
|
||||
+netdev_tx_t ieee80211_capwap_subif_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ if (skb->protocol != htons(ETH_P_IP))
|
||||
+ printk(KERN_DEBUG "capwap xmit %s: protocol: %04X, data: %p, MAC: %p\n",
|
||||
+ dev->name, ntohs(skb->protocol), skb->data, skb_mac_header(skb));
|
||||
+
|
||||
+ if (skb->protocol == htons(ETH_P_CONTROL)) {
|
||||
+ __ieee80211_capwap_inject_start_xmit(skb, dev);
|
||||
+ } else
|
||||
@ -482,7 +449,7 @@ index bdc224d..fd48ccf 100644
|
||||
struct sk_buff *
|
||||
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u32 info_flags)
|
||||
@@ -3914,3 +4052,177 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
||||
@@ -3914,3 +4019,177 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_xmit(sdata, NULL, skb);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
};
|
@ -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__ */
|
108
src/common/capwap_element_vendor_travelping_80211_update_key.c
Normal file
108
src/common/capwap_element_vendor_travelping_80211_update_key.c
Normal 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
|
||||
};
|
@ -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__ */
|
@ -35,7 +35,9 @@ 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;
|
||||
|
||||
@ -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,7 +84,8 @@ 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;
|
||||
@ -86,27 +94,36 @@ static void* capwap_wtpdescriptor_element_clone(void* data) {
|
||||
|
||||
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) {
|
||||
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;
|
||||
|
||||
@ -116,12 +133,13 @@ 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);
|
||||
capwap_array_free(element->descsubelement);
|
||||
@ -129,7 +147,9 @@ 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;
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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,17 +2202,18 @@ 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;
|
||||
}
|
||||
|
||||
#define broadcast_ether_addr (const uint8_t *) "\xff\xff\xff\xff\xff\xff"
|
||||
update_keys(wlan, params->updatekeys);
|
||||
|
||||
wlan->device->wlanactive++;
|
||||
log_printf(LOG_INFO, "Configured interface: %s, SSID: '%s'", wlan->virtname, wlan->ssid);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -5,3 +5,5 @@ smartcapwap-y := \
|
||||
netlinkapp.o \
|
||||
capwap.o \
|
||||
capwap_private.o
|
||||
|
||||
CFLAGS_capwap.o = -I$(src)
|
||||
|
486
src/wtp/kmod/capwap-trace.h
Normal file
486
src/wtp/kmod/capwap-trace.h
Normal file
@ -0,0 +1,486 @@
|
||||
#if !defined(__CAPWAP_DRIVER_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define __CAPWAP_DRIVER_TRACE_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "capwap.h"
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM capwap
|
||||
|
||||
#define SESSION_ENTRY __array(char, sessionid, 16)
|
||||
#define SESSION_ASSIGN ((session) ? memcpy(__entry->sessionid, &session->sessionid, 16) : memset(__entry->sessionid, 0, 16))
|
||||
#define SESSION_PR_FMT " session:%16phN"
|
||||
#define SESSION_PR_ARG __entry->sessionid
|
||||
|
||||
#define SESSIONID_ENTRY __array(char, sessionid, 16)
|
||||
#define SESSIONID_ASSIGN ((sessionid) ? memcpy(__entry->sessionid, sessionid, 16) : memset(__entry->sessionid, 0, 16))
|
||||
#define SESSIONID_PR_FMT " session:%16phN"
|
||||
#define SESSIONID_PR_ARG __entry->sessionid
|
||||
|
||||
#define SKB_ENTRY __field(struct sk_buff *, skb)
|
||||
#define SKB_ASSIGN __entry->skb = skb
|
||||
#define SKB_PR_FMT " skb:%p"
|
||||
#define SKB_PR_ARG __entry->skb
|
||||
|
||||
#define FRAGMENT_ENTRY __field(struct sc_capwap_fragment *, fragment)
|
||||
#define FRAGMENT_ASSIGN __entry->fragment = fragment
|
||||
#define FRAGMENT_PR_FMT " frag:%p"
|
||||
#define FRAGMENT_PR_ARG __entry->fragment
|
||||
|
||||
#define BSSID_ENTRY __array(char, bssid, ETH_ALEN)
|
||||
#define BSSID_ASSIGN (bssid ? memcpy(__entry->bssid, bssid, ETH_ALEN) : memset(__entry->bssid, 0, ETH_ALEN))
|
||||
#define BSSID_PR_FMT " BSS:%pM"
|
||||
#define BSSID_PR_ARG __entry->bssid
|
||||
|
||||
/* capwap.c */
|
||||
|
||||
TRACE_EVENT(sc_capwap_fragment_free,
|
||||
TP_PROTO(struct sc_capwap_fragment *fragment),
|
||||
|
||||
TP_ARGS(fragment),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
FRAGMENT_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
FRAGMENT_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(FRAGMENT_PR_FMT, FRAGMENT_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_freesession,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_defrag_evictor,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_defrag_evictor_fragment_expired,
|
||||
TP_PROTO(struct sc_capwap_session *session,
|
||||
struct sc_capwap_fragment *fragment,
|
||||
ktime_t now),
|
||||
|
||||
TP_ARGS(session,
|
||||
fragment,
|
||||
now),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
FRAGMENT_ENTRY
|
||||
__field(u64, now)
|
||||
__field(u64, tstamp)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
FRAGMENT_ASSIGN;
|
||||
__entry->now = now.tv64;
|
||||
__entry->tstamp = fragment->tstamp.tv64;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT FRAGMENT_PR_FMT " (%llu %llu)",
|
||||
SESSION_PR_ARG, FRAGMENT_PR_ARG,
|
||||
__entry->now,
|
||||
__entry->tstamp
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_reasm,
|
||||
TP_PROTO(struct sc_capwap_fragment *fragment),
|
||||
|
||||
TP_ARGS(fragment),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
FRAGMENT_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
FRAGMENT_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(FRAGMENT_PR_FMT, FRAGMENT_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_defrag,
|
||||
TP_PROTO(struct sc_capwap_session *session,
|
||||
uint16_t id,
|
||||
uint16_t offset,
|
||||
uint16_t length),
|
||||
|
||||
TP_ARGS(session, id, offset, length),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
__field(u16, id)
|
||||
__field(u16, offset)
|
||||
__field(u16, length)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
__entry->id = id;
|
||||
__entry->offset = offset;
|
||||
__entry->length = length;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
SESSION_PR_FMT " fragment id:%hu offset:%hu length:%hu",
|
||||
SESSION_PR_ARG, __entry->id, __entry->offset, __entry->length
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// TRACEKMOD("** *Fragment info: id %hu offset %hu length %hu\n", frag_id, cb->frag_offset, cb->frag_length);
|
||||
|
||||
TRACE_EVENT(sc_capwap_8023_to_80211,
|
||||
TP_PROTO(struct sk_buff *skb, const uint8_t *bssid),
|
||||
|
||||
TP_ARGS(skb, bssid),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SKB_ENTRY
|
||||
BSSID_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SKB_ASSIGN;
|
||||
BSSID_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
SKB_PR_FMT BSSID_PR_FMT,
|
||||
SKB_PR_ARG, BSSID_PR_ARG
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_80211_to_8023,
|
||||
TP_PROTO(struct sk_buff *skb),
|
||||
|
||||
TP_ARGS(skb),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SKB_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SKB_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SKB_PR_FMT, SKB_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_create,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_close,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_newfragmentid,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_createkeepalive,
|
||||
TP_PROTO(struct sc_capwap_sessionid_element *sessionid),
|
||||
|
||||
TP_ARGS(sessionid),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSIONID_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSIONID_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSIONID_PR_FMT, SESSIONID_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_parsingpacket,
|
||||
TP_PROTO(struct sc_capwap_session *session,
|
||||
struct sk_buff *skb),
|
||||
|
||||
TP_ARGS(session, skb),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
SKB_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
SKB_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
SESSION_PR_FMT SKB_PR_FMT,
|
||||
SESSION_PR_ARG, SKB_PR_ARG
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_forwarddata,
|
||||
TP_PROTO(struct sc_capwap_session *session,
|
||||
uint8_t radioid,
|
||||
uint8_t binding,
|
||||
struct sk_buff *skb,
|
||||
uint32_t flags,
|
||||
struct sc_capwap_radio_addr *radioaddr,
|
||||
int radioaddrlength,
|
||||
struct sc_capwap_wireless_information *winfo),
|
||||
|
||||
TP_ARGS(session, radioid, binding, skb, flags, radioaddr, radioaddrlength, winfo),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
__field(u8, radioid)
|
||||
__field(u8, binding)
|
||||
SKB_ENTRY
|
||||
__field(u32, flags)
|
||||
__field(int, radioaddrlength)
|
||||
__array(char, radioaddr, 8)
|
||||
__field(u8, rssi)
|
||||
__field(u8, snr)
|
||||
__field(u16, rate)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
__entry->radioid = radioid;
|
||||
__entry->binding = binding;
|
||||
SKB_ASSIGN;
|
||||
__entry->binding = flags;
|
||||
__entry->radioaddrlength = radioaddrlength;
|
||||
((radioaddrlength != 0 && radioaddr) ? memcpy(__entry->radioaddr, radioaddr, min(radioaddrlength, 8)) : memset(__entry->radioaddr, 0, 8));
|
||||
|
||||
__entry->rssi = (winfo) ? ((struct sc_capwap_ieee80211_frame_info *)(winfo))->rssi : 0;
|
||||
__entry->snr = (winfo) ? ((struct sc_capwap_ieee80211_frame_info *)(winfo))->snr : 0;
|
||||
__entry->rate = (winfo) ? ((struct sc_capwap_ieee80211_frame_info *)(winfo))->rate : 0;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
SESSION_PR_FMT " radio:%d binding:%d" SKB_PR_FMT
|
||||
"radioaddr:%*phC rssid:%d snr:%d rate:%d",
|
||||
SESSION_PR_ARG, __entry->radioid, __entry->binding, SKB_PR_ARG,
|
||||
min(__entry->radioaddrlength, 8), __entry->radioaddr,
|
||||
__entry->rssi, __entry->snr, __entry->rate
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_setradiomacaddress,
|
||||
TP_PROTO(uint8_t *bssid),
|
||||
|
||||
TP_ARGS(bssid),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
BSSID_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
BSSID_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(BSSID_PR_FMT, BSSID_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_setwinfo_frameinfo,
|
||||
TP_PROTO(uint8_t rssi,
|
||||
uint8_t snr,
|
||||
uint16_t rate),
|
||||
|
||||
TP_ARGS(rssi, snr, rate),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u8, rssi)
|
||||
__field(u8, snr)
|
||||
__field(u16, rate)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->rssi = rssi;
|
||||
__entry->snr = snr;
|
||||
__entry->rate = rate;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
" rssid:%d snr:%d rate:%d",
|
||||
__entry->rssi, __entry->snr, __entry->rate
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_setwinfo_destwlans,
|
||||
TP_PROTO(uint16_t wlanidbitmap),
|
||||
|
||||
TP_ARGS(wlanidbitmap),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u16, wlanidbitmap)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->wlanidbitmap = wlanidbitmap;
|
||||
),
|
||||
|
||||
TP_printk(" id:%04x", __entry->wlanidbitmap)
|
||||
);
|
||||
|
||||
/* capwap_private.c */
|
||||
|
||||
TRACE_EVENT(sc_capwap_resetsession,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_sendkeepalive,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_send,
|
||||
TP_PROTO(struct sc_capwap_session *session),
|
||||
|
||||
TP_ARGS(session),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(SESSION_PR_FMT, SESSION_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_send_80211,
|
||||
TP_PROTO(struct sk_buff *skb, struct net_device *dev),
|
||||
|
||||
TP_ARGS(skb, dev),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SKB_ENTRY
|
||||
__array(char, dev_name, 32)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SKB_ASSIGN;
|
||||
strlcpy(__entry->dev_name, dev->name, 32);
|
||||
),
|
||||
|
||||
TP_printk(" %s" SKB_PR_FMT, __entry->dev_name, SKB_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(sc_capwap_parsingdatapacket,
|
||||
TP_PROTO(struct sc_capwap_session *session,
|
||||
struct sk_buff *skb),
|
||||
|
||||
TP_ARGS(session, skb),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
SESSION_ENTRY
|
||||
SKB_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
SESSION_ASSIGN;
|
||||
SKB_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
SESSION_PR_FMT SKB_PR_FMT,
|
||||
SESSION_PR_ARG, SKB_PR_ARG
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* !__CAPWAP_DRIVER_TRACE_H || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE capwap-trace
|
||||
#include <trace/define_trace.h>
|
@ -10,6 +10,9 @@
|
||||
#include "nlsmartcapwap.h"
|
||||
#include "netlinkapp.h"
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "capwap-trace.h"
|
||||
|
||||
/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
|
||||
static const unsigned char sc_rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
|
||||
|
||||
@ -19,7 +22,7 @@ static const unsigned char sc_bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00,
|
||||
/* */
|
||||
static void sc_capwap_fragment_free(struct sc_capwap_fragment* fragment)
|
||||
{
|
||||
TRACEKMOD("### sc_capwap_fragment_free\n");
|
||||
trace_sc_capwap_fragment_free(fragment);
|
||||
|
||||
/* */
|
||||
list_del(&fragment->lru_list);
|
||||
@ -42,7 +45,7 @@ static void sc_capwap_freesession(struct sc_capwap_session* session)
|
||||
struct sc_capwap_fragment* fragment;
|
||||
struct sc_station *sta;
|
||||
|
||||
TRACEKMOD("### sc_capwap_freesession\n");
|
||||
trace_sc_capwap_freesession(session);
|
||||
|
||||
/* Free socket buffers */
|
||||
list_for_each_entry_safe(fragment, temp, &session->fragments.lru_list, lru_list) {
|
||||
@ -63,7 +66,7 @@ static void sc_capwap_defrag_evictor(struct sc_capwap_session* session, ktime_t
|
||||
struct sc_capwap_fragment* fragment;
|
||||
struct list_head* list = &session->fragments.lru_list;
|
||||
|
||||
TRACEKMOD("### sc_capwap_defrag_evictor\n");
|
||||
trace_sc_capwap_defrag_evictor(session);
|
||||
|
||||
/* Light check without lock */
|
||||
if (!list_empty(list)) {
|
||||
@ -74,7 +77,7 @@ static void sc_capwap_defrag_evictor(struct sc_capwap_session* session, ktime_t
|
||||
fragment = list_first_entry(list, struct sc_capwap_fragment, lru_list);
|
||||
delta = ktime_sub(now, fragment->tstamp);
|
||||
if ((delta.tv64 < -NSEC_PER_SEC) || (delta.tv64 > NSEC_PER_SEC)) {
|
||||
TRACEKMOD("*** Expired fragment %hu (%llu %llu)\n", fragment->fragmentid, now.tv64, fragment->tstamp.tv64);
|
||||
trace_sc_capwap_defrag_evictor_fragment_expired(session, fragment, now);
|
||||
sc_capwap_fragment_free(fragment);
|
||||
}
|
||||
}
|
||||
@ -91,7 +94,7 @@ static struct sk_buff* sc_capwap_reasm(struct sc_capwap_fragment* fragment) {
|
||||
struct sk_buff* skbfrag;
|
||||
struct sc_capwap_header* header;
|
||||
|
||||
TRACEKMOD("### sc_capwap_reasm\n");
|
||||
trace_sc_capwap_reasm(fragment);
|
||||
|
||||
/* */
|
||||
skbfrag = fragment->fragments;
|
||||
@ -140,8 +143,6 @@ static struct sk_buff* sc_capwap_defrag(struct sc_capwap_session* session, struc
|
||||
struct sk_buff* skb_defrag = NULL;
|
||||
struct sc_capwap_header* header = (struct sc_capwap_header*)skb->data;
|
||||
|
||||
TRACEKMOD("### sc_capwap_defrag\n");
|
||||
|
||||
/* */
|
||||
headersize = GET_HLEN_HEADER(header) * 4;
|
||||
if (skb->len < headersize) {
|
||||
@ -157,9 +158,10 @@ static struct sk_buff* sc_capwap_defrag(struct sc_capwap_session* session, struc
|
||||
cb->frag_offset = be16_to_cpu(header->frag_off);
|
||||
cb->frag_length = skb->len - headersize;
|
||||
|
||||
trace_sc_capwap_defrag(session, frag_id, cb->frag_offset, cb->frag_length);
|
||||
|
||||
/* */
|
||||
spin_lock(&session->fragments.lock);
|
||||
TRACEKMOD("*** Fragment info: id %hu offset %hu length %hu\n", frag_id, cb->frag_offset, cb->frag_length);
|
||||
|
||||
/* Get fragment */
|
||||
fragment = &session->fragments.queues[frag_id % CAPWAP_FRAGMENT_QUEUE];
|
||||
@ -266,8 +268,6 @@ error:
|
||||
static unsigned int sc_capwap_80211_hdrlen(__le16 fc) {
|
||||
unsigned int hdrlen = 24;
|
||||
|
||||
TRACEKMOD("### sc_capwap_80211_hdrlen\n");
|
||||
|
||||
if (ieee80211_is_data(fc)) {
|
||||
if (ieee80211_has_a4(fc)) {
|
||||
hdrlen = 30;
|
||||
@ -301,7 +301,7 @@ int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid) {
|
||||
struct ethhdr* eh = (struct ethhdr*)skb->data;
|
||||
uint16_t ethertype = ntohs(eh->h_proto);
|
||||
|
||||
TRACEKMOD("### sc_capwap_8023_to_80211\n");
|
||||
trace_sc_capwap_8023_to_80211(skb, bssid);
|
||||
|
||||
/* IEEE 802.11 header */
|
||||
hdrlen = 24;
|
||||
@ -367,7 +367,7 @@ int sc_capwap_80211_to_8023(struct sk_buff* skb) {
|
||||
uint8_t dst[ETH_ALEN];
|
||||
uint8_t src[ETH_ALEN] __aligned(2);
|
||||
|
||||
TRACEKMOD("### sc_capwap_80211_to_8023\n");
|
||||
trace_sc_capwap_80211_to_8023(skb);
|
||||
|
||||
/* */
|
||||
hdrlen = sc_capwap_80211_hdrlen(hdr->frame_control);
|
||||
@ -411,7 +411,7 @@ int sc_capwap_create(struct sc_capwap_session *session)
|
||||
.encap_rcv = sc_capwap_recvpacket
|
||||
};
|
||||
|
||||
TRACEKMOD("### sc_capwap_bind\n");
|
||||
trace_sc_capwap_create(session);
|
||||
|
||||
if (session->socket)
|
||||
return -EBUSY;
|
||||
@ -441,7 +441,7 @@ error:
|
||||
|
||||
void sc_capwap_close(struct sc_capwap_session *session)
|
||||
{
|
||||
TRACEKMOD("### sc_capwap_close\n");
|
||||
trace_sc_capwap_close(session);
|
||||
|
||||
if (session->socket)
|
||||
udp_tunnel_sock_release(session->socket);
|
||||
@ -453,7 +453,7 @@ void sc_capwap_close(struct sc_capwap_session *session)
|
||||
/* */
|
||||
static uint16_t sc_capwap_newfragmentid(struct sc_capwap_session* session)
|
||||
{
|
||||
TRACEKMOD("### sc_capwap_newfragmentid\n");
|
||||
trace_sc_capwap_newfragmentid(session);
|
||||
|
||||
return atomic_inc_return(&session->fragmentid) & 0xFFFF;
|
||||
}
|
||||
@ -465,7 +465,7 @@ int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uin
|
||||
struct sc_capwap_data_message* dataheader;
|
||||
struct sc_capwap_message_element* msgelement;
|
||||
|
||||
TRACEKMOD("### sc_capwap_createkeepalive\n");
|
||||
trace_sc_capwap_createkeepalive(sessionid);
|
||||
|
||||
/* */
|
||||
if (size < CAPWAP_KEEP_ALIVE_MAX_SIZE) {
|
||||
@ -515,7 +515,7 @@ int sc_capwap_parsingpacket(struct sc_capwap_session* session,
|
||||
struct sc_capwap_message_element* message;
|
||||
struct sc_capwap_header* header = (struct sc_capwap_header*)skb->data;
|
||||
|
||||
TRACEKMOD("### sc_capwap_parsingpacket\n");
|
||||
trace_sc_capwap_parsingpacket(session, skb);
|
||||
|
||||
/* Linearize socket buffer */
|
||||
if (skb_linearize(skb)) {
|
||||
@ -659,7 +659,7 @@ int sc_capwap_forwarddata(struct sc_capwap_session* session,
|
||||
struct sk_buff* clone = NULL;
|
||||
int packetlength = skb->len;
|
||||
|
||||
TRACEKMOD("### sc_capwap_forwarddata\n");
|
||||
trace_sc_capwap_forwarddata(session, radioid, binding, skb, flags, radioaddr, radioaddrlength, winfo);
|
||||
|
||||
/* Check headroom */
|
||||
headroom = skb_headroom(skb);
|
||||
@ -754,25 +754,12 @@ int sc_capwap_forwarddata(struct sc_capwap_session* session,
|
||||
return (!packetlength ? 0 : -EIO);
|
||||
}
|
||||
|
||||
/* */
|
||||
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string) {
|
||||
int i;
|
||||
char* pos = string;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
snprintf(pos, 3, "%02x", sessionid->id[i]);
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
*pos = 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
struct sc_capwap_radio_addr* sc_capwap_setradiomacaddress(uint8_t* buffer, int size, uint8_t* bssid) {
|
||||
struct sc_capwap_radio_addr* radioaddr;
|
||||
struct sc_capwap_macaddress_eui48* addr;
|
||||
|
||||
TRACEKMOD("### sc_capwap_setwirelessinformation\n");
|
||||
trace_sc_capwap_setradiomacaddress(bssid);
|
||||
|
||||
memset(buffer, 0, size);
|
||||
|
||||
@ -790,7 +777,7 @@ struct sc_capwap_wireless_information* sc_capwap_setwinfo_frameinfo(uint8_t* buf
|
||||
struct sc_capwap_wireless_information* winfo;
|
||||
struct sc_capwap_ieee80211_frame_info* frameinfo;
|
||||
|
||||
TRACEKMOD("### sc_capwap_setwinfo_frameinfo\n");
|
||||
trace_sc_capwap_setwinfo_frameinfo(rssi, snr, rate);
|
||||
|
||||
memset(buffer, 0, size);
|
||||
|
||||
@ -810,7 +797,7 @@ struct sc_capwap_wireless_information* sc_capwap_setwinfo_destwlans(uint8_t* buf
|
||||
struct sc_capwap_wireless_information* winfo;
|
||||
struct sc_capwap_destination_wlans* destwlans;
|
||||
|
||||
TRACEKMOD("### sc_capwap_setwinfo_destwlans\n");
|
||||
trace_sc_capwap_setwinfo_destwlans(wlanidbitmap);
|
||||
|
||||
memset(buffer, 0, size);
|
||||
|
||||
|
@ -139,8 +139,6 @@ void sc_capwap_close(struct sc_capwap_session *session);
|
||||
int sc_capwap_8023_to_80211(struct sk_buff* skb, const uint8_t* bssid);
|
||||
int sc_capwap_80211_to_8023(struct sk_buff* skb);
|
||||
|
||||
void sc_capwap_sessionid_printf(const struct sc_capwap_sessionid_element* sessionid, char* string);
|
||||
|
||||
int sc_capwap_createkeepalive(struct sc_capwap_sessionid_element* sessionid, uint8_t* buffer, int size);
|
||||
int sc_capwap_parsingpacket(struct sc_capwap_session* session, struct sk_buff* skb);
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "capwap.h"
|
||||
#include "nlsmartcapwap.h"
|
||||
#include "netlinkapp.h"
|
||||
#include "capwap-trace.h"
|
||||
|
||||
/* */
|
||||
int sc_capwap_init(struct sc_capwap_session *session, struct net *net)
|
||||
@ -42,7 +43,7 @@ int sc_capwap_init(struct sc_capwap_session *session, struct net *net)
|
||||
/* */
|
||||
void sc_capwap_resetsession(struct sc_capwap_session *session)
|
||||
{
|
||||
TRACEKMOD("### sc_capwap_resetsession\n");
|
||||
trace_sc_capwap_resetsession(session);
|
||||
|
||||
sc_capwap_close(session);
|
||||
sc_capwap_init(session, session->net);
|
||||
@ -55,7 +56,7 @@ int sc_capwap_sendkeepalive(struct sc_capwap_session *session)
|
||||
int length;
|
||||
uint8_t buffer[CAPWAP_KEEP_ALIVE_MAX_SIZE];
|
||||
|
||||
TRACEKMOD("### sc_capwap_sendkeepalive\n");
|
||||
trace_sc_capwap_sendkeepalive(session);
|
||||
|
||||
/* Build keepalive */
|
||||
length = sc_capwap_createkeepalive(&session->sessionid, buffer, CAPWAP_KEEP_ALIVE_MAX_SIZE);
|
||||
@ -80,7 +81,7 @@ int sc_capwap_send(struct sc_capwap_session *session, uint8_t* buffer, int lengt
|
||||
.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL,
|
||||
};
|
||||
|
||||
TRACEKMOD("### sc_capwap_send\n");
|
||||
trace_sc_capwap_send(session);
|
||||
|
||||
return kernel_sendmsg(session->socket, &msg, &vec, 1, vec.iov_len);
|
||||
}
|
||||
@ -170,8 +171,7 @@ static void sc_send_80211(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
printk(KERN_DEBUG "capwap inject: %s: hdr: %p\n",
|
||||
dev->name, skb->data);
|
||||
trace_sc_send_80211(skb, dev);
|
||||
|
||||
/* detach skb from CAPWAP */
|
||||
skb_orphan(skb);
|
||||
@ -213,7 +213,7 @@ void sc_capwap_parsingdatapacket(struct sc_capwap_session* session, struct sk_bu
|
||||
struct sc_capwap_destination_wlans* destwlan = NULL;
|
||||
int winfosize = 0;
|
||||
|
||||
TRACEKMOD("### sc_capwap_parsingdatapacket\n");
|
||||
trace_sc_capwap_parsingdatapacket(session, skb);
|
||||
|
||||
/* Retrieve optional attribute */
|
||||
pos = skb->data + sizeof(struct sc_capwap_header);
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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, ¶ms)) {
|
||||
@ -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, ¶ms)) {
|
||||
|
Reference in New Issue
Block a user