Compare commits
30 Commits
v1.2.0-rc1
...
v1.3.1
Author | SHA1 | Date | |
---|---|---|---|
6f7c26d0af | |||
fdf256553c | |||
ecf7a24eac | |||
57bcb0e183 | |||
9fbf441896 | |||
01919fffd9 | |||
02e8d534b5 | |||
3626927722 | |||
2ac3944e7a | |||
a131e17a6e | |||
0e19b53e28 | |||
9ded0bb87b | |||
b0aaaa4436 | |||
6024cc15cf | |||
d51873dd4b | |||
480f5d8782 | |||
651ccc0d33 | |||
baf1ccbc73 | |||
4f3fe0c339 | |||
813f24b8ac | |||
bca5c91ae1 | |||
619c40d5be | |||
7b4e386057 | |||
5195ea9e37 | |||
8f03ecca9b | |||
4b1caad54b | |||
c19da7ffb8 | |||
9096bff7a5 | |||
c132036914 | |||
f3fb11ac81 |
30
NEWS.md
Normal file
30
NEWS.md
Normal file
@ -0,0 +1,30 @@
|
||||
SmartCAPWAP
|
||||
===========
|
||||
|
||||
CAPWAP WTP and AC implementation
|
||||
|
||||
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
|
||||
---------------------------
|
||||
|
||||
* forward PAE (IEEE 802.1X Authentication) frames as raw 802.11 frames to AC
|
||||
* implement encryption support for group and peer temporal keys (CCMP only)
|
||||
|
||||
Version 1.2.1 - 06 May 2016
|
||||
---------------------------
|
||||
|
||||
* fix Add WLAN's capability field
|
||||
* fix mssing IEEE 802.11 Assigned WTP BSSID IE in Add WLAN response
|
||||
|
||||
Version 1.2.0 - 29 Apr 2016
|
||||
---------------------------
|
||||
|
||||
* 802.11n support
|
||||
* WMM/WME support
|
||||
* ported to libev
|
||||
* ported to Linux 4.4
|
37
README.md
37
README.md
@ -12,18 +12,23 @@ NOTE: The WTP has been ported to libev, the AC has not been adjusted and is ther
|
||||
|
||||
* 802.11b
|
||||
* 802.11g
|
||||
* 802.11a
|
||||
* WMM/WME (mostly)
|
||||
* Local MAC
|
||||
* single radio, single WLAN mode
|
||||
* 802.11n ([draft-ietf-opsawg-capwap-extension-06](https://tools.ietf.org/html/draft-ietf-opsawg-capwap-extension-06))
|
||||
* WPA2-PSK
|
||||
|
||||
Only cards with cfg80211 netlink API are supported and only
|
||||
ath9k cards (in particular Qualcomm Atheros AR5418) have
|
||||
been tested.
|
||||
Only cards with cfg80211 netlink API are supported. The following devices
|
||||
have been tested:
|
||||
|
||||
* Atheros AR9280 (Compex WLE200NX)
|
||||
* Mediatek MT7602E, MT7612E (ZBT WG2626, ALL-WR1200AC_WRT)
|
||||
|
||||
### Planned WTP features:
|
||||
|
||||
* encryption (WPA2)
|
||||
* WPA2 Enterprise
|
||||
* 802.11r - BSS fast transition
|
||||
* Hybrid-MAC ([RFC-7494](https://tools.ietf.org/html/rfc7494))
|
||||
|
||||
## INSTALLATION
|
||||
@ -63,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
|
||||
|
@ -102,7 +102,8 @@ capwap_SOURCES = $(top_srcdir)/src/common/capwap.c \
|
||||
$(top_srcdir)/src/common/capwap_element_80211_wtpradiofailalarm.c \
|
||||
$(top_srcdir)/src/common/capwap_element_80211_wtpradioinformation.c \
|
||||
$(top_srcdir)/src/common/capwap_element_80211n_radioconf.c \
|
||||
$(top_srcdir)/src/common/capwap_element_80211n_station_information.c
|
||||
$(top_srcdir)/src/common/capwap_element_80211n_station_information.c \
|
||||
$(top_srcdir)/src/common/capwap_element_vendor_travelping_wtp_timestamp.c
|
||||
|
||||
if DEBUG_BUILD
|
||||
capwap_SOURCES += $(top_srcdir)/src/common/capwap_debug.c
|
||||
|
@ -49,6 +49,7 @@ application: {
|
||||
|
||||
timer: {
|
||||
statistics = 120;
|
||||
inactivity = 300;
|
||||
};
|
||||
|
||||
dtls: {
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
AC_PREREQ(2.63)
|
||||
|
||||
AC_INIT([SmartCAPWAP], [1.2], [https://github.com/travelping/smartcapwap], [smartcapwap])
|
||||
AC_INIT([SmartCAPWAP], [1.2.1], [https://github.com/travelping/smartcapwap], [smartcapwap])
|
||||
AC_CONFIG_AUX_DIR([build])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([1.11 -Wall])
|
||||
|
@ -9,10 +9,21 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=smartcapwap
|
||||
PKG_VERSION:=1.0
|
||||
PKG_VERSION:=1.2.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
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:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_MAINTAINER:=Travelping GmbH <info@travelping.com>
|
||||
|
||||
PKG_LICENSE:=GPL-v2
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
|
||||
@ -29,18 +40,25 @@ define Package/smartcapwap
|
||||
CATEGORY:=Network
|
||||
TITLE:=SmartCAPWAP WTP
|
||||
MAINTAINER:=Massimo Vellucci <vemax78@gmail.com>
|
||||
DEPENDS:=+libnl-tiny +libconfig +libwolfssl +kmod-smartcapwap
|
||||
DEPENDS:=+libnl +libev +libconfig +libcyassl +kmod-smartcapwap
|
||||
endef
|
||||
|
||||
define Package/smartcapwap/description
|
||||
This package contains the SmartCAPWAP WTP daemon.
|
||||
endef
|
||||
|
||||
define Package/smartcapwap/conffiles
|
||||
/etc/capwap/wtp.conf
|
||||
/etc/capwap/ca.crt
|
||||
/etc/capwap/wtp.crt
|
||||
/etc/capwap/wtp.key
|
||||
endef
|
||||
|
||||
define KernelPackage/smartcapwap
|
||||
SUBMENU:=Network Support
|
||||
TITLE:=SmartCAPWAP Data Channel Module
|
||||
MAINTAINER:=Massimo Vellucci <vemax78@gmail.com>
|
||||
DEPENDS:=+kmod-mac80211 +kmod-ipv6
|
||||
DEPENDS:=+kmod-mac80211 +kmod-udptunnel4 +IPV6:kmod-udptunnel6
|
||||
FILES:=$(PKG_BUILD_DIR)/src/wtp/kmod/smartcapwap.ko
|
||||
AUTOLOAD:=$(call AutoLoad,70,smartcapwap)
|
||||
endef
|
||||
@ -49,8 +67,7 @@ define KernelPackage/smartcapwap/description
|
||||
This package contains the SmartCAPWAP Data Transport kernel module.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny
|
||||
SRC_SMARTCAPWAP := /mnt/hgfs/shared/smartcapwap
|
||||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/libnl3
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 03b6aa026d60cd49931934338d8ca82d05acc818 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
|
||||
@ -8,9 +8,9 @@ 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 | 306 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 462 insertions(+), 12 deletions(-)
|
||||
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..3769c33 100644
|
||||
index bdc224d..5da49f0 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -2939,6 +2939,138 @@ 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..3769c33 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..3769c33 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
|
||||
@ -388,12 +389,17 @@ index bdc224d..3769c33 100644
|
||||
+ payload[7]);
|
||||
+ }
|
||||
+
|
||||
+ memset(info, 0, sizeof(*info));
|
||||
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
+ u8 *p = ieee80211_get_qos_ctl(hdr);
|
||||
+
|
||||
+ 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;
|
||||
@ -405,46 +411,17 @@ index bdc224d..3769c33 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:
|
||||
@ -461,10 +438,6 @@ index bdc224d..3769c33 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
|
||||
@ -476,7 +449,7 @@ index bdc224d..3769c33 100644
|
||||
struct sk_buff *
|
||||
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u32 info_flags)
|
||||
@@ -3914,3 +4046,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();
|
||||
}
|
||||
@ -655,5 +628,5 @@ index bdc224d..3769c33 100644
|
||||
+EXPORT_SYMBOL(ieee80211_inject_xmit);
|
||||
+
|
||||
--
|
||||
2.7.0
|
||||
2.8.1
|
||||
|
||||
|
@ -170,7 +170,8 @@ static void execute_ieee80211_station_configuration_response_addstation(struct a
|
||||
station = ac_stations_get_station(session, station80211->radioid, wlan->address, addstation->address);
|
||||
if (station) {
|
||||
if (CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
log_printf(LOG_INFO, "Authorized station: %s", station->addrtext);
|
||||
log_printf(LOG_INFO, "Authorized station: " MACSTR,
|
||||
MAC2STR(station->address));
|
||||
|
||||
/* */
|
||||
station->flags |= AC_STATION_FLAGS_AUTHORIZED;
|
||||
@ -198,7 +199,8 @@ static void execute_ieee80211_station_configuration_response_deletestation(struc
|
||||
/* */
|
||||
station = ac_stations_get_station(session, deletestation->radioid, NULL, deletestation->address);
|
||||
if (station) {
|
||||
log_printf(LOG_INFO, "Deauthorized station: %s with %d result code", station->addrtext, (int)resultcode->code);
|
||||
log_printf(LOG_INFO, "Deauthorized station: " MACSTR " with %d result code",
|
||||
MAC2STR(station->address), (int)resultcode->code);
|
||||
|
||||
/* */
|
||||
ac_stations_delete_station(session, station);
|
||||
|
@ -42,7 +42,8 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session
|
||||
}
|
||||
|
||||
/* */
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Authentication Request from %s station", station->addrtext);
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Authentication Request "
|
||||
"from " MACSTR " station", MAC2STR(station->address));
|
||||
|
||||
/* A station is removed if the association does not complete within a given period of time */
|
||||
station->timeoutaction = AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
|
||||
@ -62,7 +63,8 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session
|
||||
|
||||
/* Parsing Information Elements */
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
|
||||
log_printf(LOG_INFO, "Invalid IEEE802.11 Authentication Request from %s station", station->addrtext);
|
||||
log_printf(LOG_INFO, "Invalid IEEE802.11 Authentication Request "
|
||||
"from " MACSTR " station", MAC2STR(station->address));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -95,14 +97,18 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session
|
||||
if (responselength > 0) {
|
||||
/* Send authentication response */
|
||||
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
|
||||
log_printf(LOG_INFO, "Sent IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)responsestatuscode);
|
||||
log_printf(LOG_INFO, "Sent IEEE802.11 Authentication Response "
|
||||
"to " MACSTR " station with %d status code",
|
||||
MAC2STR(station->address), (int)responsestatuscode);
|
||||
station->flags |= AC_STATION_FLAGS_AUTHENTICATED;
|
||||
} else {
|
||||
log_printf(LOG_WARNING, "Unable to send IEEE802.11 Authentication Response to %s station", station->addrtext);
|
||||
log_printf(LOG_WARNING, "Unable to send IEEE802.11 Authentication Response "
|
||||
"to " MACSTR " station", MAC2STR(station->address));
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
} else {
|
||||
log_printf(LOG_WARNING, "Unable to create IEEE802.11 Authentication Response to %s station", station->addrtext);
|
||||
log_printf(LOG_WARNING, "Unable to create IEEE802.11 Authentication Response "
|
||||
"to " MACSTR " station", MAC2STR(station->address));
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
@ -117,7 +123,9 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_t* session
|
||||
statuscode = __le16_to_cpu(mgmt->authetication.statuscode);
|
||||
|
||||
/* */
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Authentication Response to %s station with %d status code", station->addrtext, (int)statuscode);
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Authentication Response "
|
||||
"to " MACSTR " station with %d status code",
|
||||
MAC2STR(station->address), (int)statuscode);
|
||||
|
||||
if (statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
|
||||
@ -155,13 +163,15 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_t* se
|
||||
}
|
||||
|
||||
/* */
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Association Request from %s station", station->addrtext);
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Association Request "
|
||||
"from " MACSTR " station", MAC2STR(station->address));
|
||||
|
||||
/* */
|
||||
wlan = station->wlan;
|
||||
if (!(station->flags & AC_STATION_FLAGS_AUTHENTICATED)) {
|
||||
/* Invalid station, delete station */
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Association Request from %s unauthorized station", station->addrtext);
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Association Request "
|
||||
"from " MACSTR " unauthorized station", MAC2STR(station->address));
|
||||
ac_stations_delete_station(session, station);
|
||||
return;
|
||||
}
|
||||
@ -191,7 +201,8 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_t* se
|
||||
|
||||
/* Parsing Information Elements */
|
||||
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
|
||||
log_printf(LOG_INFO, "Invalid IEEE802.11 Association Request from %s station", station->addrtext);
|
||||
log_printf(LOG_INFO, "Invalid IEEE802.11 Association Request "
|
||||
"from " MACSTR " station", MAC2STR(station->address));
|
||||
ac_stations_delete_station(session, station);
|
||||
return;
|
||||
}
|
||||
@ -237,17 +248,21 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_t* se
|
||||
if (responselength > 0) {
|
||||
/* Send association response */
|
||||
if (!ac_kmod_send_data(&session->sessionid, wlan->device->radioid, session->binding, buffer, responselength)) {
|
||||
log_printf(LOG_INFO, "Sent IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)resultstatuscode);
|
||||
log_printf(LOG_INFO, "Sent IEEE802.11 Association Response "
|
||||
"to " MACSTR " station with %d status code",
|
||||
MAC2STR(station->address), (int)resultstatuscode);
|
||||
|
||||
/* Active Station */
|
||||
station->flags |= AC_STATION_FLAGS_ASSOCIATE;
|
||||
ac_stations_authorize_station(session, station);
|
||||
} else {
|
||||
log_printf(LOG_WARNING, "Unable to send IEEE802.11 Association Response to %s station", station->addrtext);
|
||||
log_printf(LOG_WARNING, "Unable to send IEEE802.11 Association Response "
|
||||
"to " MACSTR " station", MAC2STR(station->address));
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
} else {
|
||||
log_printf(LOG_WARNING, "Unable to create IEEE802.11 Association Response to %s station", station->addrtext);
|
||||
log_printf(LOG_WARNING, "Unable to create IEEE802.11 Association Response "
|
||||
"to " MACSTR " station", MAC2STR(station->address));
|
||||
ac_stations_delete_station(session, station);
|
||||
}
|
||||
}
|
||||
@ -271,7 +286,9 @@ static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_t* s
|
||||
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
|
||||
station = ac_stations_get_station(session, radioid, mgmt->bssid, mgmt->da);
|
||||
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)mgmt->associationresponse.statuscode);
|
||||
log_printf(LOG_INFO, "Receive IEEE802.11 Association Response "
|
||||
"to " MACSTR " station with %d status code",
|
||||
MAC2STR(station->address), (int)mgmt->associationresponse.statuscode);
|
||||
|
||||
if (mgmt->associationresponse.statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
/* Get Station Info */
|
||||
|
@ -45,7 +45,7 @@ static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* */
|
||||
log_printf(LOG_INFO, "Destroy station: %s", station->addrtext);
|
||||
log_printf(LOG_INFO, "Destroy station: " MACSTR, MAC2STR(station->address));
|
||||
|
||||
/* Remove reference from Authoritative Stations List */
|
||||
capwap_rwlock_wrlock(&g_ac.authstationslock);
|
||||
@ -139,9 +139,8 @@ void ac_wlans_destroy(struct ac_session_t* session) {
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
|
||||
char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan)
|
||||
{
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(session->wlans != NULL);
|
||||
ASSERT(wlan != NULL);
|
||||
@ -166,7 +165,8 @@ int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
|
||||
capwap_itemlist_insert_after(session->wlans->devices[wlan->device->radioid - 1].wlans, NULL, wlan->wlanitem);
|
||||
|
||||
/* */
|
||||
log_printf(LOG_INFO, "Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->device->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->address, MACADDRESS_EUI48_LENGTH));
|
||||
log_printf(LOG_INFO, "Added new wlan with radioid: %d, wlanid: %d, bssid: " MACSTR,
|
||||
(int)wlan->device->radioid, (int)wlan->wlanid, MAC2STR(wlan->address));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -325,9 +325,8 @@ struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t
|
||||
}
|
||||
|
||||
/* */
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
|
||||
char buffer1[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
char buffer2[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address)
|
||||
{
|
||||
struct ac_wlan* wlan;
|
||||
struct ac_station* authoritativestation;
|
||||
struct ac_station* station = NULL;
|
||||
@ -340,9 +339,8 @@ struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint
|
||||
ASSERT(address != NULL);
|
||||
|
||||
/* */
|
||||
capwap_printf_macaddress(buffer1, bssid, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_printf_macaddress(buffer2, address, MACADDRESS_EUI48_LENGTH);
|
||||
log_printf(LOG_INFO, "Create station to radioid: %d, bssid: %s, station address: %s", (int)radioid, buffer1, buffer2);
|
||||
log_printf(LOG_INFO, "Create station to radioid: %d, bssid: " MACSTR ", station address: " MACSTR,
|
||||
(int)radioid, MAC2STR(bssid), MAC2STR(address));
|
||||
|
||||
/* */
|
||||
wlan = ac_wlans_get_bssid(session, radioid, bssid);
|
||||
@ -357,7 +355,6 @@ struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint
|
||||
/* */
|
||||
station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
|
||||
memcpy(station->address, address, MACADDRESS_EUI48_LENGTH);
|
||||
capwap_printf_macaddress(station->addrtext, address, MACADDRESS_EUI48_LENGTH);
|
||||
station->wlanitem = stationitem;
|
||||
station->session = session;
|
||||
|
||||
@ -392,7 +389,8 @@ struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_printf(LOG_WARNING, "Unable to find radioid: %d, bssid: %s", (int)radioid, buffer1);
|
||||
log_printf(LOG_WARNING, "Unable to find radioid: %d, bssid: " MACSTR,
|
||||
(int)radioid, MAC2STR(bssid));
|
||||
}
|
||||
|
||||
return station;
|
||||
@ -479,7 +477,8 @@ void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, vo
|
||||
if (station->idtimeout == index) {
|
||||
switch (station->timeoutaction) {
|
||||
case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
|
||||
log_printf(LOG_WARNING, "The %s station has not completed the association in time", station->addrtext);
|
||||
log_printf(LOG_WARNING, "The " MACSTR " station has not completed "
|
||||
"the association in time", MAC2STR(station->address));
|
||||
ac_stations_delete_station((struct ac_session_t*)param, station);
|
||||
break;
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ struct ac_wlans {
|
||||
/* AC Station */
|
||||
struct ac_station {
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
/* */
|
||||
unsigned long flags;
|
||||
|
@ -764,3 +764,27 @@ int ieee80211_create_deauthentication(uint8_t* buffer, int length, struct ieee80
|
||||
|
||||
return (int)((uint8_t*)&header->deauthetication.ie[0] - (uint8_t*)header);
|
||||
}
|
||||
|
||||
/* */
|
||||
int ieee80211_create_disassociation(uint8_t* buffer, int length,
|
||||
struct ieee80211_disassociation_params* params)
|
||||
{
|
||||
struct ieee80211_header_mgmt* header;
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
/* */
|
||||
header = (struct ieee80211_header_mgmt*)buffer;
|
||||
|
||||
/* Management header frame */
|
||||
header->framecontrol = IEEE80211_FRAME_CONTROL(IEEE80211_FRAMECONTROL_TYPE_MGMT,
|
||||
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION);
|
||||
header->durationid = __cpu_to_le16(0);
|
||||
memcpy(header->da, params->station, ETH_ALEN);
|
||||
memcpy(header->sa, params->bssid, ETH_ALEN);
|
||||
memcpy(header->bssid, params->bssid, ETH_ALEN);
|
||||
header->sequencecontrol = __cpu_to_le16(0);
|
||||
header->disassociation.reasoncode = __cpu_to_le16(params->reasoncode);
|
||||
|
||||
return (int)((uint8_t*)&header->disassociation.ie[0] - (uint8_t*)header);
|
||||
}
|
||||
|
@ -420,6 +420,9 @@ struct ieee80211_ie_erp {
|
||||
uint8_t params;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* 802.11 RSN information element */
|
||||
#define IEEE80211_IE_RSN_INFORMATION 48
|
||||
|
||||
/* 802.11 Extended Supported Rates information element */
|
||||
#define IEEE80211_IE_EXTENDED_SUPPORTED_RATES 50
|
||||
#define IEEE80211_IE_EXTENDED_SUPPORTED_MIN_LENGTH 1
|
||||
@ -697,6 +700,16 @@ struct ieee80211_deauthentication_params {
|
||||
|
||||
int ieee80211_create_deauthentication(uint8_t* buffer, int length, struct ieee80211_deauthentication_params* params);
|
||||
|
||||
/* Management Disassociation */
|
||||
struct ieee80211_disassociation_params {
|
||||
uint8_t bssid[ETH_ALEN];
|
||||
uint8_t station[ETH_ALEN];
|
||||
|
||||
uint16_t reasoncode;
|
||||
};
|
||||
|
||||
int ieee80211_create_disassociation(uint8_t* buffer, int length, struct ieee80211_disassociation_params* params);
|
||||
|
||||
/* Utils */
|
||||
int ieee80211_retrieve_information_elements_position(struct ieee80211_ie_items* items, const uint8_t* data, int length);
|
||||
unsigned long ieee80211_frequency_to_channel(uint32_t freq);
|
||||
|
@ -1,9 +1,6 @@
|
||||
#ifndef __CAPWAP_DEBUG_HEADER__
|
||||
#define __CAPWAP_DEBUG_HEADER__
|
||||
|
||||
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define ASSERT(expr) if (!(expr)) { log_printf(LOG_EMERG, "Assertion failed \'%s\': %s(%d)", #expr, __FILE__, __LINE__); capwap_exit(CAPWAP_ASSERT_CONDITION); }
|
||||
|
@ -91,8 +91,9 @@ static const struct capwap_message_elements_ops * capwap_80211_message_elements[
|
||||
/* */
|
||||
#define element_ops(Id, Ops) [(Id) - 1] = &(Ops)
|
||||
static const struct capwap_message_elements_ops * capwap_vendor_travelping_message_elements[] = {
|
||||
element_ops(CAPWAP_ELEMENT_80211N_RADIO_CONF_TYPE, capwap_element_80211n_radioconf_ops),
|
||||
element_ops(CAPWAP_ELEMENT_80211N_STATION_INFO_TYPE, capwap_element_80211n_station_info_ops)
|
||||
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)
|
||||
};
|
||||
#undef element_ops
|
||||
|
||||
@ -138,7 +139,7 @@ struct capwap_list_item* capwap_get_message_element(struct capwap_parsed_packet*
|
||||
while (search) {
|
||||
struct capwap_message_element_itemlist* messageelement =
|
||||
(struct capwap_message_element_itemlist*)search->item;
|
||||
if ((id.vendor == messageelement->id.vendor) && (id.type == messageelement->id.type))
|
||||
if (message_element_id_eq(id, messageelement->id))
|
||||
return search;
|
||||
|
||||
/* */
|
||||
|
@ -10,6 +10,9 @@ struct capwap_message_element_id
|
||||
uint16_t type;
|
||||
};
|
||||
|
||||
#define message_element_id_eq(a, b) \
|
||||
(((a).vendor == (b).vendor) && ((a).type == (b).type))
|
||||
|
||||
/* */
|
||||
typedef void* capwap_message_elements_handle;
|
||||
struct capwap_write_message_elements_ops {
|
||||
|
@ -39,7 +39,9 @@ static void capwap_80211_stationkey_element_create(void* data, capwap_message_el
|
||||
}
|
||||
|
||||
/* */
|
||||
static void* capwap_80211_stationkey_element_parsing(capwap_message_elements_handle handle, struct capwap_read_message_elements_ops* func) {
|
||||
static void* capwap_80211_stationkey_element_parsing(capwap_message_elements_handle handle,
|
||||
struct capwap_read_message_elements_ops* func)
|
||||
{
|
||||
unsigned short length;
|
||||
struct capwap_80211_stationkey_element* data;
|
||||
|
||||
@ -53,10 +55,11 @@ static void* capwap_80211_stationkey_element_parsing(capwap_message_elements_han
|
||||
}
|
||||
|
||||
/* */
|
||||
data = (struct capwap_80211_stationkey_element*)capwap_alloc(sizeof(struct capwap_80211_stationkey_element));
|
||||
data = (struct capwap_80211_stationkey_element *)
|
||||
capwap_alloc(sizeof(struct capwap_80211_stationkey_element));
|
||||
memset(data, 0, sizeof(struct capwap_80211_stationkey_element));
|
||||
data->keylength = length - 20;
|
||||
data->key = (uint8_t*)capwap_alloc(data->keylength);
|
||||
memset(data, 0, sizeof(struct capwap_80211_stationkey_element));
|
||||
|
||||
/* Retrieve data */
|
||||
func->read_block(handle, data->address, MACADDRESS_EUI48_LENGTH);
|
||||
|
109
src/common/capwap_element_vendor_travelping_wtp_timestamp.c
Normal file
109
src/common/capwap_element_vendor_travelping_wtp_timestamp.c
Normal file
@ -0,0 +1,109 @@
|
||||
#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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Second |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Fraction |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* WTP Timestamp
|
||||
*
|
||||
* Vendor Id: 18681 (Travelping GmbH)
|
||||
* Type: 2
|
||||
*
|
||||
*/
|
||||
|
||||
struct ntp_time_t {
|
||||
uint32_t second;
|
||||
uint32_t fraction;
|
||||
};
|
||||
|
||||
static inline void convert_ntp_time_into_unix_time(struct ntp_time_t *ntp, struct timeval *tv)
|
||||
{
|
||||
tv->tv_sec = ntp->second - 0x83AA7E80; // the seconds from Jan 1, 1900 to Jan 1, 1970
|
||||
tv->tv_usec = (uint32_t)( (double)ntp->fraction * 1.0e6 / (double)(1LL<<32) );
|
||||
}
|
||||
|
||||
static inline void convert_unix_time_into_ntp_time(struct timeval *tv, struct ntp_time_t *ntp)
|
||||
{
|
||||
ntp->second = tv->tv_sec + 0x83AA7E80;
|
||||
ntp->fraction = (uint32_t)( (double)(tv->tv_usec+1) * (double)(1LL<<32) * 1.0e-6 );
|
||||
}
|
||||
|
||||
/* */
|
||||
static void
|
||||
capwap_vendor_travelping_wtp_timestamp_element_create(void *data,
|
||||
capwap_message_elements_handle handle,
|
||||
struct capwap_write_message_elements_ops *func)
|
||||
{
|
||||
struct capwap_vendor_travelping_wtp_timestamp_element *element =
|
||||
(struct capwap_vendor_travelping_wtp_timestamp_element *)data;
|
||||
struct ntp_time_t ntp;
|
||||
|
||||
ASSERT(data != NULL);
|
||||
|
||||
convert_unix_time_into_ntp_time(&element->tv, &ntp);
|
||||
|
||||
func->write_u32(handle, ntp.second);
|
||||
func->write_u32(handle, ntp.fraction);
|
||||
}
|
||||
|
||||
/* */
|
||||
static void *
|
||||
capwap_vendor_travelping_wtp_timestamp_element_parsing(capwap_message_elements_handle handle,
|
||||
struct capwap_read_message_elements_ops *func)
|
||||
{
|
||||
struct capwap_vendor_travelping_wtp_timestamp_element *data;
|
||||
struct ntp_time_t ntp;
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT(func != NULL);
|
||||
|
||||
if (func->read_ready(handle) != 8) {
|
||||
log_printf(LOG_DEBUG, "Invalid Vendor Travelping WTP Timestamp element");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
data = (struct capwap_vendor_travelping_wtp_timestamp_element *)
|
||||
capwap_alloc(sizeof(struct capwap_vendor_travelping_wtp_timestamp_element));
|
||||
|
||||
/* Retrieve data */
|
||||
func->read_u32(handle, &ntp.second);
|
||||
func->read_u32(handle, &ntp.fraction);
|
||||
|
||||
convert_ntp_time_into_unix_time(&ntp, &data->tv);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void *
|
||||
capwap_vendor_travelping_wtp_timestamp_element_clone(void *data)
|
||||
{
|
||||
ASSERT(data != NULL);
|
||||
|
||||
return capwap_clone(data, sizeof(struct capwap_vendor_travelping_wtp_timestamp_element));
|
||||
}
|
||||
|
||||
/* */
|
||||
static void
|
||||
capwap_vendor_travelping_wtp_timestamp_element_free(void* data)
|
||||
{
|
||||
ASSERT(data != NULL);
|
||||
|
||||
capwap_free(data);
|
||||
}
|
||||
|
||||
/* */
|
||||
const struct capwap_message_elements_ops capwap_element_vendor_travelping_wtp_timestamp_ops = {
|
||||
.category = CAPWAP_MESSAGE_ELEMENT_SINGLE,
|
||||
.create = capwap_vendor_travelping_wtp_timestamp_element_create,
|
||||
.parse = capwap_vendor_travelping_wtp_timestamp_element_parsing,
|
||||
.clone = capwap_vendor_travelping_wtp_timestamp_element_clone,
|
||||
.free = capwap_vendor_travelping_wtp_timestamp_element_free
|
||||
};
|
19
src/common/capwap_element_vendor_travelping_wtp_timestamp.h
Normal file
19
src/common/capwap_element_vendor_travelping_wtp_timestamp.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef __CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_HEADER__
|
||||
#define __CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_HEADER__
|
||||
|
||||
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_VENDOR CAPWAP_VENDOR_TRAVELPING_ID
|
||||
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_TYPE 2
|
||||
#define CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP \
|
||||
(struct capwap_message_element_id){ \
|
||||
.vendor = CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_VENDOR, \
|
||||
.type = CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_TYPE \
|
||||
}
|
||||
|
||||
|
||||
struct capwap_vendor_travelping_wtp_timestamp_element {
|
||||
struct timeval tv;
|
||||
};
|
||||
|
||||
extern const struct capwap_message_elements_ops capwap_element_vendor_travelping_wtp_timestamp_ops;
|
||||
|
||||
#endif /* __CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP_HEADER__ */
|
@ -1,6 +1,9 @@
|
||||
#ifndef __CAPWAP_LOGGING_HEADER__
|
||||
#define __CAPWAP_LOGGING_HEADER__
|
||||
|
||||
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
|
||||
#include <syslog.h>
|
||||
#define LOG_TO_SYSLOG
|
||||
|
||||
|
@ -384,7 +384,9 @@ int capwap_sendto(int sock, void* buffer, int size, union sockaddr_capwap* toadd
|
||||
#ifdef DEBUG
|
||||
{
|
||||
char strtoaddr[INET6_ADDRSTRLEN];
|
||||
log_printf(LOG_DEBUG, "Sent packet to %s:%d with result %d", capwap_address_to_string(toaddr, strtoaddr, INET6_ADDRSTRLEN), (int)CAPWAP_GET_NETWORK_PORT(toaddr), result);
|
||||
log_printf(LOG_DEBUG, "Sent packet to %s:%d with result %d",
|
||||
capwap_address_to_string(toaddr, strtoaddr, INET6_ADDRSTRLEN),
|
||||
(int)CAPWAP_GET_NETWORK_PORT(toaddr), result);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#define CAPWAP_VENDOR_TRAVELPING_ID 18681
|
||||
|
||||
#include "capwap_element_vendor_travelping_wtp_timestamp.h"
|
||||
|
||||
/* draft-ietf-opsawg-capwap-extension-06 */
|
||||
#include "capwap_element_80211n_radioconf.h"
|
||||
#include "capwap_element_80211n_station_information.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,10 +28,11 @@
|
||||
|
||||
/* */
|
||||
#define WIFI_CAPABILITY_FLAGS_OFFCHANNEL_TX_OK 0x00000001
|
||||
#define WIFI_CAPABILITY_FLAGS_ROAM_SUPPORT 0x00000002
|
||||
#define WIFI_CAPABILITY_FLAGS_ROAM_SUPPORT 0x00000002
|
||||
#define WIFI_CAPABILITY_FLAGS_SUPPORT_AP_UAPSD 0x00000004
|
||||
#define WIFI_CAPABILITY_FLAGS_DEVICE_AP_SME 0x00000008
|
||||
#define WIFI_CAPABILITY_FLAGS_PROBE_RESPONSE_OFFLOAD 0x00000010
|
||||
#define WIFI_CAPABILITY_FLAGS_DEVICE_AP_SME 0x00000008
|
||||
#define WIFI_CAPABILITY_FLAGS_PROBE_RESPONSE_OFFLOAD 0x00000010
|
||||
#define WIFI_CAPABILITY_FLAGS_INACTIVITY_TIMER 0x00000020
|
||||
|
||||
/* */
|
||||
#define WIFI_CAPABILITY_AP_SUPPORTED 0x00000001
|
||||
@ -70,6 +71,7 @@ DECLARE_OPAQUE_TYPE(wifi_device_handle);
|
||||
DECLARE_OPAQUE_TYPE(wifi_wlan_handle);
|
||||
|
||||
struct capwap_80211_wtpqos_element;
|
||||
struct capwap_80211_stationkey_element;
|
||||
|
||||
/* */
|
||||
struct device_setrates_params {
|
||||
@ -105,9 +107,27 @@ struct wlan_startap_params {
|
||||
uint8_t macmode;
|
||||
uint8_t tunnelmode;
|
||||
|
||||
uint8_t keyindex;
|
||||
uint8_t keylength;
|
||||
uint8_t *key;
|
||||
|
||||
struct capwap_array *ie;
|
||||
};
|
||||
|
||||
struct wlan_updateap_params {
|
||||
uint8_t radioid;
|
||||
uint8_t wlanid;
|
||||
|
||||
uint16_t capability;
|
||||
uint8_t qos;
|
||||
|
||||
uint8_t keyindex;
|
||||
uint8_t keystatus;
|
||||
uint8_t keylength;
|
||||
uint8_t *key;
|
||||
|
||||
struct capwap_array *ie;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct wlan_send_frame_params {
|
||||
@ -127,6 +147,9 @@ struct wlan_send_frame_params {
|
||||
struct station_add_params {
|
||||
uint8_t* address;
|
||||
struct ieee80211_ht_cap *ht_cap;
|
||||
uint32_t pairwise;
|
||||
struct capwap_80211_stationkey_element *key;
|
||||
int max_inactivity;
|
||||
};
|
||||
|
||||
/* Interface capability */
|
||||
@ -161,6 +184,11 @@ struct wifi_band_capability {
|
||||
struct capwap_array* rate;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct wifi_commands_capability {
|
||||
unsigned int poll_command_supported:1;
|
||||
};
|
||||
|
||||
/* */
|
||||
struct wifi_cipher_capability {
|
||||
unsigned long cipher;
|
||||
@ -186,6 +214,8 @@ struct wifi_capability {
|
||||
/* WIFI_CAPABILITY_BANDS */
|
||||
struct capwap_array* bands;
|
||||
|
||||
struct wifi_commands_capability supp_cmds;
|
||||
|
||||
/* WIFI_CAPABILITY_CIPHERS */
|
||||
struct capwap_array* ciphers;
|
||||
|
||||
@ -317,6 +347,12 @@ struct wifi_wlan {
|
||||
|
||||
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
|
||||
|
||||
struct ieee80211_ie *rsne;
|
||||
uint32_t group_cipher_suite;
|
||||
uint8_t keyindex;
|
||||
uint8_t keylength;
|
||||
uint8_t *key;
|
||||
|
||||
int beacon_ies_len;
|
||||
uint8_t *beacon_ies;
|
||||
int response_ies_len;
|
||||
@ -324,34 +360,39 @@ struct wifi_wlan {
|
||||
};
|
||||
|
||||
/* Station handle */
|
||||
#define WIFI_STATION_FLAGS_AUTHENTICATED 0x00000001
|
||||
#define WIFI_STATION_FLAGS_ASSOCIATE 0x00000002
|
||||
#define WIFI_STATION_FLAGS_NON_ERP 0x00000004
|
||||
#define WIFI_STATION_FLAGS_NO_SHORT_SLOT_TIME 0x00000008
|
||||
#define WIFI_STATION_FLAGS_NO_SHORT_PREAMBLE 0x00000010
|
||||
#define WIFI_STATION_FLAGS_WMM 0x00000020
|
||||
#define WIFI_STATION_FLAGS_AUTHORIZED 0x00000040
|
||||
#define WIFI_STATION_FLAGS_HT_CAP 0x00000080
|
||||
#define WIFI_STATION_FLAGS_AUTHENTICATED 0x00000001
|
||||
#define WIFI_STATION_FLAGS_ASSOCIATE 0x00000002
|
||||
#define WIFI_STATION_FLAGS_NON_ERP 0x00000004
|
||||
#define WIFI_STATION_FLAGS_NO_SHORT_SLOT_TIME 0x00000008
|
||||
#define WIFI_STATION_FLAGS_NO_SHORT_PREAMBLE 0x00000010
|
||||
#define WIFI_STATION_FLAGS_WMM 0x00000020
|
||||
#define WIFI_STATION_FLAGS_AUTHORIZED 0x00000040
|
||||
#define WIFI_STATION_FLAGS_HT_CAP 0x00000080
|
||||
#define WIFI_STATION_FLAGS_POLL_PENDING 0x00000100
|
||||
|
||||
/* */
|
||||
#define WIFI_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
|
||||
#define WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED 5000
|
||||
|
||||
/* */
|
||||
#define WIFI_STATION_TIMEOUT_ACTION_DELETE 0x00000001
|
||||
#define WIFI_STATION_TIMEOUT_ACTION_DEAUTHENTICATE 0x00000002
|
||||
#define WIFI_STATION_TIMEOUT_ASSOCIATION_COMPLETE 30000
|
||||
#define WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED 5000
|
||||
#define WIFI_STATION_TIMEOUT_BEFORE_DISASSOCIATE 3000
|
||||
#define WIFI_STATION_TIMEOUT_BEFORE_DEAUTHENTICATE 1000
|
||||
|
||||
struct wifi_station {
|
||||
uint8_t address[MACADDRESS_EUI48_LENGTH];
|
||||
char addrtext[CAPWAP_MACADDRESS_EUI48_BUFFER];
|
||||
|
||||
/* */
|
||||
struct wifi_wlan* wlan;
|
||||
|
||||
/* */
|
||||
unsigned long flags;
|
||||
uint32_t flags;
|
||||
|
||||
/* Timers */
|
||||
/* Timer */
|
||||
int max_inactivity;
|
||||
enum {
|
||||
WIFI_STATION_TIMEOUT_ACTION_SEND_NULLFUNC = 0,
|
||||
WIFI_STATION_TIMEOUT_ACTION_DEAUTHENTICATE,
|
||||
WIFI_STATION_TIMEOUT_ACTION_DISASSOCIATE,
|
||||
WIFI_STATION_TIMEOUT_ACTION_DELETE
|
||||
} timeout_action;
|
||||
struct ev_timer timeout;
|
||||
|
||||
/* */
|
||||
@ -365,6 +406,8 @@ struct wifi_station {
|
||||
|
||||
/* Authentication */
|
||||
uint16_t authalgorithm;
|
||||
uint32_t pairwise_cipher;
|
||||
struct capwap_80211_stationkey_element *key;
|
||||
|
||||
uint8_t qosinfo;
|
||||
|
||||
@ -394,11 +437,18 @@ struct wifi_driver_ops {
|
||||
int (*wlan_startap)(struct wifi_wlan* wlan);
|
||||
void (*wlan_stopap)(struct wifi_wlan* wlan);
|
||||
int (*wlan_sendframe)(struct wifi_wlan* wlan, uint8_t* frame, int length, uint32_t frequency, uint32_t duration, int offchannel_tx_ok, int no_cck_rate, int no_wait_ack);
|
||||
void (*wlan_poll_station)(struct wifi_wlan* wlan, const uint8_t* address, int qos);
|
||||
void (*wlan_delete)(struct wifi_wlan* wlan);
|
||||
int (*wlan_set_key)(struct wifi_wlan* wlan,
|
||||
uint32_t alg, const uint8_t *addr,
|
||||
int key_idx, int set_tx,
|
||||
const uint8_t *seq, size_t seq_len,
|
||||
const uint8_t *key, size_t key_len);
|
||||
|
||||
/* Stations functions */
|
||||
int (*station_authorize)(struct wifi_wlan* wlan, struct wifi_station* station);
|
||||
int (*station_deauthorize)(struct wifi_wlan* wlan, const uint8_t* address);
|
||||
int (*station_get_inact_sec)(struct wifi_wlan* wlan, const uint8_t* address);
|
||||
};
|
||||
|
||||
/* Initialize wifi driver engine */
|
||||
@ -419,6 +469,7 @@ int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int rate
|
||||
/* WLAN management */
|
||||
struct wifi_wlan* wifi_wlan_create(struct wifi_device* device, const char* ifname);
|
||||
int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params);
|
||||
int wifi_wlan_updateap(struct wifi_wlan* wlan, struct wlan_updateap_params* params);
|
||||
void wifi_wlan_stopap(struct wifi_wlan* wlan);
|
||||
int wifi_wlan_getbssid(struct wifi_wlan* wlan, uint8_t* bssid);
|
||||
uint16_t wifi_wlan_check_capability(struct wifi_wlan* wlan, uint16_t capability);
|
||||
@ -429,16 +480,15 @@ void wifi_wlan_destroy(struct wifi_wlan* wlan);
|
||||
void wifi_wlan_receive_station_frame(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, uint32_t frequency, uint8_t rssi, uint8_t snr, uint16_t rate);
|
||||
void wifi_wlan_receive_station_ackframe(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, int ack);
|
||||
void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, struct ieee80211_header* frame, int length);
|
||||
void wifi_wlan_client_probe_event(struct wifi_wlan *wlan, const uint8_t *address);
|
||||
|
||||
/* Station management */
|
||||
int wifi_station_set_key(struct wifi_wlan *wlan, struct wifi_station* station);
|
||||
int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* params);
|
||||
void wifi_station_deauthorize(struct wifi_device* device, const uint8_t* address);
|
||||
|
||||
/* Util functions */
|
||||
uint32_t wifi_iface_index(const char* ifname);
|
||||
int wifi_iface_hwaddr(int sock, const char* ifname, uint8_t* hwaddr);
|
||||
|
||||
int wifi_frequency_to_radiotype(uint32_t freq);
|
||||
|
||||
/* */
|
||||
int wifi_iface_getstatus(int sock, const char* ifname);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -49,4 +49,13 @@ struct nl80211_wlan_handle {
|
||||
uint64_t last_cookie;
|
||||
};
|
||||
|
||||
/* NL80211 Station statistics */
|
||||
struct nl80211_station_data {
|
||||
unsigned long rx_packets, tx_packets;
|
||||
unsigned long long rx_bytes, tx_bytes;
|
||||
int bytes_64bit;
|
||||
unsigned long inactive_msec;
|
||||
unsigned long tx_retry_failed;
|
||||
};
|
||||
|
||||
#endif /* __WIFI_NL80211_HEADER__ */
|
||||
|
@ -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)) {
|
||||
@ -637,7 +637,16 @@ int sc_capwap_parsingpacket(struct sc_capwap_session* session,
|
||||
}
|
||||
|
||||
/* */
|
||||
int sc_capwap_forwarddata(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, int winfolength) {
|
||||
int sc_capwap_forwarddata(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,
|
||||
int winfolength)
|
||||
{
|
||||
int err;
|
||||
int size;
|
||||
int length;
|
||||
@ -650,7 +659,7 @@ int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, ui
|
||||
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);
|
||||
@ -745,25 +754,12 @@ int sc_capwap_forwarddata(struct sc_capwap_session* session, uint8_t radioid, ui
|
||||
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);
|
||||
|
||||
@ -781,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);
|
||||
|
||||
@ -801,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);
|
||||
|
||||
|
@ -50,12 +50,15 @@ union capwap_addr {
|
||||
struct sockaddr_storage ss;
|
||||
};
|
||||
|
||||
#define STA_FLAG_AKM_ONLY 0x0001
|
||||
|
||||
struct sc_station {
|
||||
struct hlist_node station_list;
|
||||
|
||||
uint8_t radioid;
|
||||
uint8_t mac[ETH_ALEN];
|
||||
uint8_t wlanid;
|
||||
uint32_t flags;
|
||||
|
||||
struct rcu_head rcu_head;
|
||||
};
|
||||
@ -136,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);
|
||||
}
|
||||
@ -169,11 +170,8 @@ static void sc_send_8023(struct sk_buff *skb, struct net_device *dev)
|
||||
static void sc_send_80211(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr;
|
||||
int hdrlen;
|
||||
|
||||
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);
|
||||
@ -185,17 +183,15 @@ static void sc_send_80211(struct sk_buff *skb, struct net_device *dev)
|
||||
/* drop conntrack reference */
|
||||
nf_reset(skb);
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
skb_reset_mac_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_transport_header(skb);
|
||||
|
||||
skb->dev = dev;
|
||||
|
||||
skb_set_mac_header(skb, hdrlen);
|
||||
skb_set_network_header(skb, hdrlen);
|
||||
skb_set_transport_header(skb, hdrlen);
|
||||
|
||||
skb->protocol = htons(ETH_P_CONTROL);
|
||||
info->flags |= IEEE80211_TX_CTL_INJECTED;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->flags = IEEE80211_TX_CTL_INJECTED;
|
||||
|
||||
/* Force the device to verify it. */
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
@ -217,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);
|
||||
|
@ -85,32 +85,58 @@ static int sc_netlink_handler(uint32_t ifindex, struct sk_buff* skb,
|
||||
int err;
|
||||
uint8_t radioaddrbuffer[CAPWAP_RADIO_EUI48_LENGTH_PADDED];
|
||||
uint8_t winfobuffer[CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED];
|
||||
uint16_t hdrlen, ethertype;
|
||||
uint8_t *payload;
|
||||
struct sc_capwap_radio_addr* radioaddr = NULL;
|
||||
struct sc_capwap_wireless_information* winfo = NULL;
|
||||
uint32_t flags = nldev->flags;
|
||||
|
||||
/* Drop packet */
|
||||
ret = -1;
|
||||
|
||||
/* IEEE 802.11 into IEEE 802.3 */
|
||||
if (nldev->flags & NLSMARTCAPWAP_FLAGS_TUNNEL_8023) {
|
||||
if (ieee80211_data_to_8023(skb, nldev->dev->dev_addr, NL80211_IFTYPE_AP)) {
|
||||
goto error;
|
||||
}
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
if (!pskb_may_pull(skb, hdrlen + 8))
|
||||
goto error;
|
||||
|
||||
/* Create Radio Mac Address */
|
||||
radioaddr = sc_capwap_setradiomacaddress(radioaddrbuffer, CAPWAP_RADIO_EUI48_LENGTH_PADDED, nldev->dev->dev_addr);
|
||||
payload = skb->data + hdrlen;
|
||||
ethertype = (payload[6] << 8) | payload[7];
|
||||
|
||||
TRACEKMOD("### sc_netlink_handler, ethertype %04x\n", ethertype);
|
||||
|
||||
switch (ethertype) {
|
||||
case ETH_P_PAE:
|
||||
/* forward EAPOL as raw 802.11 frame, clear 802.3 tunnel flag */
|
||||
flags &= ~NLSMARTCAPWAP_FLAGS_TUNNEL_8023;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* IEEE 802.11 into IEEE 802.3 */
|
||||
if (nldev->flags & NLSMARTCAPWAP_FLAGS_TUNNEL_8023) {
|
||||
if (ieee80211_data_to_8023(skb, nldev->dev->dev_addr, NL80211_IFTYPE_AP))
|
||||
goto error;
|
||||
|
||||
/* Create Radio Mac Address */
|
||||
radioaddr =
|
||||
sc_capwap_setradiomacaddress(radioaddrbuffer,
|
||||
CAPWAP_RADIO_EUI48_LENGTH_PADDED,
|
||||
nldev->dev->dev_addr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create Wireless Information */
|
||||
if (sig_dbm || rate) {
|
||||
winfo = sc_capwap_setwinfo_frameinfo(winfobuffer, CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED, (uint8_t)sig_dbm, 0, ((uint16_t)rate) * 5);
|
||||
}
|
||||
if (sig_dbm || rate)
|
||||
winfo = sc_capwap_setwinfo_frameinfo(winfobuffer,
|
||||
CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED,
|
||||
(uint8_t)sig_dbm, 0, ((uint16_t)rate) * 5);
|
||||
|
||||
/* */
|
||||
CAPWAP_SKB_CB(skb)->flags = SKB_CAPWAP_FLAG_FROM_IEEE80211;
|
||||
|
||||
/* Forward to AC */
|
||||
err = sc_capwap_forwarddata(&sn->sc_acsession, nldev->radioid, nldev->binding, skb, nldev->flags, radioaddr, (radioaddr ? CAPWAP_RADIO_EUI48_LENGTH_PADDED : 0), winfo, (winfo ? CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED : 0));
|
||||
err = sc_capwap_forwarddata(&sn->sc_acsession, nldev->radioid, nldev->binding, skb, flags,
|
||||
radioaddr, (radioaddr ? CAPWAP_RADIO_EUI48_LENGTH_PADDED : 0),
|
||||
winfo, (winfo ? CAPWAP_WINFO_FRAMEINFO_LENGTH_PADDED : 0));
|
||||
}
|
||||
|
||||
error:
|
||||
@ -642,7 +668,8 @@ static int sc_netlink_add_station(struct sk_buff* skb, struct genl_info* info)
|
||||
|
||||
if (!info->attrs[NLSMARTCAPWAP_ATTR_RADIOID] ||
|
||||
!info->attrs[NLSMARTCAPWAP_ATTR_MAC] ||
|
||||
!info->attrs[NLSMARTCAPWAP_ATTR_WLANID])
|
||||
!info->attrs[NLSMARTCAPWAP_ATTR_WLANID] ||
|
||||
!info->attrs[NLSMARTCAPWAP_ATTR_FLAGS])
|
||||
return -EINVAL;
|
||||
|
||||
radioid = nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_RADIOID]);
|
||||
@ -650,11 +677,17 @@ static int sc_netlink_add_station(struct sk_buff* skb, struct genl_info* info)
|
||||
hash = jhash(mac, ETH_ALEN, radioid) % STA_HASH_SIZE;
|
||||
sta_head = &session->station_list[hash];
|
||||
|
||||
if (sc_find_station(sta_head, radioid, mac) != NULL)
|
||||
return -EEXIST;
|
||||
sta = sc_find_station(sta_head, radioid, mac);
|
||||
if (sta) {
|
||||
if (!(info->nlhdr->nlmsg_flags & NLM_F_REPLACE))
|
||||
return -EEXIST;
|
||||
|
||||
if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE)
|
||||
return -ENXIO;
|
||||
if (sta->wlanid != nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_WLANID]))
|
||||
return -ENXIO;
|
||||
|
||||
sta->flags = nla_get_u32(info->attrs[NLSMARTCAPWAP_ATTR_FLAGS]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sta = kmalloc(sizeof(struct sc_station), GFP_KERNEL);
|
||||
if (sta == NULL)
|
||||
@ -663,6 +696,7 @@ static int sc_netlink_add_station(struct sk_buff* skb, struct genl_info* info)
|
||||
sta->radioid = radioid;
|
||||
memcpy(&sta->mac, mac, ETH_ALEN);
|
||||
sta->wlanid = nla_get_u8(info->attrs[NLSMARTCAPWAP_ATTR_WLANID]);
|
||||
sta->flags = nla_get_u32(info->attrs[NLSMARTCAPWAP_ATTR_FLAGS]);
|
||||
|
||||
hlist_add_head_rcu(&sta->station_list, sta_head);
|
||||
|
||||
|
@ -57,6 +57,7 @@ static int wtp_init(void)
|
||||
g_wtp.ecn.flag = CAPWAP_LIMITED_ECN_SUPPORT;
|
||||
g_wtp.transport.type = CAPWAP_UDP_TRANSPORT;
|
||||
g_wtp.statisticstimer.timer = WTP_STATISTICSTIMER_INTERVAL / 1000;
|
||||
g_wtp.sta_max_inactivity = WIFI_STATIONS_DEFAULT_STA_MAX_INACTIVITY;
|
||||
|
||||
g_wtp.mactype.type = CAPWAP_LOCALMAC;
|
||||
g_wtp.mactunnel.mode = CAPWAP_WTP_LOCAL_BRIDGING;
|
||||
@ -1041,6 +1042,16 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (config_lookup_int(config, "application.timer.inactivity", &configInt) == CONFIG_TRUE) {
|
||||
if ((configInt < 0) || (configInt > 3600)) {
|
||||
log_printf(LOG_ERR, "Invalid configuration file, "
|
||||
"invalid application.timer.inactivity value");
|
||||
return 0;
|
||||
}
|
||||
g_wtp.sta_max_inactivity = (unsigned short)configInt;
|
||||
}
|
||||
|
||||
/* Set DTLS of WTP */
|
||||
if (config_lookup_bool(config, "application.dtls.enable", &configBool) == CONFIG_TRUE) {
|
||||
if (configBool != 0) {
|
||||
|
@ -48,6 +48,8 @@
|
||||
#define WTP_TUNNEL_DATA_FRAME_KERNELMODE 0x00000001
|
||||
#define WTP_TUNNEL_DATA_FRAME_USERMODE 0x00000002
|
||||
|
||||
#define WIFI_STATIONS_DEFAULT_STA_MAX_INACTIVITY 300
|
||||
|
||||
/* */
|
||||
struct wtp_fds {
|
||||
int fdstotalcount;
|
||||
@ -118,6 +120,11 @@ struct wtp_t {
|
||||
struct capwap_statisticstimer_element statisticstimer;
|
||||
struct capwap_wtprebootstat_element rebootstat;
|
||||
|
||||
int sta_max_inactivity;
|
||||
|
||||
/* Echo statistics */
|
||||
struct timeval echo_latency;
|
||||
|
||||
/* */
|
||||
unsigned short fragmentid;
|
||||
struct capwap_packet_rxmng* rxmngpacket;
|
||||
|
@ -6,6 +6,7 @@
|
||||
/* */
|
||||
static void wtp_dfa_state_dtlsconnect_timeout(EV_P_ ev_timer *w, int revents)
|
||||
{
|
||||
log_printf(LOG_DEBUG, "DTLS Connect Timeout");
|
||||
wtp_teardown_connection();
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,9 @@ static int send_echo_request(void)
|
||||
int result = -1;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
struct capwap_vendor_travelping_wtp_timestamp_element timestamp;
|
||||
|
||||
gettimeofday(×tamp.tv, NULL);
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, g_wtp.binding);
|
||||
@ -23,7 +26,9 @@ static int send_echo_request(void)
|
||||
g_wtp.localseqnumber, g_wtp.mtu);
|
||||
|
||||
/* Add message element */
|
||||
/* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket,
|
||||
CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP,
|
||||
×tamp);
|
||||
|
||||
/* Echo request complete, get fragment packets */
|
||||
wtp_free_reference_last_request();
|
||||
@ -47,18 +52,34 @@ static int send_echo_request(void)
|
||||
}
|
||||
|
||||
/* */
|
||||
static int receive_echo_response(struct capwap_parsed_packet* packet) {
|
||||
static int receive_echo_response(struct capwap_parsed_packet* packet)
|
||||
{
|
||||
struct capwap_resultcode_element* resultcode;
|
||||
struct capwap_vendor_travelping_wtp_timestamp_element *timestamp;
|
||||
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
/* Check the success of the Request */
|
||||
resultcode = (struct capwap_resultcode_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
resultcode = (struct capwap_resultcode_element *)
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_RESULTCODE);
|
||||
if (resultcode && !CAPWAP_RESULTCODE_OK(resultcode->code)) {
|
||||
log_printf(LOG_WARNING, "Receive Echo Response with error: %d", (int)resultcode->code);
|
||||
return 1;
|
||||
}
|
||||
|
||||
timestamp = (struct capwap_vendor_travelping_wtp_timestamp_element *)
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_VENDOR_TRAVELPING_WTP_TIMESTAMP);
|
||||
if (timestamp) {
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
timersub(&now, ×tamp->tv, &g_wtp.echo_latency);
|
||||
|
||||
log_printf(LOG_DEBUG, "Echo Latency: %ld.%03ld ms",
|
||||
g_wtp.echo_latency.tv_sec * 1000 + g_wtp.echo_latency.tv_usec / 1000,
|
||||
g_wtp.echo_latency.tv_usec % 1000);
|
||||
}
|
||||
|
||||
/* Valid packet, free request packet */
|
||||
wtp_free_reference_last_request();
|
||||
return 0;
|
||||
@ -221,7 +242,7 @@ static void receive_ieee80211_wlan_configuration_request(struct capwap_parsed_pa
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
|
||||
if (resultcode.code == CAPWAP_RESULTCODE_SUCCESS &&
|
||||
memcmp(&action, &CAPWAP_ELEMENT_80211_ADD_WLAN, sizeof(CAPWAP_ELEMENT_80211_ADD_WLAN)) == 0)
|
||||
message_element_id_eq(action, CAPWAP_ELEMENT_80211_ADD_WLAN))
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_ASSIGN_BSSID, &bssid);
|
||||
|
||||
/* CAPWAP_ELEMENT_VENDORPAYLOAD */ /* TODO */
|
||||
|
@ -438,7 +438,7 @@ int wtp_kmod_leave_mac80211_device(struct wifi_wlan* wlan) {
|
||||
}
|
||||
|
||||
/* */
|
||||
int wtp_kmod_add_station(uint8_t radioid, const uint8_t *mac, uint8_t wlanid)
|
||||
int wtp_kmod_add_station(uint8_t radioid, const uint8_t *mac, uint8_t wlanid, uint32_t flags)
|
||||
{
|
||||
int result;
|
||||
struct nl_msg* msg;
|
||||
@ -453,10 +453,12 @@ int wtp_kmod_add_station(uint8_t radioid, const uint8_t *mac, uint8_t wlanid)
|
||||
return -1;
|
||||
|
||||
/* */
|
||||
genlmsg_put(msg, 0, 0, g_wtp.kmodhandle.nlsmartcapwap_id, 0, 0, NLSMARTCAPWAP_CMD_ADD_STATION, 0);
|
||||
genlmsg_put(msg, 0, 0, g_wtp.kmodhandle.nlsmartcapwap_id, 0,
|
||||
NLM_F_CREATE | NLM_F_REPLACE, NLSMARTCAPWAP_CMD_ADD_STATION, 0);
|
||||
nla_put_u8(msg, NLSMARTCAPWAP_ATTR_RADIOID, radioid);
|
||||
nla_put(msg, NLSMARTCAPWAP_ATTR_MAC, ETH_ALEN, mac);
|
||||
nla_put_u8(msg, NLSMARTCAPWAP_ATTR_WLANID, wlanid);
|
||||
nla_put_u32(msg, NLSMARTCAPWAP_ATTR_FLAGS, wlanid);
|
||||
|
||||
/* */
|
||||
result = wtp_kmod_send_and_recv_msg(msg, NULL, NULL);
|
||||
|
@ -63,7 +63,10 @@ int wtp_kmod_join_mac80211_device(struct wifi_wlan* wlan, uint32_t flags);
|
||||
int wtp_kmod_leave_mac80211_device(struct wifi_wlan* wlan);
|
||||
|
||||
/* */
|
||||
int wtp_kmod_add_station(uint8_t radioid, const uint8_t *mac, uint8_t wlanid);
|
||||
#define STA_FLAG_AKM_ONLY 0x0001
|
||||
|
||||
/* */
|
||||
int wtp_kmod_add_station(uint8_t radioid, const uint8_t *mac, uint8_t wlanid, uint32_t flags);
|
||||
int wtp_kmod_del_station(uint8_t radioid, const uint8_t *mac);
|
||||
|
||||
#endif /* __WTP_KMOD_HEADER__ */
|
||||
|
@ -195,7 +195,7 @@ static void wtp_radio_setconfiguration_80211(struct capwap_parsed_packet *packet
|
||||
|
||||
/* Parsing only IEEE 802.11 message element */
|
||||
if (!IS_80211_MESSAGE_ELEMENTS(messageelement->id) &&
|
||||
memcmp(&messageelement->id, &CAPWAP_ELEMENT_80211N_RADIO_CONF, sizeof(messageelement->id)) != 0)
|
||||
!message_element_id_eq(messageelement->id, CAPWAP_ELEMENT_80211N_RADIO_CONF))
|
||||
continue;
|
||||
|
||||
ASSERT(messageelements != NULL);
|
||||
@ -255,7 +255,7 @@ static void wtp_radio_setconfiguration_80211(struct capwap_parsed_packet *packet
|
||||
|
||||
/* Parsing only IEEE 802.11 message element */
|
||||
if (!IS_80211_MESSAGE_ELEMENTS(messageelement->id) &&
|
||||
memcmp(&messageelement->id, &CAPWAP_ELEMENT_80211N_RADIO_CONF, sizeof(messageelement->id)) != 0)
|
||||
!message_element_id_eq(messageelement->id, CAPWAP_ELEMENT_80211N_RADIO_CONF))
|
||||
continue;
|
||||
|
||||
ASSERT(messageelements != NULL);
|
||||
@ -464,18 +464,22 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet)
|
||||
result = wifi_device_setfrequency(item->radio->devicehandle, WIFI_BAND_2GHZ,
|
||||
item->radio->radioinformation.radiotype,
|
||||
item->radio->directsequencecontrol.currentchannel);
|
||||
log_printf(LOG_DEBUG, "wtp_radio %d, set 2GHz frequency to %d, result: %d",
|
||||
item->radio->radioid, item->radio->directsequencecontrol.currentchannel,
|
||||
result);
|
||||
break;
|
||||
|
||||
case WTP_UPDATE_FREQUENCY_OFDM:
|
||||
result = wifi_device_setfrequency(item->radio->devicehandle, WIFI_BAND_5GHZ,
|
||||
item->radio->radioinformation.radiotype,
|
||||
item->radio->ofdmcontrol.currentchannel);
|
||||
log_printf(LOG_DEBUG, "wtp_radio %d, set 5GHz frequency to %d, result: %d",
|
||||
item->radio->radioid, item->radio->ofdmcontrol.currentchannel,
|
||||
result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #2: %d", result);
|
||||
|
||||
/* Update radio configuration */
|
||||
for (i = 0; (i < updateitems->count) && !result; i++) {
|
||||
struct wtp_update_configuration_item* item =
|
||||
@ -486,6 +490,8 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet)
|
||||
result = wifi_device_updaterates(item->radio->devicehandle,
|
||||
item->radio->rateset.rateset,
|
||||
item->radio->rateset.ratesetcount);
|
||||
log_printf(LOG_DEBUG, "wtp_radio %d, update rates result: %d",
|
||||
item->radio->radioid, result);
|
||||
break;
|
||||
|
||||
case WTP_UPDATE_CONFIGURATION: {
|
||||
@ -499,17 +505,21 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet)
|
||||
params.beaconperiod = item->radio->radioconfig.beaconperiod;
|
||||
memcpy(params.country, item->radio->radioconfig.country, WIFI_COUNTRY_LENGTH);
|
||||
result = wifi_device_setconfiguration(item->radio->devicehandle, ¶ms);
|
||||
|
||||
log_printf(LOG_DEBUG, "wtp_radio %d, set configuration result: %d",
|
||||
item->radio->radioid, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case WTP_UPDATE_TX_QUEUE:
|
||||
result = wifi_device_settxqueue(item->radio->devicehandle, &item->radio->qos);
|
||||
|
||||
log_printf(LOG_DEBUG, "wtp_radio %d, set Tx queue result: %d",
|
||||
item->radio->radioid, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log_printf(LOG_DEBUG, "wtp_radio_setconfiguration result #3: %d", result);
|
||||
|
||||
/* */
|
||||
capwap_array_free(updateitems);
|
||||
return result;
|
||||
@ -642,6 +652,16 @@ void wtp_radio_receive_data_packet(uint8_t radioid, unsigned short binding, cons
|
||||
}
|
||||
}
|
||||
|
||||
/* source http://stackoverflow.com/a/16994674 */
|
||||
static uint16_t reverse(register uint16_t x)
|
||||
{
|
||||
x = (((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1));
|
||||
x = (((x & 0xcccc) >> 2) | ((x & 0x3333) << 2));
|
||||
x = (((x & 0xf0f0) >> 4) | ((x & 0x0f0f) << 4));
|
||||
x = (((x & 0xff00) >> 8) | ((x & 0x00ff) << 8));
|
||||
return x;
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
|
||||
struct capwap_80211_assignbssid_element* bssid)
|
||||
@ -669,7 +689,7 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
|
||||
|
||||
/* Check if virtual interface is already exist */
|
||||
wlan = wtp_radio_get_wlan(radio, addwlan->wlanid);
|
||||
if (!wlan && !wlan->wlanhandle) {
|
||||
if (!wlan || !wlan->wlanhandle) {
|
||||
log_printf(LOG_DEBUG, "Create WLAN: invalid WLAN ID");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
@ -690,11 +710,16 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
|
||||
params.wlanid = addwlan->wlanid;
|
||||
params.ssid = (const char*)addwlan->ssid;
|
||||
params.ssid_hidden = addwlan->suppressssid;
|
||||
params.capability = addwlan->capability;
|
||||
params.capability = reverse(addwlan->capability);
|
||||
params.qos = addwlan->qos;
|
||||
params.authmode = addwlan->authmode;
|
||||
params.macmode = addwlan->macmode;
|
||||
params.tunnelmode = addwlan->tunnelmode;
|
||||
|
||||
params.keyindex = addwlan->keyindex;
|
||||
params.keylength = addwlan->keylength;
|
||||
params.key = addwlan->key;
|
||||
|
||||
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
/* Start AP */
|
||||
@ -715,8 +740,61 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
|
||||
}
|
||||
|
||||
/* */
|
||||
uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet) {
|
||||
/* TODO */
|
||||
uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet)
|
||||
{
|
||||
struct wtp_radio* radio;
|
||||
struct wtp_radio_wlan* wlan;
|
||||
struct wlan_updateap_params params;
|
||||
struct capwap_80211_updatewlan_element* updatewlan;
|
||||
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
/* Get message elements */
|
||||
updatewlan = (struct capwap_80211_updatewlan_element*)
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_UPDATE_WLAN);
|
||||
if (!updatewlan) {
|
||||
log_printf(LOG_DEBUG, "Update WLAN: no wlan");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Get physical radio */
|
||||
radio = wtp_radio_get_phy(updatewlan->radioid);
|
||||
if (!radio) {
|
||||
log_printf(LOG_DEBUG, "Update WLAN: no radio");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Check if virtual interface is already exist */
|
||||
wlan = wtp_radio_get_wlan(radio, updatewlan->wlanid);
|
||||
if (!wlan || !wlan->wlanhandle) {
|
||||
log_printf(LOG_DEBUG, "Update WLAN: invalid WLAN ID");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
if (!wlan->in_use) {
|
||||
log_printf(LOG_DEBUG, "Update WLAN: vif does not exists");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
/* Wlan Update Configuration */
|
||||
memset(¶ms, 0, sizeof(struct wlan_updateap_params));
|
||||
params.radioid = updatewlan->radioid;
|
||||
params.wlanid = updatewlan->wlanid;
|
||||
params.capability = reverse(updatewlan->capability);
|
||||
|
||||
params.keyindex = updatewlan->keyindex;
|
||||
params.keystatus = updatewlan->keystatus;
|
||||
params.keylength = updatewlan->keylength;
|
||||
params.key = updatewlan->key;
|
||||
|
||||
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
/* Update AP */
|
||||
if (wifi_wlan_updateap(wlan->wlanhandle, ¶ms)) {
|
||||
log_printf(LOG_DEBUG, "Update WLAN: update AP failed");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
return CAPWAP_RESULTCODE_SUCCESS;
|
||||
}
|
||||
|
||||
@ -731,11 +809,14 @@ uint32_t wtp_radio_add_station(struct capwap_parsed_packet* packet) {
|
||||
struct capwap_addstation_element* addstation;
|
||||
struct capwap_80211_station_element* station80211;
|
||||
struct capwap_80211n_station_info_element *station80211n;
|
||||
struct capwap_80211_stationkey_element *key;
|
||||
struct capwap_array *ie;
|
||||
struct wtp_radio* radio;
|
||||
struct wtp_radio_wlan* wlan;
|
||||
struct station_add_params stationparams;
|
||||
struct ieee80211_ht_cap ht_cap;
|
||||
int err;
|
||||
uint32_t flags = 0;
|
||||
int err, i;
|
||||
|
||||
/* Get message elements */
|
||||
addstation = (struct capwap_addstation_element*)
|
||||
@ -744,6 +825,10 @@ uint32_t wtp_radio_add_station(struct capwap_parsed_packet* packet) {
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_STATION);
|
||||
station80211n = (struct capwap_80211n_station_info_element *)
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211N_STATION_INFO);
|
||||
key = (struct capwap_80211_stationkey_element *)
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_STATION_SESSION_KEY_PROFILE);
|
||||
ie = (struct capwap_array *)
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
|
||||
|
||||
if (!station80211 || (addstation->radioid != station80211->radioid)) {
|
||||
log_printf(LOG_DEBUG, "add_station: error no station or wrong radio");
|
||||
@ -805,9 +890,56 @@ uint32_t wtp_radio_add_station(struct capwap_parsed_packet* packet) {
|
||||
memcpy(&ht_cap.mcs.rx_mask, station80211n->mcsset, sizeof(ht_cap.mcs.rx_mask));
|
||||
|
||||
stationparams.ht_cap = &ht_cap;
|
||||
stationparams.max_inactivity = g_wtp.sta_max_inactivity;
|
||||
}
|
||||
|
||||
err = wtp_kmod_add_station(addstation->radioid, station80211->address, station80211->wlanid);
|
||||
if (key) {
|
||||
if (memcmp(station80211->address, key->address,
|
||||
MACADDRESS_EUI48_LENGTH) != 0) {
|
||||
log_printf(LOG_DEBUG, "add_station: 802.11n Station Session Key MAC mismatch");
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
|
||||
log_printf(LOG_DEBUG, "add_station: key flags: %04x", key->flags);
|
||||
if (key->flags & 0x8000)
|
||||
flags |= STA_FLAG_AKM_ONLY;
|
||||
|
||||
stationparams.key = key;
|
||||
}
|
||||
|
||||
if (ie) {
|
||||
for (i = 0; i < ie->count; i++) {
|
||||
struct ieee80211_ie *rsn;
|
||||
uint8_t *data;
|
||||
|
||||
struct capwap_80211_ie_element *e =
|
||||
*(struct capwap_80211_ie_element **)capwap_array_get_item_pointer(ie, i);
|
||||
|
||||
if (e->radioid != station80211->radioid ||
|
||||
e->wlanid != station80211->wlanid ||
|
||||
e->ielength < 2)
|
||||
continue;
|
||||
|
||||
rsn = (struct ieee80211_ie *)e->ie;
|
||||
if (rsn->id != IEEE80211_IE_RSN_INFORMATION)
|
||||
continue;
|
||||
|
||||
data = (uint8_t *)(rsn + 1);
|
||||
data += 2; // RSN Version
|
||||
data += 4; // Group Chipher Suite
|
||||
if (*(uint16_t *)data != 1) {
|
||||
log_printf(LOG_DEBUG, "add_station: RSNE IE, wrong Pairwise Cipher Suite Count (%d)",
|
||||
*(uint16_t *)data);
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
}
|
||||
data +=2; // Pairwise Cipher Suiter Length
|
||||
stationparams.pairwise = ntohl(*(uint32_t *)data);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
err = wtp_kmod_add_station(addstation->radioid, station80211->address, station80211->wlanid, flags);
|
||||
if (err < 0) {
|
||||
log_printf(LOG_DEBUG, "add_station: CAPWAP add_station failed with: %d", err);
|
||||
return CAPWAP_RESULTCODE_FAILURE;
|
||||
|
Reference in New Issue
Block a user