Compare commits
12 Commits
Author | SHA1 | Date |
---|---|---|
Moritz Rosenthal | 8e34c700a6 | |
Andreas Schultz | cc55da831b | |
Tobias Hintze | 848b01e53c | |
Andreas Schultz | 890a2af6bb | |
Andreas Schultz | bf57c7a336 | |
Andreas Schultz | 2f2a287928 | |
Andreas Schultz | cd7024568f | |
Tobias Hintze | b6417ff793 | |
Tobias Hintze | 17c39e441a | |
Moritz Rosenthal | 7e8be72647 | |
Tobias Hintze | 9d0fe1cc76 | |
Andreas Schultz | 247a65c7d5 |
27
COPYING
27
COPYING
|
@ -1,35 +1,32 @@
|
|||
SmartCAPWAP -- An Open Source CAPWAP WTP / AC
|
||||
FreeWTP -- An Open Source CAPWAP WTP
|
||||
|
||||
Copyright (C) 2012-2014 Massimo Vellucci <vemax78@gmail.com>
|
||||
Portions (C) 2016 Travelping GmbH <info@travelping.com>
|
||||
|
||||
This distribution contains multiple components, some
|
||||
of which fall under different licenses. By using SmartCAPWAP
|
||||
of which fall under different licenses. By using FreeWTP
|
||||
or any of the bundled components enumerated below, you
|
||||
agree to be bound by the conditions of the license for
|
||||
each respective component.
|
||||
|
||||
SmartCAPWAP license:
|
||||
FreeWTP license:
|
||||
----------------
|
||||
|
||||
SmartCAPWAP is distributed under the GPL license version 2.
|
||||
FreeWTP is distributed under the GPL license version 2.
|
||||
|
||||
Libconfig license:
|
||||
------------
|
||||
|
||||
Libconfig is Copyright (C) Mark Lindner, and is licensed under the LGPL.
|
||||
|
||||
Libxml2 license:
|
||||
------------
|
||||
|
||||
Libxml2 is Copyright (C) Daniel Veillard, and is licensed under the MIT.
|
||||
|
||||
Libjson-c license:
|
||||
------------
|
||||
|
||||
Libjson-c is Copyright (C) Eric Haszlakiewicz, and is licensed under the MIT.
|
||||
|
||||
WolfSSL License:
|
||||
----------------
|
||||
|
||||
WolfSSL is Copyright (C) wolfSSL Inc, and is licensed under the GPL license version 2.
|
||||
WolfSSL is Copyright (C) wolfSSL Inc, and is licensed under the GPL license
|
||||
version 2.
|
||||
|
||||
libev license:
|
||||
--------------
|
||||
|
||||
libev is Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander
|
||||
Lehmann and is licensed under BSD 2-Clause license.
|
23
INSTALL
23
INSTALL
|
@ -1,12 +1,12 @@
|
|||
==================================================
|
||||
HOW TO BUILD AND RUN SmartCAPWAP FOR LINUX SYSTEMS
|
||||
==================================================
|
||||
==============================================
|
||||
HOW TO BUILD AND RUN FreeWTP FOR LINUX SYSTEMS
|
||||
==============================================
|
||||
|
||||
NOTE: To run WTP you must have a wireless card that has Linux driver based on the
|
||||
Generic IEEE 802.11 Networking Stack (mac80211).
|
||||
NOTE: To run WTP you must have a wireless card that has Linux driver based
|
||||
on the Generic IEEE 802.11 Networking Stack (mac80211).
|
||||
|
||||
|
||||
HOW TO BUILD AC AND WTP
|
||||
HOW TO BUILD THE WTP
|
||||
=======================
|
||||
|
||||
Requirements
|
||||
|
@ -15,22 +15,25 @@ Requirements
|
|||
* automake 1.9 or newer
|
||||
* autoconf
|
||||
* libconfig-dev
|
||||
* libjson0-dev
|
||||
* libnl-dev
|
||||
* libtool
|
||||
* libxml2-dev
|
||||
* libev 4.22 or newer
|
||||
* wolfssl 3.8 or newer
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
Linux Kernel:
|
||||
|
||||
Apply the appropriate path from kernel-patches to your kernel, enable
|
||||
CAPWAP WTP support and rebuild you kernel.
|
||||
|
||||
WolfSSL:
|
||||
./configure --enable-dtls --enable-psk --prefix=/usr/
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
SmartCAPWAP:
|
||||
FreeWTP:
|
||||
autoreconf -f -i
|
||||
./configure
|
||||
make
|
||||
|
|
9
NEWS.md
9
NEWS.md
|
@ -3,6 +3,15 @@ FreeWTP
|
|||
|
||||
Open Source CAPWAP WTP implementation
|
||||
|
||||
Version 1.4.1 - 15 Nov 2016
|
||||
---------------------------
|
||||
|
||||
* fix endianness buf in RSNE processing
|
||||
* command line fixes/enhances
|
||||
* updated kernel patches for plain upstream and OpenWRT/LEDE
|
||||
* remove some left over references to SmartCAPWAP
|
||||
* fix STA removal (make sure the DeAuthentication frame is sent)
|
||||
|
||||
Version 1.4.0 - 22 Aug 2016
|
||||
---------------------------
|
||||
|
||||
|
|
14
README.md
14
README.md
|
@ -6,8 +6,6 @@ This project started as a fork of SmartCAPWAP, but has since dropped the AC part
|
|||
|
||||
## STATUS
|
||||
|
||||
NOTE: The WTP implementation has been ported to libev
|
||||
|
||||
### WTP tested and working features:
|
||||
|
||||
* 802.11b
|
||||
|
@ -18,6 +16,7 @@ NOTE: The WTP implementation has been ported to libev
|
|||
* 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
|
||||
* WPA2 Enterprise
|
||||
|
||||
Only cards with cfg80211 netlink API are supported. The following devices
|
||||
have been tested:
|
||||
|
@ -27,7 +26,6 @@ have been tested:
|
|||
|
||||
### Planned WTP features:
|
||||
|
||||
* WPA2 Enterprise
|
||||
* 802.11r - BSS fast transition
|
||||
* Hybrid-MAC ([RFC-7494](https://tools.ietf.org/html/rfc7494))
|
||||
|
||||
|
@ -42,16 +40,18 @@ NOTE: To run WTP you must have a wireless card that has Linux driver based on th
|
|||
* automake 1.9 or newer
|
||||
* autoconf
|
||||
* libconfig-dev
|
||||
* libjson0-dev
|
||||
* libnl-dev
|
||||
* libev-dev
|
||||
* libtool
|
||||
* libxml2-dev
|
||||
* wolfssl 3.8 or newer
|
||||
|
||||
|
||||
### Build
|
||||
|
||||
Linux Kernel:
|
||||
|
||||
Apply the appropriate path from kernel-patches to your kernel, enable
|
||||
CAPWAP WTP support and rebuild you kernel.
|
||||
|
||||
WolfSSL:
|
||||
|
||||
./configure --enable-dtls --enable-ipv6 --enable-aesgcm \
|
||||
|
@ -71,7 +71,7 @@ FreeWTP:
|
|||
|
||||
### Debugging / Tracing
|
||||
|
||||
The smartcapwap kernel module defines a number of static ftrace events. For a detailed
|
||||
The wtp capwap 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:
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
# GPSACP message
|
||||
|
||||
GPSACP messages are defined in [WTP - SCG Reference Points](https://www.hochbahn.de/hochbahn/wcm/connect/de/1d8945fd-174c-447a-85a5-4a8424406b5a/Lieferung%2Bvon%2BWLAN%2BRoutern%2BAB%2B17.12.2016.pdf?MOD=AJPERES&CACHEID=ROOTWORKSPACE.Z18_JH8I1JC0L05M10AEB6TSP430A1-1d8945fd-174c-447a-85a5-4a8424406b5a-lLovXv0) can be sent within WTP Event Requests.
|
||||
|
||||
## Definition GPS Last Acquired Position
|
||||
The GPS Last Acquired Position contains the output of the AT$GPSACP command from an WWAN Modem.
|
||||
|
||||
### Format
|
||||
|
||||
```
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Timestamp |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| WWAN Id | GPSACP ....
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
```
|
||||
|
||||
**Vendor Id** 18681 (Travelping GmbH)
|
||||
|
||||
**Type** 15
|
||||
|
||||
**Length** >= 5
|
||||
|
||||
**Timestamp** The WTP’s time when the meassurment was recorded
|
||||
|
||||
**WWAN Id** WWAN Interface Id, used to differentiate between multiple WWAN interfaces, MUST be between
|
||||
one (1) and 16.
|
||||
|
||||
**GPSACP** The full output (including the starting $GPSACP) of the AT$GPSACP command the WWAN Interface:
|
||||
|
||||
```
|
||||
$GPSACP:<UTC>,<latitude>,<longitude>,<hdop>,<altitude>,<fix>,<cog>,<spkm>,<spkn>,<date>,<nsat>
|
||||
|
||||
<UTC>: HHMMSS
|
||||
HH: Hour of day (00..23)
|
||||
MM: Minute (00..59)
|
||||
SS: Second (00..60)
|
||||
<latitude>: ddmm.mmmmD
|
||||
dd: Degree (00..90)
|
||||
mm.mmmm: Minutes with decimal fraction (00.0000 .. 59.9999)
|
||||
D: Direction (N|S)
|
||||
<longitude>: dddmm.mmmmD
|
||||
dd: Degree (00..180)
|
||||
mm.mmmm: Minutes with decimal fraction (00.0000 .. 59.9999)
|
||||
D: Direction (W|E)
|
||||
<hdop>: xx.x
|
||||
xx.x: Horizontal dilution of precision in m (00.0..99.9)
|
||||
<altitude>: xxxx.x
|
||||
xxxx.x: Altitude above sea level in m (0000.0..9999.9) - Empty value for negative values.
|
||||
<fix>: x
|
||||
x: Fix status (0: No fix, 1: 2D, 2: 3D)
|
||||
<cog>: xxx.x
|
||||
xxx.x: Course over ground (000.0 .. 359.9)
|
||||
<spkm>: xxx.x
|
||||
xxx.x: Horizontal speed in km/h (000.0 .. 999.9)
|
||||
<spkn>: xxx.x
|
||||
xxx.x: Horizontal speed in knots (000.0 .. 999.9)
|
||||
<date>: ddmmyy
|
||||
dd: Day (01 .. 31)
|
||||
mm: Month (01 .. 12)
|
||||
yy: Year (00 .. 99)
|
||||
<nsat>: xx
|
||||
xx: Number of satallites in view (00 .. 99)
|
||||
```
|
90
etc/ac.conf
90
etc/ac.conf
|
@ -1,90 +0,0 @@
|
|||
# AC configuration file
|
||||
|
||||
version = "1.0";
|
||||
|
||||
application: {
|
||||
standalone = true;
|
||||
|
||||
name = "ac 1";
|
||||
|
||||
binding = [
|
||||
"802.11"
|
||||
];
|
||||
|
||||
descriptor: {
|
||||
maxstations = 20;
|
||||
maxwtp = 10;
|
||||
|
||||
security: {
|
||||
presharedkey = false;
|
||||
x509 = false;
|
||||
};
|
||||
|
||||
rmacfiled: {
|
||||
supported = false;
|
||||
};
|
||||
|
||||
dtlspolicy: {
|
||||
cleardatachannel = true;
|
||||
dtlsdatachannel = true;
|
||||
};
|
||||
|
||||
info = (
|
||||
{ idvendor = 12345; type = "hardware"; value = "1.0"; },
|
||||
{ idvendor = 33457; type = "software"; value = "2.0"; }
|
||||
);
|
||||
};
|
||||
|
||||
ecn = "limited";
|
||||
|
||||
timer: {
|
||||
discovery = 20;
|
||||
echorequest = 30;
|
||||
decrypterrorreport = 120;
|
||||
idletimeout = 320;
|
||||
};
|
||||
|
||||
wtpfallback = true;
|
||||
|
||||
dtls: {
|
||||
enable = true;
|
||||
|
||||
type = "x509";
|
||||
|
||||
presharedkey: {
|
||||
hint = "esempio";
|
||||
identity = "prova";
|
||||
pskkey = "123456";
|
||||
};
|
||||
|
||||
x509: {
|
||||
calist = "/etc/capwap/ca.crt";
|
||||
certificate = "/etc/capwap/ac.crt";
|
||||
privatekey = "/etc/capwap/ac.key";
|
||||
};
|
||||
};
|
||||
|
||||
network: {
|
||||
#binding = "eth1";
|
||||
#listen = "";
|
||||
transport = "udp";
|
||||
mtu = 1400;
|
||||
};
|
||||
};
|
||||
|
||||
backend: {
|
||||
id = "1";
|
||||
version = "1.0";
|
||||
server: (
|
||||
{ url = "http://127.0.0.1/csoap.php"; }
|
||||
#{ url = "https://127.0.0.1/csoap.php"; x509: { calist = "/etc/capwap/casoap.crt"; certificate = "/etc/capwap/clientsoap.crt"; privatekey = "/etc/capwap/clientsoap.key"; }; }
|
||||
);
|
||||
};
|
||||
|
||||
logging: {
|
||||
enable = true;
|
||||
level = "debug";
|
||||
output = (
|
||||
{ mode = "stdout"; }
|
||||
);
|
||||
};
|
76
etc/ac.crt
76
etc/ac.crt
|
@ -1,76 +0,0 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: C=IT, ST=IT, L=Rome, O=SmartCAPWAP, OU=SmartCAPWAP, CN=SmartCAPWAP CA/name=SmartCAPWAP/emailAddress=vemax78@gmail.com
|
||||
Validity
|
||||
Not Before: May 15 18:02:09 2014 GMT
|
||||
Not After : May 12 18:02:09 2024 GMT
|
||||
Subject: C=IT, ST=IT, L=Rome, O=SmartCAPWAP, OU=SmartCAPWAP, CN=ac1/name=SmartCAPWAP/emailAddress=vemax78@gmail.com
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:c3:98:2b:82:c3:1b:aa:13:8d:16:e4:d6:7f:c0:
|
||||
88:d9:f8:2a:52:46:92:be:c2:3d:91:04:07:7a:fb:
|
||||
c6:d1:3b:cc:8a:a0:c2:cd:25:b8:22:9c:11:c4:d5:
|
||||
ca:be:23:43:af:76:80:fd:65:bc:38:4b:66:1c:ac:
|
||||
05:b1:d2:a4:5b:57:ed:c9:62:e3:67:6e:83:37:c1:
|
||||
cc:38:a7:9b:0b:87:52:da:b1:83:7b:19:4d:99:48:
|
||||
96:c9:a3:6d:ad:93:8f:62:ee:f1:38:8a:81:99:0e:
|
||||
27:f6:70:ac:0e:93:06:3b:a4:b9:5c:6c:ed:ab:be:
|
||||
27:db:52:72:f5:7e:10:36:a5
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Cert Type:
|
||||
SSL Server
|
||||
Netscape Comment:
|
||||
Easy-RSA Generated Server Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
C6:FE:48:73:99:7A:9E:24:87:8B:43:F8:13:6F:27:FB:4A:71:4D:22
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:B8:BE:B2:CB:C6:68:BD:0A:BB:E5:BC:DE:AE:56:FE:25:E6:E4:B3:1C
|
||||
DirName:/C=IT/ST=IT/L=Rome/O=SmartCAPWAP/OU=SmartCAPWAP/CN=SmartCAPWAP CA/name=SmartCAPWAP/emailAddress=vemax78@gmail.com
|
||||
serial:9A:6A:C6:B2:AA:33:22:C5
|
||||
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication
|
||||
X509v3 Key Usage:
|
||||
Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
78:50:cf:ba:f0:b7:98:92:ae:e9:88:ce:10:43:79:22:03:bf:
|
||||
ad:9f:1b:87:26:00:37:c0:11:21:bd:9e:e9:40:92:1a:0b:50:
|
||||
a1:de:a5:00:df:8c:4b:5d:6d:09:75:6e:4e:f3:c2:4b:9e:6b:
|
||||
08:fe:d0:5c:27:98:fe:30:c9:96:a9:b5:2c:dc:ed:0b:c2:2d:
|
||||
3e:aa:b7:fd:54:be:17:5e:2f:35:5a:f1:8f:ae:49:3b:87:d5:
|
||||
99:8e:04:3a:e6:33:fd:30:4a:70:ac:34:c5:9c:0a:57:c6:ab:
|
||||
26:e7:98:bf:5d:ac:13:4a:6b:8e:e3:af:5e:e6:9b:e2:80:80:
|
||||
b9:ce
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEMjCCA5ugAwIBAgIBATANBgkqhkiG9w0BAQUFADCBpjELMAkGA1UEBhMCSVQx
|
||||
CzAJBgNVBAgTAklUMQ0wCwYDVQQHEwRSb21lMRQwEgYDVQQKEwtTbWFydENBUFdB
|
||||
UDEUMBIGA1UECxMLU21hcnRDQVBXQVAxFzAVBgNVBAMTDlNtYXJ0Q0FQV0FQIENB
|
||||
MRQwEgYDVQQpEwtTbWFydENBUFdBUDEgMB4GCSqGSIb3DQEJARYRdmVtYXg3OEBn
|
||||
bWFpbC5jb20wHhcNMTQwNTE1MTgwMjA5WhcNMjQwNTEyMTgwMjA5WjCBmzELMAkG
|
||||
A1UEBhMCSVQxCzAJBgNVBAgTAklUMQ0wCwYDVQQHEwRSb21lMRQwEgYDVQQKEwtT
|
||||
bWFydENBUFdBUDEUMBIGA1UECxMLU21hcnRDQVBXQVAxDDAKBgNVBAMTA2FjMTEU
|
||||
MBIGA1UEKRMLU21hcnRDQVBXQVAxIDAeBgkqhkiG9w0BCQEWEXZlbWF4NzhAZ21h
|
||||
aWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDmCuCwxuqE40W5NZ/
|
||||
wIjZ+CpSRpK+wj2RBAd6+8bRO8yKoMLNJbginBHE1cq+I0OvdoD9Zbw4S2YcrAWx
|
||||
0qRbV+3JYuNnboM3wcw4p5sLh1LasYN7GU2ZSJbJo22tk49i7vE4ioGZDif2cKwO
|
||||
kwY7pLlcbO2rvifbUnL1fhA2pQIDAQABo4IBdzCCAXMwCQYDVR0TBAIwADARBglg
|
||||
hkgBhvhCAQEEBAMCBkAwNAYJYIZIAYb4QgENBCcWJUVhc3ktUlNBIEdlbmVyYXRl
|
||||
ZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFMb+SHOZep4kh4tD+BNvJ/tK
|
||||
cU0iMIHbBgNVHSMEgdMwgdCAFLi+ssvGaL0Ku+W83q5W/iXm5LMcoYGspIGpMIGm
|
||||
MQswCQYDVQQGEwJJVDELMAkGA1UECBMCSVQxDTALBgNVBAcTBFJvbWUxFDASBgNV
|
||||
BAoTC1NtYXJ0Q0FQV0FQMRQwEgYDVQQLEwtTbWFydENBUFdBUDEXMBUGA1UEAxMO
|
||||
U21hcnRDQVBXQVAgQ0ExFDASBgNVBCkTC1NtYXJ0Q0FQV0FQMSAwHgYJKoZIhvcN
|
||||
AQkBFhF2ZW1heDc4QGdtYWlsLmNvbYIJAJpqxrKqMyLFMBMGA1UdJQQMMAoGCCsG
|
||||
AQUFBwMBMAsGA1UdDwQEAwIE8DANBgkqhkiG9w0BAQUFAAOBgQB4UM+68LeYkq7p
|
||||
iM4QQ3kiA7+tnxuHJgA3wBEhvZ7pQJIaC1Ch3qUA34xLXW0JdW5O88JLnmsI/tBc
|
||||
J5j+MMmWqbUs3O0Lwi0+qrf9VL4XXi81WvGPrkk7h9WZjgQ65jP9MEpwrDTFnApX
|
||||
xqsm55i/XawTSmuO469e5pvigIC5zg==
|
||||
-----END CERTIFICATE-----
|
16
etc/ac.key
16
etc/ac.key
|
@ -1,16 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMOYK4LDG6oTjRbk
|
||||
1n/AiNn4KlJGkr7CPZEEB3r7xtE7zIqgws0luCKcEcTVyr4jQ692gP1lvDhLZhys
|
||||
BbHSpFtX7cli42dugzfBzDinmwuHUtqxg3sZTZlIlsmjba2Tj2Lu8TiKgZkOJ/Zw
|
||||
rA6TBjukuVxs7au+J9tScvV+EDalAgMBAAECgYBh1N8OjKBttVHAvb08MQVCYQpq
|
||||
FLqZh3Zb7nP/Y6fSR+LLBBXrno43YXDRz02VRPY58UAbfqNiVPRCKxi+FOn3li5l
|
||||
LN9ad1S510MNg652vpKFnCQjpHDrxOQPxQHGc0XNeF4Xo12IhFxh0DbktloC3/Og
|
||||
PXL0UdvMhZ+X0ErQEQJBAOqLxRYeUSB9HeSFcgNejd0wkM7DKoNyFmJ0jwEb46vO
|
||||
mKJuA4CFbinX6PZfei8nXbZIBN5p3IS0TA7MU/b+erMCQQDVfEsfmEPUYx7M1oec
|
||||
rT4+AeSO7KzcC83zeVEmEljwP3zvbM8gn7PLsJAU3K0HEh6scocP6UosTI4o6Ohw
|
||||
ppVHAkEAsjCp9RnnTKWBlmIDsqedY9RHz63amK6ObxJaqt8DYz28HHs0UeoNPeD4
|
||||
7mSvMS/ZNGkWudr3XCKWPg/iIp5HnQJBAMALdtzuMZ5+qDdmiUn1QrevJjc4S2wL
|
||||
pnJu4QQZny5IPpB3VoCniasjowlRVsm0kClbQYqbt2DQYVYF5wtnn4MCQQCz7Rcj
|
||||
eEZN1STdLv6K03cWKW8nqk+yLgsDFOZpzhIq5ezk/oEX38+1k/KCqwy+9xlQ/oJJ
|
||||
5lGEUmKCh2XYCBcq
|
||||
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,685 @@
|
|||
From 681af1c29f8276c2105ff4ce8d31ec56bd9e5b7a 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 FreeWTP
|
||||
|
||||
Allows for kernel side interception and injection of IEEE 802.11 frames.
|
||||
---
|
||||
include/net/mac80211.h | 31 +++++
|
||||
net/mac80211/Kconfig | 7 ++
|
||||
net/mac80211/ieee80211_i.h | 12 ++
|
||||
net/mac80211/iface.c | 63 ++++++++++
|
||||
net/mac80211/rx.c | 92 +++++++++++++--
|
||||
net/mac80211/tx.c | 286 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 479 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
|
||||
index 760bc4d..e80b1af 100644
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -2199,6 +2199,37 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
|
||||
*/
|
||||
void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+extern struct static_key_false mac80211_capwap_wtp;
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+struct ieee80211_pcktunnel {
|
||||
+ u16 subtype_mask[3]; /* 0: MGMT, 1: CTLR, 2: DATA */
|
||||
+
|
||||
+ int (*handler)(u32 ifindex, struct sk_buff *skb, int sig_dbm, unsigned char rate, void *data);
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+int ieee80211_pcktunnel_register(struct net_device *dev, struct ieee80211_pcktunnel *handler);
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+int ieee80211_pcktunnel_deregister(struct net_device *dev, struct ieee80211_pcktunnel *handler);
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+netdev_tx_t ieee80211_inject_xmit(struct sk_buff* skb, struct net_device* dev);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* DOC: Hardware crypto acceleration
|
||||
*
|
||||
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
|
||||
index 3891cbd..4ff4461 100644
|
||||
--- a/net/mac80211/Kconfig
|
||||
+++ b/net/mac80211/Kconfig
|
||||
@@ -318,3 +318,10 @@ config MAC80211_STA_HASH_MAX_SIZE
|
||||
connect more stations than the number selected here.)
|
||||
|
||||
If unsure, leave the default of 0.
|
||||
+
|
||||
+config MAC80211_CAPWAP_WTP
|
||||
+ bool "Enable support functions for out-of-tree CAPWAP WTP module"
|
||||
+ depends on MAC80211
|
||||
+ ---help---
|
||||
+ Select this to build support hooks for out-of-tree CAPWAP FreeWTP
|
||||
+ module.
|
||||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
|
||||
index 6837a46..e96cbff 100644
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -180,6 +180,9 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
|
||||
#define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u)
|
||||
#define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
|
||||
#define RX_QUEUED ((__force ieee80211_rx_result) 3u)
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#define RX_IGNORE_MONITOR ((__force ieee80211_rx_result) 4u)
|
||||
+#endif
|
||||
|
||||
/**
|
||||
* enum ieee80211_packet_rx_flags - packet RX flags
|
||||
@@ -835,6 +838,11 @@ struct ieee80211_sub_if_data {
|
||||
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+ /* Packet tunnel handlers */
|
||||
+ struct ieee80211_pcktunnel __rcu *pcktunnel_handlers;
|
||||
+#endif
|
||||
+
|
||||
/* Fragment table for host-based reassembly */
|
||||
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
|
||||
unsigned int fragment_next;
|
||||
@@ -1632,6 +1640,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
u32 info_flags);
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+netdev_tx_t ieee80211_capwap_subif_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev);
|
||||
+#endif
|
||||
void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
|
||||
struct sk_buff_head *skbs);
|
||||
struct sk_buff *
|
||||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
|
||||
index bcb0a1b..cb08ec2 100644
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -1955,3 +1955,66 @@ void ieee80211_iface_exit(void)
|
||||
{
|
||||
unregister_netdevice_notifier(&mac80211_netdev_notifier);
|
||||
}
|
||||
+
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+DEFINE_STATIC_KEY_FALSE(mac80211_capwap_wtp);
|
||||
+
|
||||
+static const struct net_device_ops ieee80211_capwapif_ops = {
|
||||
+ .ndo_open = ieee80211_open,
|
||||
+ .ndo_stop = ieee80211_stop,
|
||||
+ .ndo_uninit = ieee80211_uninit,
|
||||
+ .ndo_start_xmit = ieee80211_capwap_subif_start_xmit,
|
||||
+ .ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
+ .ndo_change_mtu = ieee80211_change_mtu,
|
||||
+ .ndo_set_mac_address = ieee80211_change_mac,
|
||||
+ .ndo_select_queue = ieee80211_netdev_select_queue,
|
||||
+ .ndo_get_stats64 = ieee80211_get_stats64,
|
||||
+};
|
||||
+
|
||||
+int ieee80211_pcktunnel_register(struct net_device *dev, struct ieee80211_pcktunnel *handler)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ dev->netdev_ops = &ieee80211_capwapif_ops;
|
||||
+
|
||||
+ mutex_lock(&sdata->local->iflist_mtx);
|
||||
+
|
||||
+ if (rcu_dereference_protected(sdata->pcktunnel_handlers, lockdep_is_held(&sdata->local->iflist_mtx))) {
|
||||
+ ret = -EBUSY;
|
||||
+ } else {
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, handler);
|
||||
+ static_branch_enable(&mac80211_capwap_wtp);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&sdata->local->iflist_mtx);
|
||||
+ synchronize_net();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_pcktunnel_register);
|
||||
+
|
||||
+int ieee80211_pcktunnel_deregister(struct net_device *dev, struct ieee80211_pcktunnel *handler)
|
||||
+{
|
||||
+ int ret = -ENODEV;
|
||||
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+ struct ieee80211_pcktunnel *h;
|
||||
+
|
||||
+ mutex_lock(&sdata->local->iflist_mtx);
|
||||
+
|
||||
+ h = rcu_dereference_protected(sdata->pcktunnel_handlers, lockdep_is_held(&sdata->local->iflist_mtx));
|
||||
+ if (h == handler) {
|
||||
+ ret = 0;
|
||||
+ static_branch_disable(&mac80211_capwap_wtp);
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, NULL);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&sdata->local->iflist_mtx);
|
||||
+ synchronize_net();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_pcktunnel_deregister);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
|
||||
index a3bb8f7..07b2ff6 100644
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3058,6 +3058,56 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+static ieee80211_rx_result debug_noinline
|
||||
+ieee80211_rx_h_pcktunnel(struct ieee80211_rx_data *rx, struct ieee80211_rate *rate)
|
||||
+{
|
||||
+ struct ieee80211_pcktunnel *handler;
|
||||
+
|
||||
+ handler = rcu_dereference(rx->sdata->pcktunnel_handlers);
|
||||
+ if (handler) {
|
||||
+ u16 fc;
|
||||
+ u16 fc_type;
|
||||
+ int sig_dbm = 0;
|
||||
+ unsigned char pckrate = 0;
|
||||
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
|
||||
+
|
||||
+ if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM))
|
||||
+ sig_dbm = status->signal;
|
||||
+
|
||||
+ if (rate && !(status->flag & (RX_FLAG_HT | RX_FLAG_VHT))) {
|
||||
+ int shift = 0;
|
||||
+ if (status->flag & RX_FLAG_10MHZ)
|
||||
+ shift = 1;
|
||||
+ else if (status->flag & RX_FLAG_5MHZ)
|
||||
+ shift = 2;
|
||||
+ pckrate = DIV_ROUND_UP(rate->bitrate, 5 * (1 << shift));
|
||||
+ }
|
||||
+
|
||||
+ /* Retrieve type and subtype packet */
|
||||
+ fc = le16_to_cpu(hdr->frame_control);
|
||||
+ fc_type = ((fc & IEEE80211_FCTL_FTYPE) >> 2);
|
||||
+ if (fc_type < 3) {
|
||||
+ u16 bitmask = 1 << ((fc & IEEE80211_FCTL_STYPE) >> 4);
|
||||
+
|
||||
+ /* Delegate packet to external handler */
|
||||
+ if (handler->subtype_mask[fc_type] & bitmask) {
|
||||
+ if (handler->handler(rx->sdata->dev->ifindex, rx->skb, sig_dbm, pckrate, handler->data)) {
|
||||
+ return RX_IGNORE_MONITOR;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return RX_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+/* TODO: use IEEE80211_RX_FRAGMENTED */
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
||||
struct ieee80211_rate *rate)
|
||||
{
|
||||
@@ -3137,6 +3187,9 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
if (rx->sta)
|
||||
rx->sta->rx_stats.dropped++;
|
||||
/* fall through */
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+ case RX_IGNORE_MONITOR:
|
||||
+#endif
|
||||
case RX_CONTINUE: {
|
||||
struct ieee80211_rate *rate = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
@@ -3165,7 +3218,9 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
}
|
||||
|
||||
static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
- struct sk_buff_head *frames)
|
||||
+ struct sk_buff_head *frames,
|
||||
+ struct ieee80211_rate *rate)
|
||||
+
|
||||
{
|
||||
ieee80211_rx_result res = RX_DROP_MONITOR;
|
||||
struct sk_buff *skb;
|
||||
@@ -3204,6 +3259,15 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
if (ieee80211_vif_is_mesh(&rx->sdata->vif))
|
||||
CALL_RXH(ieee80211_rx_h_mesh_fwding);
|
||||
#endif
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+ if (static_branch_unlikely(&mac80211_capwap_wtp)) {
|
||||
+ /* special treatment */
|
||||
+ res = ieee80211_rx_h_pcktunnel(rx, rate);
|
||||
+ if (res != RX_CONTINUE)
|
||||
+ goto rxh_next;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
CALL_RXH(ieee80211_rx_h_amsdu)
|
||||
CALL_RXH(ieee80211_rx_h_data)
|
||||
|
||||
@@ -3227,7 +3291,8 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
spin_unlock_bh(&rx->local->rx_path_lock);
|
||||
}
|
||||
|
||||
-static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
|
||||
+static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
+ struct ieee80211_rate *rate)
|
||||
{
|
||||
struct sk_buff_head reorder_release;
|
||||
ieee80211_rx_result res = RX_DROP_MONITOR;
|
||||
@@ -3246,7 +3311,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
|
||||
|
||||
ieee80211_rx_reorder_ampdu(rx, &reorder_release);
|
||||
|
||||
- ieee80211_rx_handlers(rx, &reorder_release);
|
||||
+ ieee80211_rx_handlers(rx, &reorder_release, rate);
|
||||
return;
|
||||
|
||||
rxh_next:
|
||||
@@ -3292,7 +3357,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
|
||||
drv_event_callback(rx.local, rx.sdata, &event);
|
||||
}
|
||||
|
||||
- ieee80211_rx_handlers(&rx, &frames);
|
||||
+ ieee80211_rx_handlers(&rx, &frames, NULL);
|
||||
}
|
||||
|
||||
/* main receive path */
|
||||
@@ -3415,7 +3480,9 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
|
||||
* or not the skb was consumed.
|
||||
*/
|
||||
static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
- struct sk_buff *skb, bool consume)
|
||||
+ struct sk_buff *skb,
|
||||
+ struct ieee80211_rate *rate,
|
||||
+ bool consume)
|
||||
{
|
||||
struct ieee80211_local *local = rx->local;
|
||||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
@@ -3438,7 +3505,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
rx->skb = skb;
|
||||
}
|
||||
|
||||
- ieee80211_invoke_rx_handlers(rx);
|
||||
+ ieee80211_invoke_rx_handlers(rx, rate);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3448,7 +3515,8 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
*/
|
||||
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb,
|
||||
- struct napi_struct *napi)
|
||||
+ struct napi_struct *napi,
|
||||
+ struct ieee80211_rate *rate)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
@@ -3507,7 +3575,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
|
||||
rx.sta = prev_sta;
|
||||
rx.sdata = prev_sta->sdata;
|
||||
- ieee80211_prepare_and_rx_handle(&rx, skb, false);
|
||||
+ ieee80211_prepare_and_rx_handle(&rx, skb, rate, false);
|
||||
|
||||
prev_sta = sta;
|
||||
}
|
||||
@@ -3516,7 +3584,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
rx.sta = prev_sta;
|
||||
rx.sdata = prev_sta->sdata;
|
||||
|
||||
- if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
||||
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, rate, true))
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
@@ -3545,7 +3613,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
rx.sdata = prev;
|
||||
- ieee80211_prepare_and_rx_handle(&rx, skb, false);
|
||||
+ ieee80211_prepare_and_rx_handle(&rx, skb, rate, false);
|
||||
|
||||
prev = sdata;
|
||||
}
|
||||
@@ -3554,7 +3622,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
rx.sdata = prev;
|
||||
|
||||
- if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
||||
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, rate, true))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3666,7 +3734,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
ieee80211_tpt_led_trig_rx(local,
|
||||
((struct ieee80211_hdr *)skb->data)->frame_control,
|
||||
skb->len);
|
||||
- __ieee80211_rx_handle_packet(hw, skb, napi);
|
||||
+ __ieee80211_rx_handle_packet(hw, skb, napi, rate);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index bdc224d..ee4e7c7 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -2939,6 +2939,115 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+/*
|
||||
+ * inject raw 802.11 frame, processing is mostly identical
|
||||
+ * to ieee80211_monitor_start_xmit, except for the different
|
||||
+ * headers
|
||||
+ */
|
||||
+static void __ieee80211_capwap_inject_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||
+ 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 *sdata;
|
||||
+ struct cfg80211_chan_def *chandef;
|
||||
+ int tid;
|
||||
+ int hdrlen;
|
||||
+
|
||||
+ /* check for not even having the fixed 802.11 header */
|
||||
+ if (unlikely(skb->len < sizeof(struct ieee80211_hdr)))
|
||||
+ goto fail; /* too short to be possibly valid */
|
||||
+
|
||||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+
|
||||
+ /* does the skb contain enough to deliver on the alleged length? */
|
||||
+ if (unlikely(skb->len < hdrlen))
|
||||
+ goto fail; /* skb too short for claimed header length */
|
||||
+
|
||||
+ 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_set_network_header(skb, hdrlen);
|
||||
+ skb_set_transport_header(skb, hdrlen);
|
||||
+
|
||||
+ /*
|
||||
+ * Initialize skb->protocol if the injected frame is a data frame
|
||||
+ * carrying a rfc1042 header
|
||||
+ */
|
||||
+ if (ieee80211_is_data(hdr->frame_control) &&
|
||||
+ skb->len >= hdrlen + sizeof(rfc1042_header) + 2) {
|
||||
+ u8 *payload = (u8 *)hdr + hdrlen;
|
||||
+
|
||||
+ if (ether_addr_equal(payload, rfc1042_header))
|
||||
+ skb->protocol = cpu_to_be16((payload[6] << 8) |
|
||||
+ payload[7]);
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ * info->flags &= ~IEEE80211_TX_CTL_DONTFRAG;
|
||||
+ */
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
+ if (!chanctx_conf)
|
||||
+ goto fail_rcu;
|
||||
+
|
||||
+ info->band = chanctx_conf->def.chan->band;
|
||||
+
|
||||
+ ieee80211_tx_stats(dev, skb->len);
|
||||
+
|
||||
+ ieee80211_xmit(sdata, NULL, skb);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return;
|
||||
+fail_rcu:
|
||||
+ rcu_read_unlock();
|
||||
+fail:
|
||||
+ dev_kfree_skb(skb);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ieee80211_capwap_subif_start_xmit - netif start_xmit function for 802.3 vifs
|
||||
+ * @skb: packet to be sent
|
||||
+ * @dev: incoming interface
|
||||
+ *
|
||||
+ * On failure skb will be freed.
|
||||
+ */
|
||||
+netdev_tx_t ieee80211_capwap_subif_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ if (skb->protocol == htons(ETH_P_CONTROL)) {
|
||||
+ __ieee80211_capwap_inject_start_xmit(skb, dev);
|
||||
+ } else
|
||||
+ __ieee80211_subif_start_xmit(skb, dev, 0);
|
||||
+
|
||||
+ return NETDEV_TX_OK;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
struct sk_buff *
|
||||
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u32 info_flags)
|
||||
@@ -3914,3 +4023,180 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_xmit(sdata, NULL, skb);
|
||||
local_bh_enable();
|
||||
}
|
||||
+
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+netdev_tx_t ieee80211_inject_xmit(struct sk_buff* skb, struct net_device* dev) {
|
||||
+ int multicast;
|
||||
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ struct ieee80211_sub_if_data *sdata;
|
||||
+ struct cfg80211_chan_def *chandef;
|
||||
+ struct ieee80211_hdr *hdr;
|
||||
+ int hdrlen;
|
||||
+ int queue_index;
|
||||
+
|
||||
+ /* */
|
||||
+ if (skb->len < hdrlen) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* */
|
||||
+ skb->dev = dev;
|
||||
+ skb_reset_mac_header(skb);
|
||||
+ skb_reset_network_header(skb);
|
||||
+ skb_reset_transport_header(skb);
|
||||
+
|
||||
+ hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+
|
||||
+ if (skb->len < hdrlen) {
|
||||
+ printk(KERN_WARNING "dropping packet (too small)\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Initialize skb->protocol if the injected frame is a data frame
|
||||
+ * carrying a rfc1042 header
|
||||
+ */
|
||||
+ if (ieee80211_is_data(hdr->frame_control) &&
|
||||
+ skb->len >= hdrlen + sizeof(rfc1042_header) + 2) {
|
||||
+ u8 *payload = (u8 *)hdr + hdrlen;
|
||||
+
|
||||
+ if (ether_addr_equal(payload, rfc1042_header))
|
||||
+ skb->protocol = cpu_to_be16((payload[6] << 8) |
|
||||
+ payload[7]);
|
||||
+ }
|
||||
+
|
||||
+ memset(info, 0, sizeof(struct ieee80211_tx_info));
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_AP) {
|
||||
+ printk(KERN_WARNING "dropping packet (not AP)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
+ if (!chanctx_conf) {
|
||||
+ printk(KERN_WARNING "dropping packet (no chanCTX)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
+ chandef = &chanctx_conf->def;
|
||||
+
|
||||
+ queue_index = ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
+ skb_set_queue_mapping(skb, queue_index);
|
||||
+
|
||||
+ info->band = chandef->chan->band;
|
||||
+ info->hw_queue =
|
||||
+ sdata->vif.hw_queue[queue_index];
|
||||
+
|
||||
+ /*
|
||||
+ * 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)) {
|
||||
+ printk(KERN_WARNING "dropping packet (cannot BEACON)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ /* */
|
||||
+ multicast = is_multicast_ether_addr(hdr->addr1);
|
||||
+ if (!multicast) {
|
||||
+ struct sta_info* sta = sta_info_get(sdata, hdr->addr1);
|
||||
+ if (sta && test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
|
||||
+ skb->pkt_type = PACKET_OTHERHOST;
|
||||
+ } else {
|
||||
+ printk(KERN_WARNING "dropping packet (STA not authorized)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (ether_addr_equal_64bits(hdr->addr1, dev->broadcast)) {
|
||||
+ skb->pkt_type = PACKET_BROADCAST;
|
||||
+ } else {
|
||||
+ skb->pkt_type = PACKET_MULTICAST;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* */
|
||||
+ if (unlikely(!multicast && skb->sk &&
|
||||
+ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) {
|
||||
+ struct sk_buff *ack_skb = skb_clone_sk(skb);
|
||||
+
|
||||
+ if (ack_skb) {
|
||||
+ unsigned long flags;
|
||||
+ int id;
|
||||
+ struct ieee80211_local* local = sdata->local;
|
||||
+
|
||||
+ spin_lock_irqsave(&local->ack_status_lock, flags);
|
||||
+ id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
+ 1, 0x10000, GFP_ATOMIC);
|
||||
+ spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
||||
+
|
||||
+ if (id >= 0) {
|
||||
+ info->ack_frame_id = id;
|
||||
+ info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ } else {
|
||||
+ kfree_skb(ack_skb);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#if 0
|
||||
+ /* If the skb is shared we need to obtain our own copy. */
|
||||
+ if (skb_shared(skb)) {
|
||||
+ struct sk_buff *tmp_skb = skb;
|
||||
+
|
||||
+ /* can't happen -- skb is a clone if info_id != 0 */
|
||||
+ WARN_ON(info->ack_frame_id);
|
||||
+
|
||||
+ skb = skb_clone(skb, GFP_ATOMIC);
|
||||
+ kfree_skb(tmp_skb);
|
||||
+
|
||||
+ if (!skb)
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* */
|
||||
+ hdr->duration_id = 0;
|
||||
+ hdr->seq_ctrl = 0;
|
||||
+
|
||||
+ /* */
|
||||
+ ieee80211_tx_stats(dev, skb->len);
|
||||
+
|
||||
+ /* */
|
||||
+/* dev->trans_start = jiffies; */
|
||||
+
|
||||
+ /* */
|
||||
+ ieee80211_xmit(sdata, NULL, skb);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return NETDEV_TX_OK;
|
||||
+
|
||||
+error_rcu:
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+error:
|
||||
+ dev_kfree_skb(skb);
|
||||
+ return NETDEV_TX_OK;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_inject_xmit);
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,703 @@
|
|||
From c77fede6bca4d81c4db720a0ebcfa3ea6b933161 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 FreeWTP
|
||||
|
||||
Allows for kernel side interception and injection of IEEE 802.11 frames.
|
||||
---
|
||||
include/net/mac80211.h | 31 +++++
|
||||
net/mac80211/Kconfig | 7 ++
|
||||
net/mac80211/ieee80211_i.h | 12 ++
|
||||
net/mac80211/iface.c | 63 ++++++++++
|
||||
net/mac80211/rx.c | 96 ++++++++++++---
|
||||
net/mac80211/tx.c | 286 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 481 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
|
||||
index be30b05..cc1f0e8 100644
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -2309,6 +2309,37 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
|
||||
*/
|
||||
void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+extern struct static_key_false mac80211_capwap_wtp;
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+struct ieee80211_pcktunnel {
|
||||
+ u16 subtype_mask[3]; /* 0: MGMT, 1: CTLR, 2: DATA */
|
||||
+
|
||||
+ int (*handler)(u32 ifindex, struct sk_buff *skb, int sig_dbm, unsigned char rate, void *data);
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+int ieee80211_pcktunnel_register(struct net_device *dev, struct ieee80211_pcktunnel *handler);
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+int ieee80211_pcktunnel_deregister(struct net_device *dev, struct ieee80211_pcktunnel *handler);
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+netdev_tx_t ieee80211_inject_xmit(struct sk_buff* skb, struct net_device* dev);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* DOC: Hardware crypto acceleration
|
||||
*
|
||||
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
|
||||
index 3891cbd..4ff4461 100644
|
||||
--- a/net/mac80211/Kconfig
|
||||
+++ b/net/mac80211/Kconfig
|
||||
@@ -318,3 +318,10 @@ config MAC80211_STA_HASH_MAX_SIZE
|
||||
connect more stations than the number selected here.)
|
||||
|
||||
If unsure, leave the default of 0.
|
||||
+
|
||||
+config MAC80211_CAPWAP_WTP
|
||||
+ bool "Enable support functions for out-of-tree CAPWAP WTP module"
|
||||
+ depends on MAC80211
|
||||
+ ---help---
|
||||
+ Select this to build support hooks for out-of-tree CAPWAP FreeWTP
|
||||
+ module.
|
||||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
|
||||
index 9438c94..3ec4613 100644
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -180,6 +180,9 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
|
||||
#define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u)
|
||||
#define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
|
||||
#define RX_QUEUED ((__force ieee80211_rx_result) 3u)
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#define RX_IGNORE_MONITOR ((__force ieee80211_rx_result) 4u)
|
||||
+#endif
|
||||
|
||||
/**
|
||||
* enum ieee80211_packet_rx_flags - packet RX flags
|
||||
@@ -836,6 +839,11 @@ struct ieee80211_sub_if_data {
|
||||
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+ /* Packet tunnel handlers */
|
||||
+ struct ieee80211_pcktunnel __rcu *pcktunnel_handlers;
|
||||
+#endif
|
||||
+
|
||||
/* Fragment table for host-based reassembly */
|
||||
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
|
||||
unsigned int fragment_next;
|
||||
@@ -1655,6 +1663,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
u32 info_flags);
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+netdev_tx_t ieee80211_capwap_subif_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev);
|
||||
+#endif
|
||||
void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
|
||||
struct sk_buff_head *skbs);
|
||||
struct sk_buff *
|
||||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
|
||||
index c59af3e..c05f4c6 100644
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -1966,3 +1966,66 @@ void ieee80211_iface_exit(void)
|
||||
{
|
||||
unregister_netdevice_notifier(&mac80211_netdev_notifier);
|
||||
}
|
||||
+
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+DEFINE_STATIC_KEY_FALSE(mac80211_capwap_wtp);
|
||||
+
|
||||
+static const struct net_device_ops ieee80211_capwapif_ops = {
|
||||
+ .ndo_open = ieee80211_open,
|
||||
+ .ndo_stop = ieee80211_stop,
|
||||
+ .ndo_uninit = ieee80211_uninit,
|
||||
+ .ndo_start_xmit = ieee80211_capwap_subif_start_xmit,
|
||||
+ .ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
+ .ndo_change_mtu = ieee80211_change_mtu,
|
||||
+ .ndo_set_mac_address = ieee80211_change_mac,
|
||||
+ .ndo_select_queue = ieee80211_netdev_select_queue,
|
||||
+ .ndo_get_stats64 = ieee80211_get_stats64,
|
||||
+};
|
||||
+
|
||||
+int ieee80211_pcktunnel_register(struct net_device *dev, struct ieee80211_pcktunnel *handler)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ dev->netdev_ops = &ieee80211_capwapif_ops;
|
||||
+
|
||||
+ mutex_lock(&sdata->local->iflist_mtx);
|
||||
+
|
||||
+ if (rcu_dereference_protected(sdata->pcktunnel_handlers, lockdep_is_held(&sdata->local->iflist_mtx))) {
|
||||
+ ret = -EBUSY;
|
||||
+ } else {
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, handler);
|
||||
+ static_branch_enable(&mac80211_capwap_wtp);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&sdata->local->iflist_mtx);
|
||||
+ synchronize_net();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_pcktunnel_register);
|
||||
+
|
||||
+int ieee80211_pcktunnel_deregister(struct net_device *dev, struct ieee80211_pcktunnel *handler)
|
||||
+{
|
||||
+ int ret = -ENODEV;
|
||||
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+ struct ieee80211_pcktunnel *h;
|
||||
+
|
||||
+ mutex_lock(&sdata->local->iflist_mtx);
|
||||
+
|
||||
+ h = rcu_dereference_protected(sdata->pcktunnel_handlers, lockdep_is_held(&sdata->local->iflist_mtx));
|
||||
+ if (h == handler) {
|
||||
+ ret = 0;
|
||||
+ static_branch_disable(&mac80211_capwap_wtp);
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, NULL);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&sdata->local->iflist_mtx);
|
||||
+ synchronize_net();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_pcktunnel_deregister);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
|
||||
index 5e65e83..4a6d2cd 100644
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3097,6 +3097,56 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+static ieee80211_rx_result debug_noinline
|
||||
+ieee80211_rx_h_pcktunnel(struct ieee80211_rx_data *rx, struct ieee80211_rate *rate)
|
||||
+{
|
||||
+ struct ieee80211_pcktunnel *handler;
|
||||
+
|
||||
+ handler = rcu_dereference(rx->sdata->pcktunnel_handlers);
|
||||
+ if (handler) {
|
||||
+ u16 fc;
|
||||
+ u16 fc_type;
|
||||
+ int sig_dbm = 0;
|
||||
+ unsigned char pckrate = 0;
|
||||
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
|
||||
+
|
||||
+ if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM))
|
||||
+ sig_dbm = status->signal;
|
||||
+
|
||||
+ if (rate && !(status->flag & (RX_FLAG_HT | RX_FLAG_VHT))) {
|
||||
+ int shift = 0;
|
||||
+ if (status->flag & RX_FLAG_10MHZ)
|
||||
+ shift = 1;
|
||||
+ else if (status->flag & RX_FLAG_5MHZ)
|
||||
+ shift = 2;
|
||||
+ pckrate = DIV_ROUND_UP(rate->bitrate, 5 * (1 << shift));
|
||||
+ }
|
||||
+
|
||||
+ /* Retrieve type and subtype packet */
|
||||
+ fc = le16_to_cpu(hdr->frame_control);
|
||||
+ fc_type = ((fc & IEEE80211_FCTL_FTYPE) >> 2);
|
||||
+ if (fc_type < 3) {
|
||||
+ u16 bitmask = 1 << ((fc & IEEE80211_FCTL_STYPE) >> 4);
|
||||
+
|
||||
+ /* Delegate packet to external handler */
|
||||
+ if (handler->subtype_mask[fc_type] & bitmask) {
|
||||
+ if (handler->handler(rx->sdata->dev->ifindex, rx->skb, sig_dbm, pckrate, handler->data)) {
|
||||
+ return RX_IGNORE_MONITOR;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return RX_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+/* TODO: use IEEE80211_RX_FRAGMENTED */
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
||||
struct ieee80211_rate *rate)
|
||||
{
|
||||
@@ -3176,6 +3226,9 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
if (rx->sta)
|
||||
rx->sta->rx_stats.dropped++;
|
||||
/* fall through */
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+ case RX_IGNORE_MONITOR:
|
||||
+#endif
|
||||
case RX_CONTINUE: {
|
||||
struct ieee80211_rate *rate = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
@@ -3204,7 +3257,9 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
}
|
||||
|
||||
static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
- struct sk_buff_head *frames)
|
||||
+ struct sk_buff_head *frames,
|
||||
+ struct ieee80211_rate *rate)
|
||||
+
|
||||
{
|
||||
ieee80211_rx_result res = RX_DROP_MONITOR;
|
||||
struct sk_buff *skb;
|
||||
@@ -3243,6 +3298,15 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
if (ieee80211_vif_is_mesh(&rx->sdata->vif))
|
||||
CALL_RXH(ieee80211_rx_h_mesh_fwding);
|
||||
#endif
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+ if (static_branch_unlikely(&mac80211_capwap_wtp)) {
|
||||
+ /* special treatment */
|
||||
+ res = ieee80211_rx_h_pcktunnel(rx, rate);
|
||||
+ if (res != RX_CONTINUE)
|
||||
+ goto rxh_next;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
CALL_RXH(ieee80211_rx_h_amsdu);
|
||||
CALL_RXH(ieee80211_rx_h_data);
|
||||
|
||||
@@ -3266,7 +3330,8 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
spin_unlock_bh(&rx->local->rx_path_lock);
|
||||
}
|
||||
|
||||
-static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
|
||||
+static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
+ struct ieee80211_rate *rate)
|
||||
{
|
||||
struct sk_buff_head reorder_release;
|
||||
ieee80211_rx_result res = RX_DROP_MONITOR;
|
||||
@@ -3285,7 +3350,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
|
||||
|
||||
ieee80211_rx_reorder_ampdu(rx, &reorder_release);
|
||||
|
||||
- ieee80211_rx_handlers(rx, &reorder_release);
|
||||
+ ieee80211_rx_handlers(rx, &reorder_release, rate);
|
||||
return;
|
||||
|
||||
rxh_next:
|
||||
@@ -3331,7 +3396,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
|
||||
drv_event_callback(rx.local, rx.sdata, &event);
|
||||
}
|
||||
|
||||
- ieee80211_rx_handlers(&rx, &frames);
|
||||
+ ieee80211_rx_handlers(&rx, &frames, NULL);
|
||||
}
|
||||
|
||||
void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
|
||||
@@ -3406,7 +3471,7 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
|
||||
release:
|
||||
spin_unlock_bh(&tid_agg_rx->reorder_lock);
|
||||
|
||||
- ieee80211_rx_handlers(&rx, &frames);
|
||||
+ ieee80211_rx_handlers(&rx, &frames, NULL);
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
@@ -3878,7 +3943,9 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
* or not the skb was consumed.
|
||||
*/
|
||||
static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
- struct sk_buff *skb, bool consume)
|
||||
+ struct sk_buff *skb,
|
||||
+ struct ieee80211_rate *rate,
|
||||
+ bool consume)
|
||||
{
|
||||
struct ieee80211_local *local = rx->local;
|
||||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
@@ -3916,7 +3983,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
rx->skb = skb;
|
||||
}
|
||||
|
||||
- ieee80211_invoke_rx_handlers(rx);
|
||||
+ ieee80211_invoke_rx_handlers(rx, rate);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3927,7 +3994,8 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *pubsta,
|
||||
struct sk_buff *skb,
|
||||
- struct napi_struct *napi)
|
||||
+ struct napi_struct *napi,
|
||||
+ struct ieee80211_rate *rate)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
@@ -3973,7 +4041,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
if (pubsta) {
|
||||
rx.sta = container_of(pubsta, struct sta_info, sta);
|
||||
rx.sdata = rx.sta->sdata;
|
||||
- if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
||||
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, rate, true))
|
||||
return;
|
||||
goto out;
|
||||
} else if (ieee80211_is_data(fc)) {
|
||||
@@ -3992,7 +4060,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
|
||||
rx.sta = prev_sta;
|
||||
rx.sdata = prev_sta->sdata;
|
||||
- ieee80211_prepare_and_rx_handle(&rx, skb, false);
|
||||
+ ieee80211_prepare_and_rx_handle(&rx, skb, rate, false);
|
||||
|
||||
prev_sta = sta;
|
||||
}
|
||||
@@ -4001,7 +4069,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
rx.sta = prev_sta;
|
||||
rx.sdata = prev_sta->sdata;
|
||||
|
||||
- if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
||||
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, rate, true))
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
@@ -4030,7 +4098,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
rx.sdata = prev;
|
||||
- ieee80211_prepare_and_rx_handle(&rx, skb, false);
|
||||
+ ieee80211_prepare_and_rx_handle(&rx, skb, rate, false);
|
||||
|
||||
prev = sdata;
|
||||
}
|
||||
@@ -4039,7 +4107,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
rx.sdata = prev;
|
||||
|
||||
- if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
||||
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, rate, true))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4152,7 +4220,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
|
||||
((struct ieee80211_hdr *)skb->data)->frame_control,
|
||||
skb->len);
|
||||
|
||||
- __ieee80211_rx_handle_packet(hw, pubsta, skb, napi);
|
||||
+ __ieee80211_rx_handle_packet(hw, pubsta, skb, napi, rate);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index 2030443..bca96a4 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3213,6 +3213,115 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+/*
|
||||
+ * inject raw 802.11 frame, processing is mostly identical
|
||||
+ * to ieee80211_monitor_start_xmit, except for the different
|
||||
+ * headers
|
||||
+ */
|
||||
+static void __ieee80211_capwap_inject_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||
+ 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 *sdata;
|
||||
+ struct cfg80211_chan_def *chandef;
|
||||
+ int tid;
|
||||
+ int hdrlen;
|
||||
+
|
||||
+ /* check for not even having the fixed 802.11 header */
|
||||
+ if (unlikely(skb->len < sizeof(struct ieee80211_hdr)))
|
||||
+ goto fail; /* too short to be possibly valid */
|
||||
+
|
||||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+
|
||||
+ /* does the skb contain enough to deliver on the alleged length? */
|
||||
+ if (unlikely(skb->len < hdrlen))
|
||||
+ goto fail; /* skb too short for claimed header length */
|
||||
+
|
||||
+ 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_set_network_header(skb, hdrlen);
|
||||
+ skb_set_transport_header(skb, hdrlen);
|
||||
+
|
||||
+ /*
|
||||
+ * Initialize skb->protocol if the injected frame is a data frame
|
||||
+ * carrying a rfc1042 header
|
||||
+ */
|
||||
+ if (ieee80211_is_data(hdr->frame_control) &&
|
||||
+ skb->len >= hdrlen + sizeof(rfc1042_header) + 2) {
|
||||
+ u8 *payload = (u8 *)hdr + hdrlen;
|
||||
+
|
||||
+ if (ether_addr_equal(payload, rfc1042_header))
|
||||
+ skb->protocol = cpu_to_be16((payload[6] << 8) |
|
||||
+ payload[7]);
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ * info->flags &= ~IEEE80211_TX_CTL_DONTFRAG;
|
||||
+ */
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
+ if (!chanctx_conf)
|
||||
+ goto fail_rcu;
|
||||
+
|
||||
+ info->band = chanctx_conf->def.chan->band;
|
||||
+
|
||||
+ ieee80211_tx_stats(dev, skb->len);
|
||||
+
|
||||
+ ieee80211_xmit(sdata, NULL, skb);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return;
|
||||
+fail_rcu:
|
||||
+ rcu_read_unlock();
|
||||
+fail:
|
||||
+ dev_kfree_skb(skb);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ieee80211_capwap_subif_start_xmit - netif start_xmit function for 802.3 vifs
|
||||
+ * @skb: packet to be sent
|
||||
+ * @dev: incoming interface
|
||||
+ *
|
||||
+ * On failure skb will be freed.
|
||||
+ */
|
||||
+netdev_tx_t ieee80211_capwap_subif_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev)
|
||||
+{
|
||||
+ if (skb->protocol == htons(ETH_P_CONTROL)) {
|
||||
+ __ieee80211_capwap_inject_start_xmit(skb, dev);
|
||||
+ } else
|
||||
+ __ieee80211_subif_start_xmit(skb, dev, 0);
|
||||
+
|
||||
+ return NETDEV_TX_OK;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
struct sk_buff *
|
||||
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u32 info_flags)
|
||||
@@ -4188,3 +4297,180 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_xmit(sdata, NULL, skb);
|
||||
local_bh_enable();
|
||||
}
|
||||
+
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+netdev_tx_t ieee80211_inject_xmit(struct sk_buff* skb, struct net_device* dev) {
|
||||
+ int multicast;
|
||||
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||
+ struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ struct ieee80211_sub_if_data *sdata;
|
||||
+ struct cfg80211_chan_def *chandef;
|
||||
+ struct ieee80211_hdr *hdr;
|
||||
+ int hdrlen;
|
||||
+ int queue_index;
|
||||
+
|
||||
+ /* */
|
||||
+ if (skb->len < hdrlen) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* */
|
||||
+ skb->dev = dev;
|
||||
+ skb_reset_mac_header(skb);
|
||||
+ skb_reset_network_header(skb);
|
||||
+ skb_reset_transport_header(skb);
|
||||
+
|
||||
+ hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+
|
||||
+ if (skb->len < hdrlen) {
|
||||
+ printk(KERN_WARNING "dropping packet (too small)\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Initialize skb->protocol if the injected frame is a data frame
|
||||
+ * carrying a rfc1042 header
|
||||
+ */
|
||||
+ if (ieee80211_is_data(hdr->frame_control) &&
|
||||
+ skb->len >= hdrlen + sizeof(rfc1042_header) + 2) {
|
||||
+ u8 *payload = (u8 *)hdr + hdrlen;
|
||||
+
|
||||
+ if (ether_addr_equal(payload, rfc1042_header))
|
||||
+ skb->protocol = cpu_to_be16((payload[6] << 8) |
|
||||
+ payload[7]);
|
||||
+ }
|
||||
+
|
||||
+ memset(info, 0, sizeof(struct ieee80211_tx_info));
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_AP) {
|
||||
+ printk(KERN_WARNING "dropping packet (not AP)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
+ if (!chanctx_conf) {
|
||||
+ printk(KERN_WARNING "dropping packet (no chanCTX)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
+ chandef = &chanctx_conf->def;
|
||||
+
|
||||
+ queue_index = ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
+ skb_set_queue_mapping(skb, queue_index);
|
||||
+
|
||||
+ info->band = chandef->chan->band;
|
||||
+ info->hw_queue =
|
||||
+ sdata->vif.hw_queue[queue_index];
|
||||
+
|
||||
+ /*
|
||||
+ * 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)) {
|
||||
+ printk(KERN_WARNING "dropping packet (cannot BEACON)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ /* */
|
||||
+ multicast = is_multicast_ether_addr(hdr->addr1);
|
||||
+ if (!multicast) {
|
||||
+ struct sta_info* sta = sta_info_get(sdata, hdr->addr1);
|
||||
+ if (sta && test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
|
||||
+ skb->pkt_type = PACKET_OTHERHOST;
|
||||
+ } else {
|
||||
+ printk(KERN_WARNING "dropping packet (STA not authorized)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (ether_addr_equal_64bits(hdr->addr1, dev->broadcast)) {
|
||||
+ skb->pkt_type = PACKET_BROADCAST;
|
||||
+ } else {
|
||||
+ skb->pkt_type = PACKET_MULTICAST;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* */
|
||||
+ if (unlikely(!multicast && skb->sk &&
|
||||
+ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) {
|
||||
+ struct sk_buff *ack_skb = skb_clone_sk(skb);
|
||||
+
|
||||
+ if (ack_skb) {
|
||||
+ unsigned long flags;
|
||||
+ int id;
|
||||
+ struct ieee80211_local* local = sdata->local;
|
||||
+
|
||||
+ spin_lock_irqsave(&local->ack_status_lock, flags);
|
||||
+ id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
+ 1, 0x10000, GFP_ATOMIC);
|
||||
+ spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
||||
+
|
||||
+ if (id >= 0) {
|
||||
+ info->ack_frame_id = id;
|
||||
+ info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ } else {
|
||||
+ kfree_skb(ack_skb);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#if 0
|
||||
+ /* If the skb is shared we need to obtain our own copy. */
|
||||
+ if (skb_shared(skb)) {
|
||||
+ struct sk_buff *tmp_skb = skb;
|
||||
+
|
||||
+ /* can't happen -- skb is a clone if info_id != 0 */
|
||||
+ WARN_ON(info->ack_frame_id);
|
||||
+
|
||||
+ skb = skb_clone(skb, GFP_ATOMIC);
|
||||
+ kfree_skb(tmp_skb);
|
||||
+
|
||||
+ if (!skb)
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* */
|
||||
+ hdr->duration_id = 0;
|
||||
+ hdr->seq_ctrl = 0;
|
||||
+
|
||||
+ /* */
|
||||
+ ieee80211_tx_stats(dev, skb->len);
|
||||
+
|
||||
+ /* */
|
||||
+/* dev->trans_start = jiffies; */
|
||||
+
|
||||
+ /* */
|
||||
+ ieee80211_xmit(sdata, NULL, skb);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return NETDEV_TX_OK;
|
||||
+
|
||||
+error_rcu:
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+error:
|
||||
+ dev_kfree_skb(skb);
|
||||
+ return NETDEV_TX_OK;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_inject_xmit);
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -29,4 +29,4 @@ module_exit(smartcapwap_wtp_exit);
|
|||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Massimo Vellucci <vemax78@gmail.com>");
|
||||
MODULE_DESCRIPTION("SmartCAPWAP WTP Data Channel Module");
|
||||
MODULE_DESCRIPTION("FreeWTP CAPWAP Data Channel Module");
|
||||
|
|
|
@ -178,7 +178,7 @@ static struct sc_netlink_device* sc_netlink_new_device(struct net *net, uint32_t
|
|||
}
|
||||
|
||||
/* disable IPv6 on this iface */
|
||||
printk("SmartCAPWAP: disabling IPv6 on %s\n", dev->name);
|
||||
printk("CAPWAP: disabling IPv6 on %s\n", dev->name);
|
||||
idev->cnf.disable_ipv6 = 1;
|
||||
|
||||
/* Create device */
|
||||
|
@ -996,7 +996,7 @@ int __init sc_netlink_init(void) {
|
|||
if (ret)
|
||||
goto unreg_genl_family;
|
||||
|
||||
pr_info("smartCAPWAP module loaded\n");
|
||||
pr_info("CAPWAP WTP module loaded\n");
|
||||
return 0;
|
||||
|
||||
unreg_genl_family:
|
||||
|
@ -1006,7 +1006,7 @@ unreg_netdev_notifier:
|
|||
unreg_pernet:
|
||||
unregister_pernet_subsys(&sc_net_ops);
|
||||
error_out:
|
||||
pr_err("error loading smartCAPWAP module\n");
|
||||
pr_err("error loading CAPWAP WTP module\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ PKG_RELEASE:=1
|
|||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/travelping/freewtp.git
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=a631f89729604f77a4907e5597bf15dd916f1e33
|
||||
PKG_SOURCE_VERSION:=17c39e441ad7860acb211d08d8fb7eb60a84cb35
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
@ -63,6 +63,7 @@ endef
|
|||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/libnl3
|
||||
|
||||
define Build/Compile/wtp
|
||||
printf '#undef VERSION\n#define VERSION "'$(PKG_VERSION)'"\n' >> $(PKG_BUILD_DIR)/lib/config.h
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
all
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From abc84789bd6d42fdbfe598d72177ed41d54c7bcf Mon Sep 17 00:00:00 2001
|
||||
From 681af1c29f8276c2105ff4ce8d31ec56bd9e5b7a 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 FreeWTP
|
||||
|
@ -14,16 +14,16 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
6 files changed, 479 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
|
||||
index 760bc4d..bf60d9d 100644
|
||||
index 760bc4d..e80b1af 100644
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -2199,6 +2199,37 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
|
||||
*/
|
||||
void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+extern struct static_key mac80211_capwap_wtp;
|
||||
+extern struct static_key_false mac80211_capwap_wtp;
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
|
@ -78,7 +78,7 @@ index 6837a46..e96cbff 100644
|
|||
#define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u)
|
||||
#define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
|
||||
#define RX_QUEUED ((__force ieee80211_rx_result) 3u)
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+#define RX_IGNORE_MONITOR ((__force ieee80211_rx_result) 4u)
|
||||
+#endif
|
||||
|
||||
|
@ -88,7 +88,7 @@ index 6837a46..e96cbff 100644
|
|||
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+ /* Packet tunnel handlers */
|
||||
+ struct ieee80211_pcktunnel __rcu *pcktunnel_handlers;
|
||||
+#endif
|
||||
|
@ -100,7 +100,7 @@ index 6837a46..e96cbff 100644
|
|||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
u32 info_flags);
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+netdev_tx_t ieee80211_capwap_subif_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *dev);
|
||||
+#endif
|
||||
|
@ -108,7 +108,7 @@ index 6837a46..e96cbff 100644
|
|||
struct sk_buff_head *skbs);
|
||||
struct sk_buff *
|
||||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
|
||||
index bcb0a1b..8e2069f 100644
|
||||
index bcb0a1b..cb08ec2 100644
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -1955,3 +1955,66 @@ void ieee80211_iface_exit(void)
|
||||
|
@ -116,9 +116,9 @@ index bcb0a1b..8e2069f 100644
|
|||
unregister_netdevice_notifier(&mac80211_netdev_notifier);
|
||||
}
|
||||
+
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+struct static_key mac80211_capwap_wtp __read_mostly;
|
||||
+DEFINE_STATIC_KEY_FALSE(mac80211_capwap_wtp);
|
||||
+
|
||||
+static const struct net_device_ops ieee80211_capwapif_ops = {
|
||||
+ .ndo_open = ieee80211_open,
|
||||
|
@ -145,7 +145,7 @@ index bcb0a1b..8e2069f 100644
|
|||
+ ret = -EBUSY;
|
||||
+ } else {
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, handler);
|
||||
+ static_key_slow_inc(&mac80211_capwap_wtp);
|
||||
+ static_branch_enable(&mac80211_capwap_wtp);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&sdata->local->iflist_mtx);
|
||||
|
@ -166,7 +166,7 @@ index bcb0a1b..8e2069f 100644
|
|||
+ h = rcu_dereference_protected(sdata->pcktunnel_handlers, lockdep_is_held(&sdata->local->iflist_mtx));
|
||||
+ if (h == handler) {
|
||||
+ ret = 0;
|
||||
+ static_key_slow_dec(&mac80211_capwap_wtp);
|
||||
+ static_branch_disable(&mac80211_capwap_wtp);
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, NULL);
|
||||
+ }
|
||||
+
|
||||
|
@ -179,14 +179,14 @@ index bcb0a1b..8e2069f 100644
|
|||
+
|
||||
+#endif
|
||||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
|
||||
index a3bb8f7..cbe0642 100644
|
||||
index a3bb8f7..07b2ff6 100644
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3058,6 +3058,56 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+static ieee80211_rx_result debug_noinline
|
||||
+ieee80211_rx_h_pcktunnel(struct ieee80211_rx_data *rx, struct ieee80211_rate *rate)
|
||||
|
@ -243,7 +243,7 @@ index a3bb8f7..cbe0642 100644
|
|||
if (rx->sta)
|
||||
rx->sta->rx_stats.dropped++;
|
||||
/* fall through */
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+ case RX_IGNORE_MONITOR:
|
||||
+#endif
|
||||
case RX_CONTINUE: {
|
||||
|
@ -264,8 +264,8 @@ index a3bb8f7..cbe0642 100644
|
|||
if (ieee80211_vif_is_mesh(&rx->sdata->vif))
|
||||
CALL_RXH(ieee80211_rx_h_mesh_fwding);
|
||||
#endif
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+ if (static_key_false(&mac80211_capwap_wtp)) {
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+ if (static_branch_unlikely(&mac80211_capwap_wtp)) {
|
||||
+ /* special treatment */
|
||||
+ res = ieee80211_rx_h_pcktunnel(rx, rate);
|
||||
+ if (res != RX_CONTINUE)
|
||||
|
@ -380,14 +380,14 @@ index a3bb8f7..cbe0642 100644
|
|||
rcu_read_unlock();
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index bdc224d..5f1f424 100644
|
||||
index bdc224d..ee4e7c7 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -2939,6 +2939,115 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+/*
|
||||
+ * inject raw 802.11 frame, processing is mostly identical
|
||||
|
@ -504,7 +504,7 @@ index bdc224d..5f1f424 100644
|
|||
local_bh_enable();
|
||||
}
|
||||
+
|
||||
+#ifdef CONFIG_MAC80211_CAPWAP_WTP
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+netdev_tx_t ieee80211_inject_xmit(struct sk_buff* skb, struct net_device* dev) {
|
||||
+ int multicast;
|
||||
|
@ -532,7 +532,7 @@ index bdc224d..5f1f424 100644
|
|||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+
|
||||
+ if (skb->len < hdrlen) {
|
||||
+ printk(KERN_WARNING, "droping packet for TO SMALL");
|
||||
+ printk(KERN_WARNING "dropping packet (too small)\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
|
@ -556,13 +556,13 @@ index bdc224d..5f1f424 100644
|
|||
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_AP) {
|
||||
+ printk(KERN_WARNING, "droping packet for NOT AP");
|
||||
+ printk(KERN_WARNING "dropping packet (not AP)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
+ if (!chanctx_conf) {
|
||||
+ printk(KERN_WARNING, "droping packet for NO CHANTX");
|
||||
+ printk(KERN_WARNING "dropping packet (no chanCTX)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
|
@ -593,7 +593,7 @@ index bdc224d..5f1f424 100644
|
|||
+ */
|
||||
+ if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
|
||||
+ sdata->vif.type)) {
|
||||
+ printk(KERN_WARNING, "droping packet for CAN NOT BEACON");
|
||||
+ printk(KERN_WARNING "dropping packet (cannot BEACON)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ /* */
|
||||
|
@ -603,7 +603,7 @@ index bdc224d..5f1f424 100644
|
|||
+ if (sta && test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
|
||||
+ skb->pkt_type = PACKET_OTHERHOST;
|
||||
+ } else {
|
||||
+ printk(KERN_WARNING, "droping packet for STA not AUTHORIZED");
|
||||
+ printk(KERN_WARNING "dropping packet (STA not authorized)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ } else {
|
||||
|
@ -683,3 +683,13 @@ index bdc224d..5f1f424 100644
|
|||
--
|
||||
2.9.3
|
||||
|
||||
--- a/.local-symbols
|
||||
+++ b/.local-symbols
|
||||
@@ -42,6 +42,7 @@ LIB80211_CRYPT_CCMP=
|
||||
LIB80211_CRYPT_TKIP=
|
||||
LIB80211_DEBUG=
|
||||
MAC80211=
|
||||
+MAC80211_CAPWAP_WTP=
|
||||
MAC80211_HAS_RC=
|
||||
MAC80211_RC_MINSTREL=
|
||||
MAC80211_RC_MINSTREL_HT=
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 0829e230256d8f18c2d482923d16d3582311221f Mon Sep 17 00:00:00 2001
|
||||
From c77fede6bca4d81c4db720a0ebcfa3ea6b933161 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 FreeWTP
|
||||
|
@ -13,15 +13,17 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
net/mac80211/tx.c | 286 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 481 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
|
||||
index be30b05..cc1f0e8 100644
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -2323,6 +2323,37 @@ ieee80211_get_alt_retry_rate(const struc
|
||||
@@ -2309,6 +2309,37 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
|
||||
*/
|
||||
void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+extern struct static_key mac80211_capwap_wtp;
|
||||
+extern struct static_key_false mac80211_capwap_wtp;
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
|
@ -53,9 +55,11 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
/**
|
||||
* DOC: Hardware crypto acceleration
|
||||
*
|
||||
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
|
||||
index 3891cbd..4ff4461 100644
|
||||
--- a/net/mac80211/Kconfig
|
||||
+++ b/net/mac80211/Kconfig
|
||||
@@ -317,3 +317,10 @@ config MAC80211_STA_HASH_MAX_SIZE
|
||||
@@ -318,3 +318,10 @@ config MAC80211_STA_HASH_MAX_SIZE
|
||||
connect more stations than the number selected here.)
|
||||
|
||||
If unsure, leave the default of 0.
|
||||
|
@ -66,9 +70,11 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+ ---help---
|
||||
+ Select this to build support hooks for out-of-tree CAPWAP FreeWTP
|
||||
+ module.
|
||||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
|
||||
index 9438c94..3ec4613 100644
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -182,6 +182,9 @@ typedef unsigned __bitwise__ ieee80211_r
|
||||
@@ -180,6 +180,9 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
|
||||
#define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u)
|
||||
#define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
|
||||
#define RX_QUEUED ((__force ieee80211_rx_result) 3u)
|
||||
|
@ -78,7 +84,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
|
||||
/**
|
||||
* enum ieee80211_packet_rx_flags - packet RX flags
|
||||
@@ -847,6 +850,11 @@ struct ieee80211_sub_if_data {
|
||||
@@ -836,6 +839,11 @@ struct ieee80211_sub_if_data {
|
||||
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
|
@ -90,7 +96,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
/* Fragment table for host-based reassembly */
|
||||
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
|
||||
unsigned int fragment_next;
|
||||
@@ -1696,6 +1704,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s
|
||||
@@ -1655,6 +1663,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
u32 info_flags);
|
||||
|
@ -101,16 +107,18 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
|
||||
struct sk_buff_head *skbs);
|
||||
struct sk_buff *
|
||||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
|
||||
index c59af3e..c05f4c6 100644
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -2001,3 +2001,66 @@ void ieee80211_iface_exit(void)
|
||||
@@ -1966,3 +1966,66 @@ void ieee80211_iface_exit(void)
|
||||
{
|
||||
unregister_netdevice_notifier(&mac80211_netdev_notifier);
|
||||
}
|
||||
+
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+
|
||||
+struct static_key mac80211_capwap_wtp __read_mostly;
|
||||
+DEFINE_STATIC_KEY_FALSE(mac80211_capwap_wtp);
|
||||
+
|
||||
+static const struct net_device_ops ieee80211_capwapif_ops = {
|
||||
+ .ndo_open = ieee80211_open,
|
||||
|
@ -137,7 +145,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+ ret = -EBUSY;
|
||||
+ } else {
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, handler);
|
||||
+ static_key_slow_inc(&mac80211_capwap_wtp);
|
||||
+ static_branch_enable(&mac80211_capwap_wtp);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&sdata->local->iflist_mtx);
|
||||
|
@ -158,7 +166,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+ h = rcu_dereference_protected(sdata->pcktunnel_handlers, lockdep_is_held(&sdata->local->iflist_mtx));
|
||||
+ if (h == handler) {
|
||||
+ ret = 0;
|
||||
+ static_key_slow_dec(&mac80211_capwap_wtp);
|
||||
+ static_branch_disable(&mac80211_capwap_wtp);
|
||||
+ rcu_assign_pointer(sdata->pcktunnel_handlers, NULL);
|
||||
+ }
|
||||
+
|
||||
|
@ -170,9 +178,11 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+EXPORT_SYMBOL(ieee80211_pcktunnel_deregister);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
|
||||
index 5e65e83..4a6d2cd 100644
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3097,6 +3097,56 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
|
||||
@@ -3097,6 +3097,56 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
||||
|
@ -229,7 +239,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
||||
struct ieee80211_rate *rate)
|
||||
{
|
||||
@@ -3176,6 +3226,9 @@ static void ieee80211_rx_handlers_result
|
||||
@@ -3176,6 +3226,9 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
if (rx->sta)
|
||||
rx->sta->rx_stats.dropped++;
|
||||
/* fall through */
|
||||
|
@ -239,7 +249,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
case RX_CONTINUE: {
|
||||
struct ieee80211_rate *rate = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
@@ -3204,7 +3257,9 @@ static void ieee80211_rx_handlers_result
|
||||
@@ -3204,7 +3257,9 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
}
|
||||
|
||||
static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
|
@ -250,12 +260,12 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
{
|
||||
ieee80211_rx_result res = RX_DROP_MONITOR;
|
||||
struct sk_buff *skb;
|
||||
@@ -3243,6 +3298,15 @@ static void ieee80211_rx_handlers(struct
|
||||
@@ -3243,6 +3298,15 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
if (ieee80211_vif_is_mesh(&rx->sdata->vif))
|
||||
CALL_RXH(ieee80211_rx_h_mesh_fwding);
|
||||
#endif
|
||||
+#ifdef CPTCFG_MAC80211_CAPWAP_WTP
|
||||
+ if (static_key_false(&mac80211_capwap_wtp)) {
|
||||
+ if (static_branch_unlikely(&mac80211_capwap_wtp)) {
|
||||
+ /* special treatment */
|
||||
+ res = ieee80211_rx_h_pcktunnel(rx, rate);
|
||||
+ if (res != RX_CONTINUE)
|
||||
|
@ -266,7 +276,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
CALL_RXH(ieee80211_rx_h_amsdu);
|
||||
CALL_RXH(ieee80211_rx_h_data);
|
||||
|
||||
@@ -3266,7 +3330,8 @@ static void ieee80211_rx_handlers(struct
|
||||
@@ -3266,7 +3330,8 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
spin_unlock_bh(&rx->local->rx_path_lock);
|
||||
}
|
||||
|
||||
|
@ -276,7 +286,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
{
|
||||
struct sk_buff_head reorder_release;
|
||||
ieee80211_rx_result res = RX_DROP_MONITOR;
|
||||
@@ -3285,7 +3350,7 @@ static void ieee80211_invoke_rx_handlers
|
||||
@@ -3285,7 +3350,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
|
||||
|
||||
ieee80211_rx_reorder_ampdu(rx, &reorder_release);
|
||||
|
||||
|
@ -285,7 +295,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
return;
|
||||
|
||||
rxh_next:
|
||||
@@ -3331,7 +3396,7 @@ void ieee80211_release_reorder_timeout(s
|
||||
@@ -3331,7 +3396,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
|
||||
drv_event_callback(rx.local, rx.sdata, &event);
|
||||
}
|
||||
|
||||
|
@ -294,7 +304,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
}
|
||||
|
||||
void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
|
||||
@@ -3406,7 +3471,7 @@ void ieee80211_mark_rx_ba_filtered_frame
|
||||
@@ -3406,7 +3471,7 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
|
||||
release:
|
||||
spin_unlock_bh(&tid_agg_rx->reorder_lock);
|
||||
|
||||
|
@ -303,7 +313,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
@@ -3878,7 +3943,9 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
@@ -3878,7 +3943,9 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
* or not the skb was consumed.
|
||||
*/
|
||||
static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
|
@ -314,7 +324,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
{
|
||||
struct ieee80211_local *local = rx->local;
|
||||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
@@ -3916,7 +3983,7 @@ static bool ieee80211_prepare_and_rx_han
|
||||
@@ -3916,7 +3983,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
rx->skb = skb;
|
||||
}
|
||||
|
||||
|
@ -323,7 +333,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
return true;
|
||||
}
|
||||
|
||||
@@ -3927,7 +3994,8 @@ static bool ieee80211_prepare_and_rx_han
|
||||
@@ -3927,7 +3994,8 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
||||
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *pubsta,
|
||||
struct sk_buff *skb,
|
||||
|
@ -333,7 +343,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
@@ -3973,7 +4041,7 @@ static void __ieee80211_rx_handle_packet
|
||||
@@ -3973,7 +4041,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
if (pubsta) {
|
||||
rx.sta = container_of(pubsta, struct sta_info, sta);
|
||||
rx.sdata = rx.sta->sdata;
|
||||
|
@ -342,7 +352,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
return;
|
||||
goto out;
|
||||
} else if (ieee80211_is_data(fc)) {
|
||||
@@ -3992,7 +4060,7 @@ static void __ieee80211_rx_handle_packet
|
||||
@@ -3992,7 +4060,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
|
||||
rx.sta = prev_sta;
|
||||
rx.sdata = prev_sta->sdata;
|
||||
|
@ -351,7 +361,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
|
||||
prev_sta = sta;
|
||||
}
|
||||
@@ -4001,7 +4069,7 @@ static void __ieee80211_rx_handle_packet
|
||||
@@ -4001,7 +4069,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
rx.sta = prev_sta;
|
||||
rx.sdata = prev_sta->sdata;
|
||||
|
||||
|
@ -360,7 +370,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
return;
|
||||
goto out;
|
||||
}
|
||||
@@ -4030,7 +4098,7 @@ static void __ieee80211_rx_handle_packet
|
||||
@@ -4030,7 +4098,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
rx.sdata = prev;
|
||||
|
@ -369,7 +379,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
|
||||
prev = sdata;
|
||||
}
|
||||
@@ -4039,7 +4107,7 @@ static void __ieee80211_rx_handle_packet
|
||||
@@ -4039,7 +4107,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
rx.sdata = prev;
|
||||
|
||||
|
@ -378,7 +388,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
return;
|
||||
}
|
||||
|
||||
@@ -4152,7 +4220,7 @@ void ieee80211_rx_napi(struct ieee80211_
|
||||
@@ -4152,7 +4220,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
|
||||
((struct ieee80211_hdr *)skb->data)->frame_control,
|
||||
skb->len);
|
||||
|
||||
|
@ -387,9 +397,11 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
|
||||
rcu_read_unlock();
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index 2030443..bca96a4 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3434,6 +3434,115 @@ netdev_tx_t ieee80211_subif_start_xmit(s
|
||||
@@ -3213,6 +3213,115 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -505,7 +517,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
struct sk_buff *
|
||||
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u32 info_flags)
|
||||
@@ -4409,3 +4518,180 @@ void __ieee80211_tx_skb_tid_band(struct
|
||||
@@ -4188,3 +4297,180 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_xmit(sdata, NULL, skb);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
@ -538,7 +550,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+
|
||||
+ if (skb->len < hdrlen) {
|
||||
+ printk(KERN_WARNING, "droping packet for TO SMALL");
|
||||
+ printk(KERN_WARNING "dropping packet (too small)\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
|
@ -562,13 +574,13 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_AP) {
|
||||
+ printk(KERN_WARNING, "droping packet for NOT AP");
|
||||
+ printk(KERN_WARNING "dropping packet (not AP)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
+ if (!chanctx_conf) {
|
||||
+ printk(KERN_WARNING, "droping packet for NO CHANTX");
|
||||
+ printk(KERN_WARNING "dropping packet (no chanCTX)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+
|
||||
|
@ -599,7 +611,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+ */
|
||||
+ if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
|
||||
+ sdata->vif.type)) {
|
||||
+ printk(KERN_WARNING, "droping packet for CAN NOT BEACON");
|
||||
+ printk(KERN_WARNING "dropping packet (cannot BEACON)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ /* */
|
||||
|
@ -609,7 +621,7 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+ if (sta && test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
|
||||
+ skb->pkt_type = PACKET_OTHERHOST;
|
||||
+ } else {
|
||||
+ printk(KERN_WARNING, "droping packet for STA not AUTHORIZED");
|
||||
+ printk(KERN_WARNING "dropping packet (STA not authorized)\n");
|
||||
+ goto error_rcu;
|
||||
+ }
|
||||
+ } else {
|
||||
|
@ -686,6 +698,9 @@ Allows for kernel side interception and injection of IEEE 802.11 frames.
|
|||
+EXPORT_SYMBOL(ieee80211_inject_xmit);
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.9.3
|
||||
|
||||
--- a/.local-symbols
|
||||
+++ b/.local-symbols
|
||||
@@ -42,6 +42,7 @@ LIB80211_CRYPT_CCMP=
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# The OpenWRT patches are for the mac80211 package. They are functional
|
||||
# indentical to the kernel patches but need two modifications.
|
||||
#
|
||||
# 1. CONFIG_ needs to be replaced with CPTCFG_
|
||||
# 2. any new configuration option, need to be patched into .local-symbols
|
||||
#
|
||||
# This script takes the pure kernel patches and make the above modifications.
|
||||
#
|
||||
|
||||
DIR=$(dirname $0)
|
||||
|
||||
rebuild() {
|
||||
sed -e"s|CONFIG_|CPTCFG_|g" $DIR/../../kernel-patches/$1 > $DIR/922-$1
|
||||
cat >> $DIR/922-$1 <<EOF
|
||||
--- a/.local-symbols
|
||||
+++ b/.local-symbols
|
||||
@@ -42,6 +42,7 @@ LIB80211_CRYPT_CCMP=
|
||||
LIB80211_CRYPT_TKIP=
|
||||
LIB80211_DEBUG=
|
||||
MAC80211=
|
||||
+MAC80211_CAPWAP_WTP=
|
||||
MAC80211_HAS_RC=
|
||||
MAC80211_RC_MINSTREL=
|
||||
MAC80211_RC_MINSTREL_HT=
|
||||
EOF
|
||||
}
|
||||
|
||||
for F in $DIR/../../kernel-patches/mac80211_packet_tunnel*patch; do \
|
||||
rebuild $(basename $F); \
|
||||
done
|
|
@ -387,6 +387,20 @@ static void wifi_station_clean(struct wifi_station* station)
|
|||
station->supportedratescount = 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wifi_station_schedule_delete(struct wifi_station* station)
|
||||
{
|
||||
ASSERT(station != NULL);
|
||||
|
||||
/* */
|
||||
log_printf(LOG_INFO, "Schedule Delete station: " MACSTR, MAC2STR(station->address));
|
||||
|
||||
/* Delay delete station */
|
||||
station->timeout_action = WIFI_STATION_TIMEOUT_ACTION_DELETE;
|
||||
station->timeout.repeat = WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED / 1000.0;
|
||||
ev_timer_again(EV_DEFAULT_UC_ &station->timeout);
|
||||
}
|
||||
|
||||
/* */
|
||||
static void wifi_station_delete(struct wifi_station* station)
|
||||
{
|
||||
|
@ -395,13 +409,9 @@ static void wifi_station_delete(struct wifi_station* station)
|
|||
/* */
|
||||
log_printf(LOG_INFO, "Delete station: " MACSTR, MAC2STR(station->address));
|
||||
|
||||
/* */
|
||||
/* Free station into hash callback function */
|
||||
wifi_station_clean(station);
|
||||
|
||||
/* Delay delete station */
|
||||
station->timeout_action = WIFI_STATION_TIMEOUT_ACTION_DELETE;
|
||||
station->timeout.repeat = WIFI_STATION_TIMEOUT_AFTER_DEAUTHENTICATED / 1000.0;
|
||||
ev_timer_again(EV_DEFAULT_UC_ &station->timeout);
|
||||
capwap_hash_delete(g_wifiglobal.stations, station->address);
|
||||
}
|
||||
|
||||
/* */
|
||||
|
@ -508,7 +518,7 @@ static void wifi_wlan_deauthentication_station(struct wifi_wlan* wlan,
|
|||
wifi_wlan_send_mgmt_deauthentication(wlan, station->address, reasoncode);
|
||||
|
||||
/* delete station */
|
||||
wifi_station_delete(station);
|
||||
wifi_station_schedule_delete(station);
|
||||
}
|
||||
|
||||
/* */
|
||||
|
@ -585,9 +595,7 @@ static void wifi_station_timeout(EV_P_ ev_timer *w, int revents)
|
|||
station->timeout_action);
|
||||
|
||||
if (station->timeout_action == WIFI_STATION_TIMEOUT_ACTION_DELETE) {
|
||||
/* Free station into hash callback function */
|
||||
wifi_station_clean(station);
|
||||
capwap_hash_delete(g_wifiglobal.stations, station->address);
|
||||
wifi_station_delete(station);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1574,7 +1582,7 @@ wifi_wlan_receive_ac_mgmt_deauthentication(struct wifi_wlan* wlan,
|
|||
/* Delete station */
|
||||
station = wifi_station_get(wlan, frame->da);
|
||||
if (station)
|
||||
wifi_station_delete(station);
|
||||
wifi_station_schedule_delete(station);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <endian.h>
|
||||
|
||||
#include "wtp.h"
|
||||
#include "array.h"
|
||||
#include "list.h"
|
||||
|
@ -903,7 +905,7 @@ static int nl80211_wlan_setbeacon(struct wifi_wlan* wlan) {
|
|||
nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, ntohl(*(uint32_t *)data));
|
||||
data += sizeof(uint32_t);
|
||||
|
||||
suites_num = *(uint16_t *)data;
|
||||
suites_num = le16toh(*(uint16_t *)data);
|
||||
data += 2;
|
||||
suites = alloca(suites_num * sizeof(uint32_t));
|
||||
|
||||
|
@ -914,7 +916,7 @@ static int nl80211_wlan_setbeacon(struct wifi_wlan* wlan) {
|
|||
}
|
||||
nla_put(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, suites_num * sizeof(uint32_t), suites);
|
||||
|
||||
suites_num = *(uint16_t *)data;
|
||||
suites_num = le16toh(*(uint16_t *)data);
|
||||
data += 2;
|
||||
suites = alloca(suites_num * sizeof(uint32_t));
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <endian.h>
|
||||
|
||||
#include "wtp.h"
|
||||
#include "hash.h"
|
||||
#include "list.h"
|
||||
|
@ -970,7 +972,7 @@ uint32_t wtp_radio_add_station(struct capwap_parsed_packet* packet) {
|
|||
data = (uint8_t *)(rsn + 1);
|
||||
data += 2; // RSN Version
|
||||
data += 4; // Group Chipher Suite
|
||||
if (*(uint16_t *)data != 1) {
|
||||
if (le16toh(*(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;
|
||||
|
|
|
@ -1350,6 +1350,7 @@ static void wtp_handle_argv(int argc, char **argv) {
|
|||
case 'c': {
|
||||
if (strlen(optarg) < sizeof(g_configurationfile)) {
|
||||
strcpy(g_configurationfile, optarg);
|
||||
break;
|
||||
} else {
|
||||
printf("Invalid -%c argument\n", optopt);
|
||||
exit(1);
|
||||
|
@ -1506,7 +1507,7 @@ int main(int argc, char** argv) {
|
|||
goto out_close_radio;
|
||||
}
|
||||
|
||||
log_printf(LOG_INFO, "SmartCAPWAP kernel module connected");
|
||||
log_printf(LOG_INFO, "CAPWAP WTP kernel module connected");
|
||||
|
||||
/* */
|
||||
log_printf(LOG_INFO, "Startup WTP");
|
||||
|
|
Loading…
Reference in New Issue