3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2026-01-12 09:17:55 +01:00

Compare commits

..

No commits in common. "master" and "2.17" have entirely different histories.
master ... 2.17

187 changed files with 1718 additions and 7650 deletions

View File

@ -1,3 +0,0 @@
[codespell]
ignore-words-list = fils, FILS, SME, assertIn, OCE, clen, aci, ELL, sav, ths
skip = build-aux, linux, autom4te.cache, aclocal.m4, AUTHORS, libtool, configure*, *.5, ell

3
.gitignore vendored
View File

@ -66,9 +66,6 @@ unit/test-p2p
unit/test-band
unit/test-dpp
unit/test-json
unit/test-nl80211util
unit/test-pmksa
unit/test-storage
unit/cert-*.pem
unit/cert-*.csr
unit/cert-*.srl

View File

@ -1,82 +1,3 @@
ver 3.10:
Fix issue with handling neighbor report on BSS TM request.
Fix issue with handling deauth and FT association failure.
Fix issue with handling roaming and old frequencies.
ver 3.9:
Fix issue with Access Point mode and frequency unlocking.
Fix issue with network configuration and BSS retry logic.
Fix issue with handling busy notification from Access Point.
Fix issue with handling P-192, P-224 and P-521 for SAE.
ver 3.8:
Fix issue with handling unit tests and missing kernel features.
ver 3.7:
Fix issue with handling length of EncryptedSecurity.
Fix issue with handling empty affinities lists.
Fix issue with handling survey scanning results.
Fix issue with handling duplicate values in DPP URI.
ver 3.6:
Fix issue with handling blacklisting and roaming requests.
Fix issue with handling CQM thresholds for FullMAC devices.
Add support for PMKSA when using FullMAC devices.
ver 3.5:
Add support for option to disable blacklist handling.
Add support for option to disable SAE for broken drivers.
ver 3.4:
Add support for the Test Anything Protocol.
ver 3.3:
Fix issue with handling External Authentication.
ver 3.2:
Fix issue with GCC 15 and -std=c23 build errors.
Add support for using PMKSA over SAE if available.
Add support for HighUtilization/StationCount thresholds.
Add support for disabling Multicast RX option.
ver 3.1:
Fix issue with handling OWE transition BSS selection.
Fix issue with handling oper class 136 starting frequency.
ver 3.0:
Fix issue with handling alpha2 code for United Kingdom.
Fix issue with handling empty TX/RX bitrate attributes.
Fix issue with handling RSSI polling fallback workaround.
Fix issue with handling harmless cloned information elements.
Add experimental support for External Authentication feature.
ver 2.22:
Fix issue with handling the Affinities property.
Fix issue with handling ConnectedAccessPoint signal when roaming.
ver 2.21:
Fix issue with pending scan requests after regdom update.
Fix issue with handling the rearming of the roaming timeout.
Fix issue with survey request and externally triggered scans.
Fix issue with RSSI fallback when setting CQM threshold fails.
Fix issue with FT-over-Air without offchannel support.
Add support for per station Affinities property.
ver 2.20:
Fix issue with PKEX timeout and number of frequencies used.
Fix issue with handling logic for handshake failures.
Fix issue with handling ConnectedAccessPoint signal.
ver 2.19:
Fix issue with handling flush flag for external scans.
Fix issue with handling SNR calculation in ranking.
ver 2.18:
Fix issue with handling BSS with invalid HE capabilities.
Fix issue with neighbor reports with invalid country codes.
Fix issue with EAP-TTLS Start packets with L flag set.
Add support for enabling SAE for AP mode operation.
ver 2.17:
Fix issue with handling deauthenticate on disconnect.
Fix issue with handling of rate estimation errors.

View File

@ -64,16 +64,12 @@ ell_headers = ell/util.h \
ell/acd.h \
ell/cleanup.h \
ell/netconfig.h \
ell/sysctl.h \
ell/notifylist.h \
ell/minheap.h
ell/sysctl.h
ell_sources = ell/private.h \
ell/missing.h \
ell/util.c \
ell/test-private.h \
ell/test.c \
ell/test-dbus.c \
ell/strv.c \
ell/utf8.c \
ell/queue.c \
@ -149,9 +145,7 @@ ell_sources = ell/private.h \
ell/dhcp6-transport.c \
ell/acd.c \
ell/netconfig.c \
ell/sysctl.c \
ell/notifylist.c \
ell/minheap.c
ell/sysctl.c
ell_shared = ell/useful.h ell/asn1-private.h
@ -218,8 +212,7 @@ eap_sources = src/eap.c src/eap.h src/eap-private.h \
if DAEMON
libexec_PROGRAMS += src/iwd
src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
src/missing.h src/defs.h \
src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
src/netdev.h src/netdev.c \
src/wiphy.h src/wiphy.c \
src/device.c \
@ -272,10 +265,6 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
src/dpp-util.h src/dpp-util.c \
src/json.h src/json.c \
src/dpp.c \
src/udev.c \
src/pmksa.h src/pmksa.c \
src/vendor_quirks.h \
src/vendor_quirks.c \
$(eap_sources) \
$(builtin_sources)
@ -327,7 +316,6 @@ client_iwctl_SOURCES = client/main.c \
client/daemon.c client/daemon.h \
client/dpp.c client/dpp-pkex.c \
client/station-debug.c \
client/bss.c \
src/util.c src/util.h \
src/band.c src/band.h
@ -442,8 +430,7 @@ unit_tests += unit/test-cmac-aes \
unit/test-ie unit/test-util unit/test-ssid-security \
unit/test-arc4 unit/test-wsc unit/test-eap-mschapv2 \
unit/test-eap-sim unit/test-sae unit/test-p2p unit/test-band \
unit/test-dpp unit/test-json unit/test-nl80211util \
unit/test-pmksa unit/test-storage
unit/test-dpp unit/test-json
endif
if CLIENT
@ -462,7 +449,6 @@ unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
src/eapol.h src/eapol.c \
src/eapolutil.h src/eapolutil.c \
src/handshake.h src/handshake.c \
src/pmksa.h src/pmksa.c \
src/eap.h src/eap.c src/eap-private.h \
src/util.h src/util.c \
src/simauth.h src/simauth.c \
@ -522,7 +508,6 @@ unit_test_eapol_SOURCES = unit/test-eapol.c \
src/eapol.h src/eapol.c \
src/eapolutil.h src/eapolutil.c \
src/handshake.h src/handshake.c \
src/pmksa.h src/pmksa.c \
src/eap.h src/eap.c src/eap-private.h \
src/eap-tls.c src/eap-ttls.c \
src/eap-md5.c src/util.c \
@ -553,7 +538,6 @@ unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
src/eapol.h src/eapol.c \
src/eapolutil.h src/eapolutil.c \
src/handshake.h src/handshake.c \
src/pmksa.h src/pmksa.c \
src/eap.h src/eap.c src/eap-private.h \
src/util.h src/util.c \
src/erp.h src/erp.c \
@ -572,7 +556,6 @@ unit_test_sae_SOURCES = unit/test-sae.c \
src/crypto.h src/crypto.c \
src/ie.h src/ie.c \
src/handshake.h src/handshake.c \
src/pmksa.h src/pmksa.c \
src/erp.h src/erp.c \
src/band.h src/band.c \
src/util.h src/util.c \
@ -596,22 +579,6 @@ unit_test_dpp_LDADD = $(ell_ldadd)
unit_test_json_SOURCES = unit/test-json.c src/json.h src/json.c shared/jsmn.h
unit_test_json_LDADD = $(ell_ldadd)
unit_test_nl80211util_SOURCES = unit/test-nl80211util.c \
src/nl80211util.h src/nl80211util.c \
src/band.h src/band.c \
src/ie.h src/ie.c \
src/util.h src/util.c
unit_test_nl80211util_LDADD = $(ell_ldadd)
unit_test_pmksa_SOURCES = unit/test-pmksa.c src/pmksa.c src/pmksa.h \
src/module.h src/util.h
unit_test_pmksa_LDADD = $(ell_ldadd)
unit_test_storage_SOURCES = unit/test-storage.c src/storage.c src/storage.h \
src/crypto.c src/crypto.h \
src/common.c src/common.h
unit_test_storage_LDADD = $(ell_ldadd)
endif
if CLIENT
@ -627,9 +594,6 @@ unit_test_client_SOURCES = unit/test-client.c \
unit_test_client_LDADD = $(ell_ldadd) $(client_ldadd)
endif
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
$(top_srcdir)/build-aux/tap-driver.sh
TESTS = $(unit_tests)
EXTRA_DIST = src/genbuiltin src/iwd.service.in src/net.connman.iwd.service \
@ -746,7 +710,6 @@ ell/internal: Makefile
done > $@
ell/ell.h: Makefile
$(AM_V_at)$(MKDIR_P) ell
$(AM_V_at)echo -n > $@
$(AM_V_GEN)for f in $(ell_headers) ; do \
echo "#include <$$f>" >> $@ ; \

4
TODO
View File

@ -110,7 +110,7 @@ Wireless monitor
- Subscribe to all nl80211 multicast groups at startup
It seems the nlmon packets are limited to actual subscribed multicast
It seems the nlmon packets are limited to actual subscribed mutlicast
groups. To get a complete picture of all the nl80211 commands and
events, it is required that iwmon adds membership to all multicast
groups that the nl80211 lists.
@ -234,7 +234,7 @@ Wireless daemon
- Implement Enrollee Session Overlap Detection after WSC Protocol Run
WSC Best Practices v2.0.1, Section 3.15 describes an enhancement to detect
WSC Best Practices v2.0.1, Section 3.15 describes an enhacement to detect
PBC session overlaps. The Enrollee is asked to perform an extra scan without
the PBC request in the ProbeRequest frames after EAP-WSC completes
successfully. If another AP in PBC mode is found, then a SessionOverlap

View File

@ -1,156 +0,0 @@
#!/usr/bin/python3
import unittest
import sys
sys.path.append('../util')
import iwd
from iwd import IWD
from iwd import NetworkType
from hostapd import HostapdCLI
class Test(unittest.TestCase):
def initial_connection(self):
ordered_network = self.device.get_ordered_network('TestAPRoam')
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
self.device.connect_bssid(self.bss_hostapd[0].bssid)
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED')
self.assertFalse(self.bss_hostapd[1].list_sta())
def test_full_scan(self):
"""
Tests that IWD first tries a limited scan, then a full scan after
an AP directed roam. After the full scan yields no results IWD
should stop trying to roam.
"""
self.initial_connection()
# Disable other APs, so the scans come up empty
self.bss_hostapd[1].disable()
self.bss_hostapd[2].disable()
# Send a bad candidate list with the BSS TM request which contains a
# channel with no AP operating on it.
self.bss_hostapd[0].send_bss_transition(
self.device.address,
[(self.bss_hostapd[1].bssid, "8f0000005105060603000000")]
)
self.device.wait_for_event("roam-scan-triggered")
self.device.wait_for_event("no-roam-candidates")
# IWD should then trigger a full scan
self.device.wait_for_event("full-roam-scan")
self.device.wait_for_event("no-roam-candidates", timeout=30)
# IWD should not trigger a roam again after the above 2 failures.
with self.assertRaises(TimeoutError):
self.device.wait_for_event("roam-scan-triggered", timeout=60)
def test_bad_candidate_list(self):
"""
Tests behavior when the AP sends a candidate list but the scan
finds no BSS's. IWD should fall back to a full scan after.
"""
self.initial_connection()
# Send a bad candidate list with the BSS TM request which contains a
# channel with no AP operating on it.
self.bss_hostapd[0].send_bss_transition(
self.device.address,
[(self.bss_hostapd[1].bssid, "8f0000005105060603000000")]
)
self.device.wait_for_event("roam-scan-triggered")
self.device.wait_for_event("no-roam-candidates")
# IWD should then trigger a full scan
self.device.wait_for_event("full-roam-scan")
self.device.wait_for_event("roaming", timeout=30)
self.device.wait_for_event("connected")
def test_bad_neighbor_report(self):
"""
Tests behavior when the AP sends no candidate list. IWD should
request a neighbor report. If the limited scan yields no BSS's IWD
should fall back to a full scan.
"""
# Set a bad neighbor (channel that no AP is on) to force the limited
# roam scan to fail
self.bss_hostapd[0].set_neighbor(
self.bss_hostapd[1].bssid,
"TestAPRoam",
'%s8f000000%s%s060603000000' % (self.bss_hostapd[1].bssid.replace(':', ''), "51", "0b")
)
self.initial_connection()
self.bss_hostapd[0].send_bss_transition(self.device.address, [])
self.device.wait_for_event("roam-scan-triggered")
# The AP will have sent a neighbor report with a single BSS but on
# channel 11 which no AP is on. This should result in a limited scan
# picking up no candidates.
self.device.wait_for_event("no-roam-candidates", timeout=30)
# IWD should then trigger a full scan
self.device.wait_for_event("full-roam-scan")
self.device.wait_for_event("roaming", timeout=30)
self.device.wait_for_event("connected")
def test_ignore_candidate_list_quirk(self):
"""
Tests that IWD ignores the candidate list sent by the AP since its
OUI indicates it should be ignored.
"""
# Set the OUI so the candidate list should be ignored
for hapd in self.bss_hostapd:
hapd.set_value('vendor_elements', 'dd0400180a01')
self.initial_connection()
# Send with a candidate list (should be ignored)
self.bss_hostapd[0].send_bss_transition(
self.device.address,
[(self.bss_hostapd[1].bssid, "8f0000005105060603000000")]
)
# IWD should ignore the list and trigger a full scan since we have not
# set any neighbors
self.device.wait_for_event("full-roam-scan")
self.device.wait_for_event("roaming", timeout=30)
self.device.wait_for_event("connected")
def setUp(self):
self.wd = IWD(True)
devices = self.wd.list_devices(1)
self.device = devices[0]
def tearDown(self):
self.wd = None
self.device = None
for hapd in self.bss_hostapd:
hapd.reload()
@classmethod
def setUpClass(cls):
IWD.copy_to_storage('TestAPRoam.psk')
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
HostapdCLI(config='ssid2.conf'),
HostapdCLI(config='ssid3.conf') ]
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -11,58 +11,52 @@ from iwd import NetworkType
from hostapd import HostapdCLI
class Test(unittest.TestCase):
def initial_connection(self):
ordered_network = self.device.get_ordered_network('TestAPRoam')
def validate(self, expect_roam=True):
wd = IWD()
devices = wd.list_devices(1)
device = devices[0]
ordered_network = device.get_ordered_network('TestAPRoam')
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
wd.wait_for_object_condition(ordered_network.network_object, condition)
self.device.connect_bssid(self.bss_hostapd[0].bssid)
device.connect_bssid(self.bss_hostapd[0].bssid)
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
wd.wait_for_object_condition(device, condition)
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED')
self.assertFalse(self.bss_hostapd[1].list_sta())
def validate_roam(self, from_bss, to_bss, expect_roam=True):
from_bss.send_bss_transition(self.device.address,
self.neighbor_list,
self.bss_hostapd[0].send_bss_transition(device.address,
[(self.bss_hostapd[1].bssid, '8f0000005102060603000000')],
disassoc_imminent=expect_roam)
if expect_roam:
from_condition = 'obj.state == DeviceState.roaming'
to_condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
wd.wait_for_object_change(device, from_condition, to_condition)
to_bss.wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
self.bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
else:
self.device.wait_for_event("no-roam-candidates")
device.wait_for_event("no-roam-candidates")
device.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
def test_disassoc_imminent(self):
self.initial_connection()
self.validate_roam(self.bss_hostapd[0], self.bss_hostapd[1])
self.validate(expect_roam=True)
def test_no_candidates(self):
self.initial_connection()
# We now have BSS0 roam blacklisted
self.validate_roam(self.bss_hostapd[0], self.bss_hostapd[1])
# Try and trigger another roam back, which shouldn't happen since now
# both BSS's are roam blacklisted
self.validate_roam(self.bss_hostapd[1], self.bss_hostapd[0], expect_roam=False)
def setUp(self):
self.wd = IWD(True)
devices = self.wd.list_devices(1)
self.device = devices[0]
def tearDown(self):
self.wd = None
self.device = None
self.validate(expect_roam=False)
@classmethod
def setUpClass(cls):
@ -71,10 +65,6 @@ class Test(unittest.TestCase):
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
HostapdCLI(config='ssid2.conf'),
HostapdCLI(config='ssid3.conf') ]
cls.neighbor_list = [
(cls.bss_hostapd[0].bssid, "8f0000005101060603000000"),
(cls.bss_hostapd[1].bssid, "8f0000005102060603000000"),
]
@classmethod
def tearDownClass(cls):

View File

@ -1,7 +1,5 @@
[SETUP]
num_radios=4
hwsim_medium=true
start_iwd=false
[HOSTAPD]
rad0=ssid1.conf

View File

@ -1,6 +0,0 @@
[General]
RoamThreshold=-72
CriticalRoamThreshold=-72
[Blacklist]
InitialAccessPointBusyTimeout=20

View File

@ -1,183 +0,0 @@
#!/usr/bin/python3
import unittest
import sys
sys.path.append('../util')
import iwd
from iwd import IWD, IWD_CONFIG_DIR
from iwd import NetworkType
from hostapd import HostapdCLI
from hwsim import Hwsim
class Test(unittest.TestCase):
def validate_connected(self, hostapd):
ordered_network = self.device.get_ordered_network('TestAPRoam')
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
self.device.connect_bssid(hostapd.bssid)
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
hostapd.wait_for_event('AP-STA-CONNECTED')
def validate_ap_roamed(self, from_hostapd, to_hostapd):
from_hostapd.send_bss_transition(
self.device.address, self.neighbor_list, disassoc_imminent=True
)
from_condition = 'obj.state == DeviceState.roaming'
to_condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
to_hostapd.wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
self.device.wait_for_event("ap-roam-blacklist-added")
def test_roam_to_optimal_candidates(self):
# In this test IWD will naturally transition down the list after each
# BSS gets roam blacklisted. All BSS's are above the RSSI thresholds.
self.rule_ssid1.signal = -5000
self.rule_ssid2.signal = -6500
self.rule_ssid3.signal = -6900
# Connect to BSS0
self.validate_connected(self.bss_hostapd[0])
# AP directed roam to BSS1
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
# AP directed roam to BSS2
self.validate_ap_roamed(self.bss_hostapd[1], self.bss_hostapd[2])
def test_avoiding_under_threshold_bss(self):
# In this test IWD will blacklist BSS0, then roam the BSS1. BSS1 will
# then tell IWD to roam, but it should go back to BSS0 since the only
# non-blacklisted BSS is under the roam threshold.
self.rule_ssid1.signal = -5000
self.rule_ssid2.signal = -6500
self.rule_ssid3.signal = -7300
# Connect to BSS0
self.validate_connected(self.bss_hostapd[0])
# AP directed roam to BSS1
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
# AP directed roam, but IWD should choose BSS0 since BSS2 is -73dB
self.validate_ap_roamed(self.bss_hostapd[1], self.bss_hostapd[0])
def test_connect_to_roam_blacklisted_bss(self):
# In this test a BSS will be roam blacklisted, but all other options are
# below the RSSI threshold so IWD should roam back to the blacklisted
# BSS.
self.rule_ssid1.signal = -5000
self.rule_ssid2.signal = -8000
self.rule_ssid3.signal = -8500
# Connect to BSS0
self.validate_connected(self.bss_hostapd[0])
# AP directed roam, should connect to BSS1 as its the next best
self.validate_ap_roamed(self.bss_hostapd[0], self.bss_hostapd[1])
# Connected to BSS1, but the signal is bad, so IWD should try to roam
# again. BSS0 is still blacklisted, but its the only reasonable option
# since both BSS1 and BSS2 are below the set RSSI threshold (-72dB)
from_condition = 'obj.state == DeviceState.roaming'
to_condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
# IWD should have connected to BSS0, even though its roam blacklisted
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
def test_blacklist_during_roam_scan(self):
# Tests that an AP roam request mid-roam results in the AP still being
# blacklisted even though the request itself doesn't directly trigger
# a roam.
self.rule_ssid1.signal = -7300
self.rule_ssid2.signal = -7500
self.rule_ssid3.signal = -8500
# Connect to BSS0 under the roam threshold so IWD will immediately try
# roaming elsewhere
self.validate_connected(self.bss_hostapd[0])
self.device.wait_for_event("roam-scan-triggered")
self.bss_hostapd[0].send_bss_transition(
self.device.address, self.neighbor_list, disassoc_imminent=True
)
self.device.wait_for_event("ap-roam-blacklist-added")
# BSS0 should have gotten blacklisted even though IWD was mid-roam,
# causing IWD to choose BSS1 when it gets is results.
from_condition = 'obj.state == DeviceState.roaming'
to_condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_change(self.device, from_condition, to_condition)
self.bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % self.device.address)
def setUp(self):
self.wd = IWD(True)
devices = self.wd.list_devices(1)
self.device = devices[0]
def tearDown(self):
self.wd = None
self.device = None
@classmethod
def setUpClass(cls):
IWD.copy_to_storage("main.conf.roaming", IWD_CONFIG_DIR, "main.conf")
IWD.copy_to_storage('TestAPRoam.psk')
hwsim = Hwsim()
cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
HostapdCLI(config='ssid2.conf'),
HostapdCLI(config='ssid3.conf') ]
HostapdCLI.group_neighbors(*cls.bss_hostapd)
rad0 = hwsim.get_radio('rad0')
rad1 = hwsim.get_radio('rad1')
rad2 = hwsim.get_radio('rad2')
cls.neighbor_list = [
(cls.bss_hostapd[0].bssid, "8f0000005101060603000000"),
(cls.bss_hostapd[1].bssid, "8f0000005102060603000000"),
(cls.bss_hostapd[2].bssid, "8f0000005103060603000000"),
]
cls.rule_ssid1 = hwsim.rules.create()
cls.rule_ssid1.source = rad0.addresses[0]
cls.rule_ssid1.bidirectional = True
cls.rule_ssid1.enabled = True
cls.rule_ssid2 = hwsim.rules.create()
cls.rule_ssid2.source = rad1.addresses[0]
cls.rule_ssid2.bidirectional = True
cls.rule_ssid2.enabled = True
cls.rule_ssid3 = hwsim.rules.create()
cls.rule_ssid3.source = rad2.addresses[0]
cls.rule_ssid3.bidirectional = True
cls.rule_ssid3.enabled = True
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -1,2 +0,0 @@
[Security]
Passphrase=EasilyGuessedPassword

View File

@ -1,41 +0,0 @@
hw_mode=g
channel=1
ssid=TestFT
utf8_ssid=1
ctrl_interface=/var/run/hostapd
r1_key_holder=120000000001
nas_identifier=dummy1
wpa=2
# Can support WPA-PSK and FT-PSK (space separated list) and/or EAP at the same
# time but we want to force FT
wpa_key_mgmt=FT-PSK
wpa_pairwise=CCMP
wpa_passphrase=EasilyGuessedPassword
ieee80211w=0
rsn_preauth=1
rsn_preauth_interfaces=lo
disable_pmksa_caching=0
# Allow PMK cache to be shared opportunistically among configured interfaces
# and BSSes (i.e., all configurations within a single hostapd process).
okc=1
mobility_domain=1234
reassociation_deadline=60000
r0kh=12:00:00:00:00:01 dummy1 000102030405060708090a0b0c0d0e0f
r0kh=12:00:00:00:00:02 dummy2 000102030405060708090a0b0c0d0e0f
r1kh=12:00:00:00:00:01 00:00:00:00:00:01 000102030405060708090a0b0c0d0e0f
r1kh=12:00:00:00:00:02 00:00:00:00:00:02 000102030405060708090a0b0c0d0e0f
# Push mode only needed for 8021x, not PSK mode since msk already known
pmk_r1_push=0
# Allow locally generated FT response so we don't have to configure push/pull
# between BSSes running as separate hostapd processes as in the test-runner
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
# CONFIG_BRIDGE enabled in the kernel.
ft_psk_generate_local=1
rkh_pull_timeout=50
ft_over_ds=0
ap_table_expiration_time=36000
ap_table_max_size=10
rrm_neighbor_report=1
ocv=1

View File

@ -1,41 +0,0 @@
hw_mode=g
channel=2
ssid=TestFT
utf8_ssid=1
ctrl_interface=/var/run/hostapd
r1_key_holder=120000000002
nas_identifier=dummy2
wpa=2
# Can support WPA-PSK and FT-PSK (space separated list) and/or EAP at the same
# time but we want to force FT
wpa_key_mgmt=FT-PSK
wpa_pairwise=CCMP
wpa_passphrase=EasilyGuessedPassword
ieee80211w=0
rsn_preauth=1
rsn_preauth_interfaces=lo
disable_pmksa_caching=0
# Allow PMK cache to be shared opportunistically among configured interfaces
# and BSSes (i.e., all configurations within a single hostapd process).
okc=1
mobility_domain=1234
reassociation_deadline=60000
r0kh=12:00:00:00:00:01 dummy1 000102030405060708090a0b0c0d0e0f
r0kh=12:00:00:00:00:02 dummy2 000102030405060708090a0b0c0d0e0f
r1kh=12:00:00:00:00:01 00:00:00:00:00:01 000102030405060708090a0b0c0d0e0f
r1kh=12:00:00:00:00:02 00:00:00:00:00:02 000102030405060708090a0b0c0d0e0f
# Push mode only needed for 8021x, not PSK mode since msk already known
pmk_r1_push=0
# Allow locally generated FT response so we don't have to configure push/pull
# between BSSes running as separate hostapd processes as in the test-runner
# case. Only works with FT-PSK, otherwise brctl needs to be installed and
# CONFIG_BRIDGE enabled in the kernel.
ft_psk_generate_local=1
rkh_pull_timeout=50
ft_over_ds=0
ap_table_expiration_time=36000
ap_table_max_size=10
rrm_neighbor_report=1
ocv=1

View File

@ -1,8 +0,0 @@
[SETUP]
num_radios=3
start_iwd=0
hwsim_medium=yes
[HOSTAPD]
rad0=ft-psk-ccmp-1.conf
rad1=ft-psk-ccmp-2.conf

View File

@ -1,5 +0,0 @@
[Scan]
DisableMacAddressRandomization=true
[General]
RoamRetryInterval=1

View File

@ -1,216 +0,0 @@
#! /usr/bin/python3
import unittest
import sys, os
import dbus
sys.path.append('../util')
from config import ctx
import iwd
from iwd import IWD, IWDDBusAbstract
from iwd import NetworkType
from hwsim import Hwsim
from hostapd import HostapdCLI
#
# Separate client used to test DBus disconnects so we don't bring down the
# entire IWD python library
#
class AffinityClient(IWDDBusAbstract):
def __init__(self, device_path):
self._bus = dbus.bus.BusConnection(address_or_type=ctx.dbus_address)
self._station_prop_if = dbus.Interface(
self._bus.get_object(iwd.IWD_SERVICE, device_path),
iwd.DBUS_PROPERTIES)
def set(self, values):
self._station_prop_if.Set(iwd.IWD_STATION_INTERFACE, 'Affinities', dbus.Array([dbus.ObjectPath(v) for v in values], signature="o"))
def close(self):
self._bus.close()
class Test(unittest.TestCase):
def connect(self, device, hapd):
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
self.wd.wait_for_object_condition(ordered_network.network_object, condition)
device.connect_bssid(hapd.bssid)
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(device, condition)
def test_set_affinity(self):
device = self.wd.list_devices(1)[0]
self.connect(device, self.bss_hostapd[0])
print(device.connected_bss)
device.affinities = [device.connected_bss]
# IWD should not attempt to roam
with self.assertRaises(TimeoutError):
device.wait_for_event("roam-scan-triggered")
device.affinities = []
device.wait_for_event("roam-scan-triggered")
def test_roam_below_critical(self):
device = self.wd.list_devices(1)[0]
self.connect(device, self.bss_hostapd[0])
device.affinities = [device.connected_bss]
# IWD should not attempt to roam
with self.assertRaises(TimeoutError):
device.wait_for_event("roam-scan-triggered")
# Lower signal past critical level
self.bss0_rule.signal = -9000
device.wait_for_event("roam-scan-triggered")
def test_error_conditions(self):
device = self.wd.list_devices(1)[0]
# Calling set while disconnected should fail
with self.assertRaises(iwd.NotConnectedEx):
device.affinities = ["/some/path"]
self.connect(device, self.bss_hostapd[0])
device.affinities = [device.connected_bss]
# An invalid path should fail
with self.assertRaises(iwd.InvalidArgumentsEx):
device.affinities = [device.connected_bss, "/an/invalid/path"]
def test_affinity_client_disconnect(self):
device = self.wd.list_devices(1)[0]
client = AffinityClient(device.device_path)
self.connect(device, self.bss_hostapd[0])
client.set([device.connected_bss])
with self.assertRaises(TimeoutError):
device.wait_for_event("roam-scan-triggered")
client._bus.close()
device.wait_for_event("roam-scan-triggered")
def test_affinity_client_reconnect_during_roam(self):
device = self.wd.list_devices(1)[0]
client = AffinityClient(device.device_path)
self.connect(device, self.bss_hostapd[0])
client.set([device.connected_bss])
# Lower signal past critical level
self.bss0_rule.signal = -9000
device.wait_for_event("roam-scan-triggered")
client.close()
del client
client = AffinityClient(device.device_path)
# setting here should get cleared after connecting
client.set([device.connected_bss])
device.wait_for_event("ft-authenticating")
device.wait_for_event("associating")
device.wait_for_event("connected")
# Affinity should be reset, and IWD should be trying to roam
device.wait_for_event("roam-scan-triggered")
def test_cleanup_with_connected_client(self):
device = self.wd.list_devices(1)[0]
client = AffinityClient(device.device_path)
self.connect(device, self.bss_hostapd[0])
client.set([device.connected_bss])
self.wd.stop()
def test_affinity_removed_after_roam(self):
device = self.wd.list_devices(1)[0]
self.connect(device, self.bss_hostapd[0])
device.affinities = [device.connected_bss]
# Lower signal past critical level
self.bss0_rule.signal = -9000
device.wait_for_event("roam-scan-triggered")
device.wait_for_event("ft-authenticating")
device.wait_for_event("associating")
device.wait_for_event("connected")
self.assertEqual(device.affinities, [])
def tearDown(self):
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
self.wd.stop()
self.wd = None
def setUp(self):
self.bss0_rule.signal = -8000
self.bss1_rule.signal = -8000
self.wd = IWD(True)
@classmethod
def setUpClass(cls):
hwsim = Hwsim()
IWD.copy_to_storage('TestFT.psk')
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
rad0 = hwsim.get_radio('rad0')
rad1 = hwsim.get_radio('rad1')
cls.bss0_rule = hwsim.rules.create()
cls.bss0_rule.source = rad0.addresses[0]
cls.bss0_rule.bidirectional = True
cls.bss0_rule.signal = -8000
cls.bss0_rule.enabled = True
cls.bss1_rule = hwsim.rules.create()
cls.bss1_rule.source = rad1.addresses[0]
cls.bss1_rule.bidirectional = True
cls.bss1_rule.signal = -8000
cls.bss1_rule.enabled = True
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
HostapdCLI.group_neighbors(*cls.bss_hostapd)
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
cls.bss_hostapd = None
cls.bss0_rule.remove()
cls.bss1_rule.remove()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -1,2 +0,0 @@
[Security]
Passphrase=secret123

View File

@ -260,69 +260,12 @@ class Test(unittest.TestCase):
self.wd.unregister_psk_agent(psk_agent)
def test_blacklist_disabled(self):
wd = self.wd
bss_hostapd = self.bss_hostapd
rule0 = self.rule0
rule1 = self.rule1
rule2 = self.rule2
psk_agent = PSKAgent(["secret123", 'secret123'])
wd.register_psk_agent(psk_agent)
devices = wd.list_devices(1)
device = devices[0]
rule0.drop = True
rule0.enabled = True
device.autoconnect = True
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
ordered_network = device.get_ordered_network("TestBlacklist", full_scan=True)
self.assertEqual(ordered_network.type, NetworkType.psk)
# The first BSS should fail, and we should connect to the second. This
# should not result in a connection blacklist though since its disabled.
bss_hostapd[1].wait_for_event('AP-STA-CONNECTED %s' % device.address)
device.disconnect()
rule0.drop = False
device.autoconnect = True
# Verify the first BSS wasn't blacklisted.
bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
def setUp(self):
_, _, name = self.id().split(".")
# TODO: If we have this pattern elsewhere it might be nice to turn this
# into a decorator e.g.
#
# @config("main.conf.disabled")
# @profile("TestBlacklist.psk")
# def test_blacklist_disabled(self)
# ...
#
if name == "test_blacklist_disabled":
IWD.copy_to_storage("main.conf.disabled", IWD_CONFIG_DIR, "main.conf")
IWD.copy_to_storage("TestBlacklist.psk")
else:
IWD.copy_to_storage("main.conf.default", IWD_CONFIG_DIR, "main.conf")
self.wd = IWD(True)
def tearDown(self):
IWD.clear_storage()
self.wd = None
self.rule0.drop = False
self.rule1.drop = False
self.rule2.drop = False
@classmethod
def setUpClass(cls):

View File

@ -1,2 +0,0 @@
[Blacklist]
InitialTimeout=0

View File

@ -1,98 +0,0 @@
#! /usr/bin/python3
import unittest
import sys, os
sys.path.append('../util')
import iwd
from iwd import IWD
from iwd import PSKAgent
from iwd import NetworkType
from hwsim import Hwsim
from hostapd import HostapdCLI
import testutil
class Test(unittest.TestCase):
def test_bss_unregister(self):
device = self.wd.list_devices(1)[0]
ordered_network = device.get_ordered_network('ssidTKIP', full_scan=True)
network = ordered_network.network_object
self.assertEqual(len(network.extended_service_set), 2)
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
self.assertIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
self.rule_bss1.enabled = True
# Even with flushing, the kernel still seems to return the scan
# results
self.wd.wait(40)
ordered_network = device.get_ordered_network('ssidTKIP', full_scan=True)
network = ordered_network.network_object
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
self.assertNotIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
self.rule_bss0.enabled = True
self.wd.wait(40)
ordered_networks = device.get_ordered_networks('ssidTKIP', full_scan=True)
self.assertIsNone(ordered_networks)
self.rule_bss0.enabled = False
ordered_networks = device.get_ordered_networks('ssidTKIP', full_scan=True)
ends = [parts.split('/')[-1] for parts in network.extended_service_set]
self.assertIn(self.bss_hostapd[0].bssid.replace(':', ''), ends)
self.assertNotIn(self.bss_hostapd[1].bssid.replace(':', ''), ends)
def tearDown(self):
self.rule_bss0.enabled = False
self.rule_bss1.enabled = False
self.wd.stop()
self.wd.wait(10)
self.wd = None
def setUp(self):
self.wd = IWD(True)
@classmethod
def setUpClass(cls):
hwsim = Hwsim()
IWD.copy_to_storage('ssidTKIP.psk')
cls.bss_hostapd = [ HostapdCLI(config='ssidTKIP-1.conf'),
HostapdCLI(config='ssidTKIP-2.conf') ]
rad0 = hwsim.get_radio('rad0')
rad1 = hwsim.get_radio('rad1')
cls.rule_bss0 = hwsim.rules.create()
cls.rule_bss0.source = rad0.addresses[0]
cls.rule_bss0.bidirectional = True
cls.rule_bss0.drop = True
cls.rule_bss1 = hwsim.rules.create()
cls.rule_bss1.source = rad1.addresses[0]
cls.rule_bss1.bidirectional = True
cls.rule_bss1.drop = True
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
cls.bss_hostapd = None
cls.rule_bss0.remove()
cls.rule_bss1.remove()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -1,8 +0,0 @@
[SETUP]
num_radios=3
hwsim_medium=yes
start_iwd=no
[HOSTAPD]
rad0=ssidTKIP-1.conf
rad1=ssidTKIP-2.conf

View File

@ -1,7 +0,0 @@
hw_mode=g
channel=1
ssid=ssidTKIP
wpa=1
wpa_pairwise=TKIP
wpa_passphrase=secret123

View File

@ -1,7 +0,0 @@
hw_mode=g
channel=2
ssid=ssidTKIP
wpa=1
wpa_pairwise=TKIP
wpa_passphrase=secret123

View File

@ -1,5 +0,0 @@
[Security]
Passphrase=secret123
[Settings]
AutoConnect=False

View File

@ -11,7 +11,7 @@ from iwd import IWD
class Test8021xNetwork(unittest.TestCase):
'''
The below test cases excesise the following connection scenarios:
The bellow test cases excesise the following connection scenarios:
Network config is
present at start time: Connect: AutoConnect: Result:

View File

@ -11,7 +11,7 @@ from iwd import IWD
class TestOpenNetwork(unittest.TestCase):
'''
The below test cases excesise the following connection scenarios:
The bellow test cases excesise the following connection scenarios:
Network config is
present at start time: Connect: AutoConnect: Result:

View File

@ -11,7 +11,7 @@ from iwd import IWD
class TestWpaNetwork(unittest.TestCase):
'''
The below test cases exercise the following connection scenarios:
The bellow test cases exercise the following connection scenarios:
Network config is
present at start time: Connect: AutoConnect: Result:

View File

@ -38,18 +38,20 @@ class Test(unittest.TestCase):
def test_iwd_as_enrollee_scan_after(self):
self.wpas.disconnect()
self.device.autoconnect = True
uri = self.device.dpp_start_enrollee()
self.wpas.dpp_configurator_create(uri)
self.wpas.dpp_configurator_start('ssidCCMP', 'secret123')
self.hapd.reload()
with self.assertRaises(Exception):
self.device.get_ordered_network('ssidCCMP', scan_if_needed=False)
self.hapd.reload()
self.hapd.wait_for_event('AP-ENABLED')
self.device.autoconnect = True
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)

View File

@ -4,7 +4,7 @@ import unittest
import sys
sys.path.append('../util')
from iwd import IWD, SharedCodeAgent, DeviceState
from iwd import IWD, SharedCodeAgent
from iwd import DeviceProvisioning
from wpas import Wpas
from hostapd import HostapdCLI
@ -160,9 +160,11 @@ class Test(unittest.TestCase):
def test_pkex_iwd_to_iwd(self):
self.start_iwd_pkex_configurator(self.device[0])
self.device[1].autoconnect = True
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
self.device[1].autoconnect = True
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device[1], condition)
@ -174,9 +176,11 @@ class Test(unittest.TestCase):
def test_pkex_configurator_with_agent(self):
self.start_iwd_pkex_configurator(self.device[0], agent=True)
self.device[1].autoconnect = True
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
self.device[1].autoconnect = True
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device[1], condition)
@ -194,8 +198,8 @@ class Test(unittest.TestCase):
self.start_iwd_pkex_configurator(self.device[0])
self.device[1].autoconnect = False
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
self.device[1].autoconnect = False
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device[1], condition)
@ -206,24 +210,6 @@ class Test(unittest.TestCase):
self.assertIn("SendHostname=true", settings)
def test_existing_incorrect_profile(self):
self.hapd.reload()
self.hapd.wait_for_event('AP-ENABLED')
IWD.copy_to_storage("existingProfile.psk", "/tmp/ns0/", "ssidCCMP.psk")
# Start connecting
self.device[1].autoconnect = True
self.wd.wait_for_object_condition(self.device[1], 'obj.state == DeviceState.connecting')
# We should be able to start DPP despite the connecting state
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
self.start_iwd_pkex_configurator(self.device[0])
self.assertEqual(self.device[1].state, DeviceState.disconnected)
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device[1], condition)
def test_existing_hidden_network(self):
self.hapd_hidden.reload()
self.hapd_hidden.wait_for_event('AP-ENABLED')
@ -236,9 +222,8 @@ class Test(unittest.TestCase):
self.start_iwd_pkex_configurator(self.device[0], profile='ssidHidden.psk')
self.device[1].autoconnect = False
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
self.device[1].autoconnect = False
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device[1], condition)
@ -254,8 +239,8 @@ class Test(unittest.TestCase):
self.hapd_hidden.wait_for_event('AP-ENABLED')
self.start_iwd_pkex_configurator(self.device[0], profile='ssidHidden.psk')
self.device[1].autoconnect = False
self.device[1].dpp_pkex_enroll('secret123', identifier="test")
self.device[1].autoconnect = False
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device[1], condition)

View File

@ -1,107 +0,0 @@
#!/usr/bin/python3
import unittest
import sys
sys.path.append('../util')
from iwd import IWD, SharedCodeAgent, DeviceState
from iwd import DeviceProvisioning
from wpas import Wpas
from hostapd import HostapdCLI
from hwsim import Hwsim
from config import ctx
from time import time
import os
class Test(unittest.TestCase):
def auto_connect(self):
IWD.copy_to_storage('ssidCCMP.psk')
self.device.autoconnect = True
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
def test_configurator_stops_on_disconnect(self):
self.auto_connect()
self.device.dpp_start_configurator()
self.device.disconnect()
condition = 'obj.state == DeviceState.disconnected'
self.wd.wait_for_object_condition(self.device, condition)
self.assertEqual(self.device._device_provisioning.started, False)
def test_enrollee_stops_on_connect(self):
# Scan to get a list of networks
self.device.scan()
self.wd.wait_for_object_condition(self.device, 'obj.scanning == True')
self.wd.wait_for_object_condition(self.device, 'obj.scanning == False')
self.device.dpp_start_enrollee()
network = self.device.get_ordered_network("ssidCCMP")
network.network_object.connect()
condition = 'obj.state == DeviceState.connected'
self.wd.wait_for_object_condition(self.device, condition)
self.assertEqual(self.device._device_provisioning.started, False)
def test_enrollee_disconnects_automatically(self):
self.auto_connect()
self.device.dpp_start_enrollee()
condition = 'obj.state == DeviceState.disconnected'
self.wd.wait_for_object_condition(self.device, condition)
def test_enrollee_autoconnect_stays_on(self):
# Put in an autoconnecting state, no saved profile though
self.device.autoconnect = True
self.device.dpp_start_enrollee()
# DPP should set autoconnect false, but then re-enable after it stops
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
self.wd.wait_for_object_condition(self.device._device_provisioning, "obj.started == True")
# Stop DPP
self.device.dpp_stop()
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == True")
def test_enrollee_autoconnect_stays_off(self):
# Autoconnect should be off by default
self.device.dpp_start_enrollee()
# DPP should set autoconnect false, but stay off after it stops
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
self.wd.wait_for_object_condition(self.device._device_provisioning, "obj.started == True")
# Stop DPP
self.device.dpp_stop()
self.wd.wait_for_object_condition(self.device, "obj.autoconnect == False")
def setUp(self):
self.wd = IWD(True)
self.device = self.wd.list_devices(1)[0]
def tearDown(self):
self.wd.stop()
self.wd = None
@classmethod
def setUpClass(cls):
hapd = HostapdCLI(config="hostapd.conf")
hapd.reload()
hapd.wait_for_event("AP-ENABLED")
@classmethod
def tearDownClass(cls):
pass
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -104,7 +104,7 @@ class Test(unittest.TestCase):
self.assertTrue(self.profile_is_encrypted('ssidCCMP.psk'))
# Tests that a profile that doesn't decrypt won't become a known network
# Tests that a profile that doesn't decrypt wont become a known network
def test_decryption_failure(self):
bad_config = \
'''

View File

@ -1,5 +1,2 @@
[Security]
Passphrase=secret123
[General]
AutoConnect=false

View File

@ -3,11 +3,7 @@ import sys
import sys
import os
from scapy.layers.dot11 import *
from scapy.arch import str2mac
try:
from scapy.arch import get_if_raw_hwaddr
except:
from scapy.arch.unix import get_if_raw_hwaddr
from scapy.arch import str2mac, get_if_raw_hwaddr
from time import time, sleep
from threading import Thread

View File

@ -12,7 +12,7 @@ from hostapd import HostapdCLI
class TestWpaNetwork(unittest.TestCase):
'''
The below test cases excesise the following connection scenarios:
The bellow test cases excesise the following connection scenarios:
Network config is
present at start time: Connect: AutoConnect: Result:

View File

@ -12,7 +12,7 @@ from hostapd import HostapdCLI
class TestOpenNetwork(unittest.TestCase):
'''
The below test cases excesise the following connection scenarios:
The bellow test cases excesise the following connection scenarios:
Network config is
present at start time: Connect: AutoConnect: Result:

View File

@ -12,7 +12,7 @@ from hostapd import HostapdCLI
class TestWpaNetwork(unittest.TestCase):
'''
The below test cases excesise the following connection scenarios:
The bellow test cases excesise the following connection scenarios:
Network config is
present at start time: Connect: AutoConnect: Result:

View File

@ -11,7 +11,7 @@ from iwd import NetworkType
class TestMFP(unittest.TestCase):
'''
The below test cases excesise the following MFP option setting scenarios:
The bellow test cases excesise the following MFP option setting scenarios:
IWD_MFP: AP_MFP: Result:
0 0 No MFP, connection succeeds

View File

@ -137,7 +137,7 @@ class Test(unittest.TestCase):
# since (T2 - T1) / 2 is shorter than 60s. It is now about 10s since the last
# renewal or 5s before the next DHCPREQUEST frame that is going to be lost. We'll
# wait T1 seconds, so until about 10s after the failed attempt, we'll check that
# there was no renewal by that time, just in case, and we'll re-enable frame delivery.
# there was no renewal by that time, just in case, and we'll reenable frame delivery.
# We'll then wait another 60s and we should see the lease has been successfully
# renewed some 10 seconds earlier on the 1st DHCPREQUEST retransmission.
#

View File

@ -91,11 +91,16 @@ class Test(unittest.TestCase):
# using the same static config. The new client's ACD client should
# detect an IP conflict and not allow the device to reach the
# "connected" state although the DBus .Connect call will succeed.
with self.assertRaises(iwd.FailedEx):
ordered_network.network_object.connect(timeout=500)
condition = 'obj.state == DeviceState.disconnected'
iwd_ns0_1.wait_for_object_condition(dev2, condition, max_wait=21)
ordered_network.network_object.connect()
self.assertEqual(dev2.state, iwd.DeviceState.connecting)
try:
# We should either stay in "connecting" indefinitely or move to
# "disconnecting"
condition = 'obj.state != DeviceState.connecting'
iwd_ns0_1.wait_for_object_condition(dev2, condition, max_wait=21)
self.assertEqual(dev2.state, iwd.DeviceState.disconnecting)
except TimeoutError:
dev2.disconnect()
iwd_ns0_1.unregister_psk_agent(psk_agent_ns0_1)
del dev2

View File

@ -8,8 +8,6 @@ from iwd import PSKAgent
from iwd import NetworkType
class Test(unittest.TestCase):
def connect_failure(self, ex):
self.failure_triggered = True
def test_netconfig_timeout(self):
IWD.copy_to_storage('autoconnect.psk', name='ap-ns1.psk')
@ -29,34 +27,23 @@ class Test(unittest.TestCase):
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
self.failure_triggered = False
ordered_network.network_object.connect()
# Set our error handler here so we can check if it fails
ordered_network.network_object.connect(
wait=False,
timeout=1000,
error_handler=self.connect_failure
)
# IWD should attempt to try both BSS's with both failing netconfig.
# Then the autoconnect list should be exhausted, and IWD should
# transition to a disconnected state, then proceed to full autoconnect.
device.wait_for_event("netconfig-failed", timeout=1000)
device.wait_for_event("netconfig-failed", timeout=1000)
device.wait_for_event("disconnected")
device.wait_for_event("autoconnect_full")
# The connect call should have failed
self.assertTrue(self.failure_triggered)
condition = "obj.scanning"
wd.wait_for_object_condition(device, condition)
condition = "not obj.scanning"
condition = 'obj.state == DeviceState.connecting'
wd.wait_for_object_condition(device, condition)
# IWD should attempt to connect, but it will of course fail again.
device.wait_for_event("netconfig-failed", timeout=1000)
device.wait_for_event("connecting (netconfig)")
# Netconfig should fail, and IWD should disconnect
from_condition = 'obj.state == DeviceState.connecting'
to_condition = 'obj.state == DeviceState.disconnecting'
wd.wait_for_object_change(device, from_condition, to_condition, max_wait=60)
# Autoconnect should then try again
condition = 'obj.state == DeviceState.connecting'
wd.wait_for_object_condition(device, condition)
device.wait_for_event("connecting (netconfig)")
device.disconnect()
condition = 'obj.state == DeviceState.disconnected'

View File

@ -19,7 +19,7 @@ class Test(unittest.TestCase):
device = wd.list_devices(1)[0]
device.get_ordered_network('TestFT', full_scan=True)
device.connect_bssid(self.bss_hostapd[1].bssid, wait=False)
device.connect_bssid(self.bss_hostapd[1].bssid)
self.bss_hostapd[1].wait_for_event(f'AP-STA-CONNECTED {device.address}')
device.wait_for_event("connecting (netconfig)")

View File

@ -1,114 +0,0 @@
#!/usr/bin/python3
import unittest
import sys
sys.path.append('../util')
from iwd import IWD
from iwd import PSKAgent
from iwd import NetworkType
from hostapd import HostapdCLI
import testutil
class Test(unittest.TestCase):
def validate_connection(self, wd, ssid, hostapd, expected_group):
psk_agent = PSKAgent("secret123")
wd.register_psk_agent(psk_agent)
devices = wd.list_devices(1)
self.assertIsNotNone(devices)
device = devices[0]
device.disconnect()
network = device.get_ordered_network(ssid, full_scan=True)
self.assertEqual(network.type, NetworkType.psk)
network.network_object.connect()
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
wd.wait(2)
testutil.test_iface_operstate(intf=device.name)
testutil.test_ifaces_connected(if0=device.name, if1=hostapd.ifname)
# Initial connection PMKSA should not be used. So we should see the
# SAE group set.
sta_status = hostapd.sta_status(device.address)
self.assertEqual(int(sta_status["sae_group"]), expected_group)
device.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(network.network_object, condition)
wd.unregister_psk_agent(psk_agent)
network.network_object.connect(wait=False)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
wd.wait(2)
testutil.test_iface_operstate(intf=device.name)
testutil.test_ifaces_connected(if0=device.name, if1=hostapd.ifname)
# Having connected once prior we should have a PMKSA and SAE should not
# have been used.
sta_status = hostapd.sta_status(device.address)
self.assertNotIn("sae_group", sta_status.keys())
device.disconnect()
condition = 'not obj.connected'
wd.wait_for_object_condition(network.network_object, condition)
hostapd.pmksa_flush()
wd.wait(5)
network.network_object.connect()
device.wait_for_event("pmksa-invalid-pmkid")
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
wd.wait(2)
testutil.test_iface_operstate(intf=device.name)
testutil.test_ifaces_connected(if0=device.name, if1=hostapd.ifname)
# Manually flushing the PMKSA from the AP then reconnecting we should
# have failed (INVALID_PMKID) then retried the same BSS with SAE, not
# PMKSA.
sta_status = hostapd.sta_status(device.address)
self.assertEqual(int(sta_status["sae_group"]), expected_group)
def test_pmksa_sae(self):
self.hostapd.wait_for_event("AP-ENABLED")
self.validate_connection(self.wd, "ssidSAE", self.hostapd, 19)
def setUp(self):
self.hostapd.default()
self.wd = IWD(True)
def tearDown(self):
self.wd.clear_storage()
self.wd = None
@classmethod
def setUpClass(cls):
cls.hostapd = HostapdCLI(config='ssidSAE.conf')
@classmethod
def tearDownClass(cls):
pass
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -1,7 +0,0 @@
[SETUP]
num_radios=2
start_iwd=0
hwsim_medium=yes
[HOSTAPD]
rad0=ssidSAE.conf

View File

@ -1,114 +0,0 @@
#! /usr/bin/python3
import unittest
import sys, os
sys.path.append('../util')
from iwd import IWD
from iwd import NetworkType
from hostapd import HostapdCLI
from packaging import version
from subprocess import run
import re
import testutil
#
# The CSA handling was added in kernel 6.8, so for any earlier kernel this test
# won't pass.
#
def kernel_is_newer(min_version="6.8"):
proc = run(["uname", "-r"], capture_output=True)
version_str = proc.stdout.decode("utf-8")
match = re.match(r"(\d+\.\d+)", version_str)
if not match:
return False
return version.parse(match.group(1)) >= version.parse(min_version)
class Test(unittest.TestCase):
def test_channel_switch_during_roam(self):
wd = self.wd
device = wd.list_devices(1)[0]
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
self.assertFalse(self.bss_hostapd[0].list_sta())
self.assertFalse(self.bss_hostapd[1].list_sta())
device.connect_bssid(self.bss_hostapd[0].bssid)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
testutil.test_iface_operstate(device.name)
testutil.test_ifaces_connected(self.bss_hostapd[0].ifname, device.name)
self.assertRaises(Exception, testutil.test_ifaces_connected,
(self.bss_hostapd[1].ifname, device.name, True, True))
# Start a channel switch and wait for it to begin
self.bss_hostapd[1].chan_switch(6, wait=False)
self.bss_hostapd[1].wait_for_event("CTRL-EVENT-STARTED-CHANNEL-SWITCH")
# Initiate a roam immediately which should get rejected by the kernel
device.roam(self.bss_hostapd[1].bssid)
# IWD should authenticate, then proceed to association
device.wait_for_event("ft-authenticating")
device.wait_for_event("ft-roaming")
# The kernel should reject the association, which should trigger a
# disconnect
condition = 'obj.state == DeviceState.disconnected'
wd.wait_for_object_condition(device, condition)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
def tearDown(self):
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
for hapd in self.bss_hostapd:
hapd.default()
self.wd.stop()
self.wd = None
def setUp(self):
self.wd = IWD(True)
@classmethod
def setUpClass(cls):
if not kernel_is_newer():
raise unittest.SkipTest()
IWD.copy_to_storage('TestFT.psk')
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
HostapdCLI(config='ft-psk-ccmp-2.conf'),
HostapdCLI(config='ft-psk-ccmp-3.conf') ]
unused = HostapdCLI(config='ft-psk-ccmp-3.conf')
unused.disable()
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
cls.bss_hostapd[2].set_address('12:00:00:00:00:03')
HostapdCLI.group_neighbors(*cls.bss_hostapd)
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
cls.bss_hostapd = None

View File

@ -1,112 +0,0 @@
#! /usr/bin/python3
import unittest
import sys, os
sys.path.append('../util')
import iwd
from iwd import IWD
from iwd import PSKAgent
from iwd import NetworkType
from hwsim import Hwsim
from hostapd import HostapdCLI
import testutil
class Test(unittest.TestCase):
def validate_connection(self, wd):
device = wd.list_devices(1)[0]
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
self.assertFalse(self.bss_hostapd[0].list_sta())
self.assertFalse(self.bss_hostapd[1].list_sta())
device.connect_bssid(self.bss_hostapd[0].bssid)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
testutil.test_iface_operstate(device.name)
testutil.test_ifaces_connected(self.bss_hostapd[0].ifname, device.name)
self.assertRaises(Exception, testutil.test_ifaces_connected,
(self.bss_hostapd[1].ifname, device.name, True, True))
self.rule0.enabled = True
device.roam(self.bss_hostapd[1].bssid)
device.clear_events()
device.wait_for_event("handshake-started")
self.bss_hostapd[1].deauthenticate(device.address, reason=15, test=1)
# Check that iwd is on BSS 1 once out of roaming state and doesn't
# go through 'disconnected', 'autoconnect', 'connecting' in between
from_condition = 'obj.state == DeviceState.roaming'
to_condition = 'obj.state == DeviceState.disconnected'
wd.wait_for_object_change(device, from_condition, to_condition)
def test_disconnect_during_handshake(self):
self.bss_hostapd[0].set_value('wpa_key_mgmt', 'WPA-PSK')
self.bss_hostapd[0].reload()
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
self.bss_hostapd[1].set_value('wpa_key_mgmt', 'WPA-PSK')
self.bss_hostapd[1].reload()
self.bss_hostapd[1].wait_for_event("AP-ENABLED")
self.validate_connection(self.wd)
def tearDown(self):
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
for hapd in self.bss_hostapd:
hapd.default()
self.wd.stop()
self.wd = None
def setUp(self):
self.wd = IWD(True)
@classmethod
def setUpClass(cls):
hwsim = Hwsim()
IWD.copy_to_storage('TestFT.psk')
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
HostapdCLI(config='ft-psk-ccmp-2.conf') ]
unused = HostapdCLI(config='ft-psk-ccmp-3.conf')
unused.disable()
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
rad1 = hwsim.get_radio('rad1')
cls.rule0 = hwsim.rules.create()
cls.rule0.destination = rad1.addresses[0]
cls.rule0.prefix = '08'
cls.rule0.drop = True
HostapdCLI.group_neighbors(*cls.bss_hostapd)
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
cls.bss_hostapd = None
cls.rule0.remove()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -149,21 +149,6 @@ class Test(unittest.TestCase):
condition = 'obj.state == DeviceState.disconnected'
self.wd.wait_for_object_condition(device, condition)
def test_ft_deauth_before_association(self):
self.rule2.enabled = True
self.rule3.enabled = True
device = self.wd.list_devices(1)[0]
self.connect(self.wd, device, self.bss_hostapd[0])
device.wait_for_event('ft-authenticating', timeout=60)
self.bss_hostapd[1].deauthenticate(device.address)
condition = 'obj.state == DeviceState.disconnected'
self.wd.wait_for_object_condition(device, condition)
def setUp(self):
self.wd = IWD(True)
@ -247,9 +232,6 @@ class Test(unittest.TestCase):
cls.rule2.remove()
cls.rule3.remove()
cls.assoc_rule.remove()
cls.rule_bss0.remove()
cls.rule_bss1.remove()
cls.rule_bss2.remove()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -13,7 +13,7 @@ wpa=2
wpa_key_mgmt=FT-PSK
wpa_pairwise=CCMP
wpa_passphrase=EasilyGuessedPassword
ieee80211w=0
ieee80211w=1
rsn_preauth=1
rsn_preauth_interfaces=lo
disable_pmksa_caching=0

View File

@ -13,7 +13,7 @@ wpa=2
wpa_key_mgmt=FT-PSK
wpa_pairwise=CCMP
wpa_passphrase=EasilyGuessedPassword
ieee80211w=0
ieee80211w=1
rsn_preauth=1
rsn_preauth_interfaces=lo
disable_pmksa_caching=0

View File

@ -13,7 +13,7 @@ wpa=2
wpa_key_mgmt=FT-PSK
wpa_pairwise=CCMP
wpa_passphrase=EasilyGuessedPassword
ieee80211w=0
ieee80211w=1
rsn_preauth=1
rsn_preauth_interfaces=lo
disable_pmksa_caching=0

View File

@ -3,6 +3,3 @@ DisableMacAddressRandomization=true
[General]
RoamRetryInterval=1
# For disconnect_during_handshake_test
ManagementFrameProtection=0

View File

@ -81,21 +81,12 @@ class Test(unittest.TestCase):
cls.bss_hostapd[0].set_value('ocv', '0')
cls.bss_hostapd[0].set_value('ieee80211w', '0')
rad0 = hwsim.get_radio('rad0')
rad1 = hwsim.get_radio('rad1')
cls.rule0 = hwsim.rules.create()
cls.rule0.source = rad0.addresses[0]
cls.rule0.source = 'any'
cls.rule0.bidirectional = True
cls.rule0.signal = -8000
cls.rule0.enabled = True
cls.rule1 = hwsim.rules.create()
cls.rule1.source = rad1.addresses[0]
cls.rule1.bidirectional = True
cls.rule1.signal = -8500
cls.rule1.enabled = True
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
@ -104,7 +95,6 @@ class Test(unittest.TestCase):
IWD.clear_storage()
cls.bss_hostapd = None
cls.rule0.remove()
cls.rule1.remove()
if __name__ == '__main__':
unittest.main(exit=True)

View File

@ -17,7 +17,7 @@ from hwsim import Hwsim
class Test(unittest.TestCase):
# Normally the time between a failed roam attempt and the next roam attempt
# is 60 seconds (default RoamRetryInterval). Test that we retry roaming
# faster if the transition looks like this: LOW [roam] [same bss] HIGH LOW.
# faster if the transision looks like this: LOW [roam] [same bss] HIGH LOW.
def test_fast_retry(self):
hwsim = Hwsim()

View File

@ -15,7 +15,7 @@ from hostapd import HostapdCLI
from hwsim import Hwsim
class Test(unittest.TestCase):
# Test that we do not periodically retry roaming if the transition looks
# Test that we do not periodically retry roaming if the transision looks
# like this: LOW [roam] [new bss] HIGH.
def test_stop_retry(self):
hwsim = Hwsim()

View File

@ -13,7 +13,7 @@ import testutil
from config import ctx
class Test(unittest.TestCase):
def validate_connection(self, wd, ft=True, check_used_pmksa=False):
def validate_connection(self, wd, ft=True):
device = wd.list_devices(1)[0]
# This won't guarantee all BSS's are found, but at least ensures that
@ -37,14 +37,6 @@ class Test(unittest.TestCase):
self.assertRaises(Exception, testutil.test_ifaces_connected,
(self.bss_hostapd[1].ifname, device.name, True, True))
# If PMKSA was used, hostapd should not include the sae_group key in
# its status for the station.
sta_status = self.bss_hostapd[0].sta_status(device.address)
if check_used_pmksa:
self.assertNotIn("sae_group", sta_status.keys())
else:
self.assertIn("sae_group", sta_status.keys())
device.roam(self.bss_hostapd[1].bssid)
# Check that iwd is on BSS 1 once out of roaming state and doesn't
@ -96,31 +88,6 @@ class Test(unittest.TestCase):
self.validate_connection(wd, True)
def test_ft_roam_pmksa(self):
wd = IWD(True)
self.bss_hostapd[0].set_value('wpa_key_mgmt', 'FT-SAE SAE')
self.bss_hostapd[0].reload()
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
self.bss_hostapd[1].set_value('wpa_key_mgmt', 'FT-SAE SAE')
self.bss_hostapd[1].reload()
self.bss_hostapd[1].wait_for_event("AP-ENABLED")
self.bss_hostapd[2].set_value('wpa_key_mgmt', 'FT-PSK')
self.bss_hostapd[2].reload()
self.bss_hostapd[2].wait_for_event("AP-ENABLED")
self.validate_connection(wd, True)
device = wd.list_devices(1)[0]
device.disconnect()
for hapd in self.bss_hostapd:
hapd.deauthenticate(device.address)
wd.wait(5)
self.validate_connection(wd, True, check_used_pmksa=True)
def test_reassociate_roam_success(self):
wd = IWD(True)
@ -136,31 +103,6 @@ class Test(unittest.TestCase):
self.validate_connection(wd, False)
def test_reassociate_roam_pmksa(self):
wd = IWD(True)
self.bss_hostapd[0].set_value('wpa_key_mgmt', 'SAE')
self.bss_hostapd[0].reload()
self.bss_hostapd[0].wait_for_event("AP-ENABLED")
self.bss_hostapd[1].set_value('wpa_key_mgmt', 'SAE')
self.bss_hostapd[1].reload()
self.bss_hostapd[1].wait_for_event("AP-ENABLED")
self.bss_hostapd[2].set_value('wpa_key_mgmt', 'WPA-PSK')
self.bss_hostapd[2].reload()
self.bss_hostapd[2].wait_for_event("AP-ENABLED")
self.validate_connection(wd, False)
device = wd.list_devices(1)[0]
device.disconnect()
for hapd in self.bss_hostapd:
hapd.deauthenticate(device.address)
wd.wait(5)
self.validate_connection(wd, False, check_used_pmksa=True)
def tearDown(self):
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')

View File

@ -52,6 +52,12 @@ class Test(unittest.TestCase):
self.hostapd.wait_for_event("AP-ENABLED")
self.validate_connection(self.wd, "ssidSAE", self.hostapd, 19)
def test_SAE_force_group_19(self):
# Vendor data from APs which require group 19 be used first
self.hostapd.reload()
self.hostapd.wait_for_event("AP-ENABLED")
self.validate_connection(self.wd, "ssidSAE-default-group", self.hostapd_defgroup, 19)
def test_SAE_Group20(self):
self.hostapd.set_value('sae_groups', '20')
self.hostapd.reload()
@ -82,6 +88,7 @@ class Test(unittest.TestCase):
def setUpClass(cls):
cls.hostapd = HostapdCLI(config='ssidSAE.conf')
cls.hostapd_h2e = HostapdCLI(config='ssidSAE-H2E.conf')
cls.hostapd_defgroup = HostapdCLI(config='ssidSAE-default-group.conf')
@classmethod
def tearDownClass(cls):

View File

@ -13,7 +13,7 @@ import testutil
class Test(unittest.TestCase):
def validate_connection(self, wd, hostapd, rejected=False):
def validate_connection(self, wd, rejected=False):
devices = wd.list_devices(1)
self.assertIsNotNone(devices)
device = devices[0]
@ -29,14 +29,14 @@ class Test(unittest.TestCase):
wd.wait(2)
testutil.test_iface_operstate(intf=device.name)
testutil.test_ifaces_connected(if0=device.name, if1=hostapd.ifname)
testutil.test_ifaces_connected(if0=device.name, if1=self.hostapd.ifname)
if not rejected:
self.assertEqual(device.event_ocurred("ecc-group-rejected"), False)
print(hostapd._get_status())
print(self.hostapd._get_status())
sta_status = hostapd.sta_status(device.address)
sta_status = self.hostapd.sta_status(device.address)
print(sta_status)
@ -51,27 +51,22 @@ class Test(unittest.TestCase):
# - Connect, try only group 19
def test_auto_selection(self):
IWD.copy_to_storage("profiles/ssidSAE.psk.default", name="ssidSAE.psk")
self.validate_connection(self.wd, self.hostapd, rejected=True)
self.validate_connection(self.wd, rejected=True)
self.validate_connection(self.wd, self.hostapd, rejected=False)
self.validate_connection(self.wd, rejected=False)
# Try group 19 first
def test_default_group_enabled(self):
IWD.copy_to_storage("profiles/ssidSAE.psk.default_group", name="ssidSAE.psk")
self.validate_connection(self.wd, self.hostapd)
# Try group 19 first, with H2E
def test_default_group_enabled_h2e(self):
IWD.copy_to_storage("profiles/ssidSAE-H2E.psk.default_group", name="ssidSAE-H2E.psk")
self.validate_connection(self.wd, self.hostapd_h2e)
self.validate_connection(self.wd)
# Same as auto-selection but won't retain the default group setting
def test_default_group_disabled(self):
IWD.copy_to_storage("profiles/ssidSAE.psk.most_secure", name="ssidSAE.psk")
self.validate_connection(self.wd, self.hostapd, rejected=True)
self.validate_connection(self.wd, rejected=True)
# IWD should then retry but use only group 19
self.validate_connection(self.wd, self.hostapd, rejected=True)
self.validate_connection(self.wd, rejected=True)
def setUp(self):
self.hostapd.default()
@ -93,9 +88,6 @@ class Test(unittest.TestCase):
cls.hostapd = HostapdCLI(config='ssidSAE.conf')
cls.hostapd.default()
cls.hostapd_h2e = HostapdCLI(config='ssidSAE-H2E.conf')
cls.hostapd_h2e.default()
@classmethod
def tearDownClass(cls):
pass

View File

@ -1,8 +1,9 @@
[SETUP]
num_radios=3
num_radios=4
start_iwd=0
hwsim_medium=yes
[HOSTAPD]
rad0=ssidSAE.conf
rad1=ssidSAE-H2E.conf
rad2=ssidSAE-default-group.conf

View File

@ -4,6 +4,3 @@
# hardware, but fails when used in simulated environment with mac80211_hwsim.
# Disable MAC randomization for the tests with hidden networks.
DisableMacAddressRandomization=true
[General]
DisablePMKSA=true

View File

@ -1,5 +0,0 @@
[Security]
Passphrase=secret123
[Settings]
UseDefaultEccGroup=true

View File

@ -1,6 +1,6 @@
hw_mode=g
channel=1
ssid=ssidSAE
ssid=ssidSAE-default-group
wpa=2
wpa_key_mgmt=SAE
@ -9,4 +9,4 @@ sae_password=secret123
sae_groups=19
ieee80211w=2
sae_pwe=0
rsn_preauth=1
vendor_elements=dd0cf4f5e8050500000000000000

View File

@ -8,12 +8,11 @@ import iwd
from iwd import IWD
from iwd import PSKAgent
from iwd import NetworkType
from hostapd import HostapdCLI
import testutil
class Test(unittest.TestCase):
def test_incorrect_password(self):
def test_connection_success(self):
wd = IWD(True)
psk_agent = PSKAgent("InvalidPassword")
@ -35,35 +34,6 @@ class Test(unittest.TestCase):
wd.unregister_psk_agent(psk_agent)
def test_deauth_after_connection(self):
wd = IWD(True)
hostapd = HostapdCLI(config="ssidWPA2.conf")
psk_agent = PSKAgent("secret123")
wd.register_psk_agent(psk_agent)
devices = wd.list_devices(1)
self.assertIsNotNone(devices)
device = devices[0]
ordered_network = device.get_ordered_network('ssidWPA2')
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
ordered_network.network_object.connect(wait=False)
device.wait_for_event("authenticating")
# Trigger a deauth just after authenticating
hostapd.deauthenticate(device.address)
device.wait_for_event("disconnected")
wd.unregister_psk_agent(psk_agent)
@classmethod
def setUpClass(cls):
pass

View File

@ -184,12 +184,8 @@ class HostapdCLI(object):
cmd = self.cmdline + ['wps_pin', 'any', pin]
ctx.start_process(cmd).wait()
def deauthenticate(self, client_address, reason=None, test=None):
def deauthenticate(self, client_address):
cmd = self.cmdline + ['deauthenticate', client_address]
if reason:
cmd.append(f"reason={reason} test={test}")
ctx.start_process(cmd).wait()
def eapol_reauth(self, client_address):
@ -288,15 +284,13 @@ class HostapdCLI(object):
cmd = 'RESEND_M3 %s' % address
self.ctrl_sock.sendall(cmd.encode('utf-8'))
def chan_switch(self, channel, wait=True):
def chan_switch(self, channel):
if channel > len(chan_freq_map):
raise Exception("Only 2.4GHz channels supported for chan_switch")
cmd = self.cmdline + ['chan_switch', '50', str(chan_freq_map[channel])]
ctx.start_process(cmd).wait()
if wait:
self.wait_for_event('AP-CSA-FINISHED')
self.wait_for_event('AP-CSA-FINISHED')
def _get_status(self):
ret = {}
@ -370,7 +364,3 @@ class HostapdCLI(object):
others = [h for h in args if h != hapd]
hapd._add_neighbors(*others)
def pmksa_flush(self):
cmd = self.cmdline + ['pmksa_flush']
ctx.start_process(cmd).wait()

View File

@ -7,10 +7,7 @@ from weakref import WeakValueDictionary
from abc import ABCMeta, abstractmethod
from enum import Enum
from scapy.all import *
try:
from scapy.contrib.wpa_eapol import WPA_key
except:
from scapy.layers.eap import EAPOL_KEY
from scapy.contrib.wpa_eapol import WPA_key
import iwd
from config import ctx
@ -447,15 +444,9 @@ class Hwsim(iwd.AsyncOpAbstract):
# NOTE: Expected key_info is 0x008a, with the install flag
# this becomes 0x00ca.
try:
eapol = WPA_key( descriptor_type = 2,
key_info = 0x00ca, # Includes an invalid install flag!
replay_counter = struct.pack(">Q", 100))
except:
eapol = EAPOL_KEY( key_descriptor_type = 2,
install = 1,
key_ack = 1,
key_replay_counter = 1)
eapol = WPA_key( descriptor_type = 2,
key_info = 0x00ca, # Includes an invalid install flag!
replay_counter = struct.pack(">Q", 100))
frame /= LLC()/SNAP()/EAPOL(version="802.1X-2004", type="EAPOL-Key")
frame /= eapol

View File

@ -112,8 +112,8 @@ class AsyncOpAbstract(object):
self._is_completed = True
self._exception = _convert_dbus_ex(ex)
def _wait_for_async_op(self, timeout=50):
ctx.non_block_wait(lambda s: s._is_completed, timeout, self, exception=None)
def _wait_for_async_op(self):
ctx.non_block_wait(lambda s: s._is_completed, 30, self, exception=None)
self._is_completed = False
if self._exception is not None:
@ -280,15 +280,8 @@ class StationDebug(IWDDBusAbstract):
def autoconnect(self):
return self._properties['AutoConnect']
def connect_bssid(self, address, wait=True):
self._iface.ConnectBssid(
dbus.ByteArray.fromhex(address.replace(':', '')),
reply_handler=self._success,
error_handler=self._failure
)
if wait:
self._wait_for_async_op()
def connect_bssid(self, address):
self._iface.ConnectBssid(dbus.ByteArray.fromhex(address.replace(':', '')))
def roam(self, address):
self._iface.Roam(dbus.ByteArray.fromhex(address.replace(':', '')))
@ -306,9 +299,6 @@ class StationDebug(IWDDBusAbstract):
return False
def clear_events(self):
self._events = []
def wait_for_event(self, event, timeout=10):
return ctx.non_block_wait(self._poll_event, timeout, event,
exception=TimeoutError("waiting for event"))
@ -457,15 +447,13 @@ class Device(IWDDBusAbstract):
self._wps_manager_if = None
self._station_if = None
self._station_props = None
self._station_debug_obj = None
self._dpp_obj = None
self._sc_dpp_obj = None
self._ap_obj = None
IWDDBusAbstract.__init__(self, *args, **kwargs)
self._station_debug_obj = StationDebug(object_path=self._object_path,
namespace=self._namespace)
@property
def _wps_manager(self):
if self._wps_manager_if is None:
@ -605,11 +593,6 @@ class Device(IWDDBusAbstract):
props = self._station_properties()
return props.get('ConnectedNetwork')
@property
def connected_bss(self):
props = self._station_properties()
return props.get('ConnectedAccessPoint')
@property
def powered(self):
'''
@ -644,19 +627,6 @@ class Device(IWDDBusAbstract):
self._station_debug._prop_proxy.Set(IWD_STATION_DEBUG_INTERFACE,
'AutoConnect', value)
@property
def affinities(self):
return self._station_properties()['Affinities']
@affinities.setter
def affinities(self, values):
self._station_properties()
self._station_prop_if.Set(
IWD_STATION_INTERFACE, 'Affinities',
dbus.Array([dbus.ObjectPath(v) for v in values], signature="o"),
reply_handler=self._success, error_handler=self._failure)
self._wait_for_async_op()
def scan(self, wait=True):
'''Schedule a network scan.
@ -877,8 +847,8 @@ class Device(IWDDBusAbstract):
def stop_adhoc(self):
self._prop_proxy.Set(IWD_DEVICE_INTERFACE, 'Mode', 'station')
def connect_bssid(self, address, wait=True):
self._station_debug.connect_bssid(address, wait=wait)
def connect_bssid(self, address):
self._station_debug.connect_bssid(address)
def roam(self, address):
self._station_debug.roam(address)
@ -889,9 +859,6 @@ class Device(IWDDBusAbstract):
def wait_for_event(self, event, timeout=10):
self._station_debug.wait_for_event(event, timeout)
def clear_events(self):
self._station_debug.clear_events()
def event_ocurred(self, event):
return self._station_debug.event_ocurred(event)
@ -1002,11 +969,7 @@ class Network(IWDDBusAbstract):
'''
return bool(self._properties['Connected'])
@property
def extended_service_set(self):
return self._properties['ExtendedServiceSet']
def connect(self, wait=True, timeout=50, reply_handler=None, error_handler=None):
def connect(self, wait=True):
'''
Connect to the network. Request the device implied by the object
path to connect to specified network.
@ -1021,19 +984,12 @@ class Network(IWDDBusAbstract):
@rtype: void
'''
if not reply_handler:
reply_handler = self._success
if not error_handler:
error_handler = self._failure
self._iface.Connect(dbus_interface=self._iface_name,
reply_handler=reply_handler,
error_handler=error_handler,
timeout=timeout)
reply_handler=self._success,
error_handler=self._failure)
if wait:
self._wait_for_async_op(timeout=timeout)
self._wait_for_async_op()
def __str__(self, prefix = ''):
return prefix + 'Network:\n' \
@ -1497,10 +1453,10 @@ class IWD(AsyncOpAbstract):
@staticmethod
def create_in_storage(file_name, file_content, storage_dir=IWD_STORAGE_DIR):
f = open(storage_dir + '/' + file_name, 'w')
fo = open(storage_dir + '/' + file_name, 'w')
f.write(file_content)
f.close()
fo.write(file_content)
fo.close()
@staticmethod
def _ensure_storage_dir_exists(storage_dir):

View File

@ -237,7 +237,7 @@ class Wpas:
('' if go_intent is None else ' go_intent=' + str(go_intent)))
self.wait_for_event('OK')
# Pre-accept the next GO Negotiation Request from this peer to avoid the extra Response + Request frames
# Pre-accept the next GO Negotiation Request from this peer to avoid the extra Respone + Request frames
def p2p_authorize(self, peer, pin=None, go_intent=None):
self._rx_data = []
self._ctrl_request('P2P_CONNECT ' + peer['p2p_dev_addr'] + ' ' + ('pbc' if pin is None else pin) +

View File

@ -1,109 +0,0 @@
/*
*
* Wireless daemon for Linux
*
* Copyright (C) 2024, Locus Robotics
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <ell/ell.h>
#include "ell/useful.h"
#include "client/dbus-proxy.h"
#include "client/display.h"
struct bss {
char *address;
};
static const char *get_address(const void *data)
{
const struct bss *bss = data;
return bss->address;
}
static void update_address(void *data, struct l_dbus_message_iter *variant)
{
struct bss *bss = data;
const char *value;
l_free(bss->address);
if (!l_dbus_message_iter_get_variant(variant, "s", &value)) {
bss->address = NULL;
return;
}
bss->address = l_strdup(value);
}
static const struct proxy_interface_property bss_properties[] = {
{ "Address", "s", update_address, get_address },
{ }
};
static void *bss_create(void)
{
return l_new(struct bss, 1);
}
static void bss_destroy(void *data)
{
struct bss *bss = data;
l_free(bss->address);
l_free(bss);
}
static void bss_display_inline(const char *margin, const void *data)
{
const struct bss *bss = data;
display("%s%s\n", margin, bss->address);
}
static const struct proxy_interface_type_ops ops = {
.create = bss_create,
.destroy = bss_destroy,
.display = bss_display_inline,
};
static struct proxy_interface_type bss_interface_type = {
.interface = IWD_BSS_INTERFACE,
.properties = bss_properties,
.ops = &ops,
};
static int bss_interface_init(void)
{
proxy_interface_type_register(&bss_interface_type);
return 0;
}
static void bss_interface_exit(void)
{
proxy_interface_type_unregister(&bss_interface_type);
}
INTERFACE_TYPE(bss_interface_type, bss_interface_init, bss_interface_exit)

View File

@ -47,10 +47,10 @@ static struct l_dbus *dbus;
static struct l_queue *proxy_interfaces;
static struct l_queue *proxy_interface_types;
void proxy_properties_display_inline(const struct proxy_interface *proxy,
const char *margin,
unsigned int name_column_width,
unsigned int value_column_width)
void proxy_properties_display(const struct proxy_interface *proxy,
const char *caption, const char *margin,
unsigned int name_column_width,
unsigned int value_column_width)
{
const void *data;
const struct proxy_interface_property *properties;
@ -59,6 +59,11 @@ void proxy_properties_display_inline(const struct proxy_interface *proxy,
if (!proxy->type->properties)
return;
display_table_header(caption, "%s%-*s %-*s %-*s", margin,
8, "Settable",
name_column_width, "Property",
value_column_width, "Value");
data = proxy_interface_get_data(proxy);
properties = proxy->type->properties;
@ -77,31 +82,6 @@ void proxy_properties_display_inline(const struct proxy_interface *proxy,
}
}
void proxy_properties_display_header(const char *caption, const char *margin,
unsigned int name_column_width,
unsigned int value_column_width)
{
display_table_header(caption, "%s%-*s %-*s %-*s", margin,
8, "Settable",
name_column_width, "Property",
value_column_width, "Value");
}
void proxy_properties_display(const struct proxy_interface *proxy,
const char *caption, const char *margin,
unsigned int name_column_width,
unsigned int value_column_width)
{
if (!proxy->type->properties)
return;
proxy_properties_display_header(caption, margin, name_column_width,
value_column_width);
proxy_properties_display_inline(proxy, margin, name_column_width,
value_column_width);
}
static const void *proxy_interface_property_tostr(
const struct proxy_interface *proxy,
const char *name)

View File

@ -41,7 +41,6 @@ struct proxy_interface;
#define IWD_DPP_INTERFACE "net.connman.iwd.DeviceProvisioning"
#define IWD_DPP_PKEX_INTERFACE \
"net.connman.iwd.SharedCodeDeviceProvisioning"
#define IWD_BSS_INTERFACE "net.connman.iwd.BasicServiceSet"
typedef bool (*proxy_property_match_func_t) (const void *a, const void *b);
@ -96,13 +95,6 @@ void proxy_properties_display(const struct proxy_interface *proxy,
const char *caption, const char *margin,
unsigned int name_column_width,
unsigned int value_column_width);
void proxy_properties_display_inline(const struct proxy_interface *proxy,
const char *margin,
unsigned int name_column_width,
unsigned int value_column_width);
void proxy_properties_display_header(const char *caption, const char *margin,
unsigned int name_column_width,
unsigned int value_column_width);
char *proxy_property_str_completion(const struct proxy_interface_type *type,
proxy_property_match_func_t function,

View File

@ -95,8 +95,6 @@ static const struct diagnostic_dict_mapping diagnostic_mapping[] = {
{ "Frequency", 'u' },
{ "Channel", 'q' },
{ "Security", 's' },
{ "InactiveTime", 'u', "ms" },
{ "ConnectedTime", 'u', "s" },
{ NULL }
};
@ -188,5 +186,5 @@ void diagnostic_display(struct l_dbus_message_iter *dict,
return;
parse_error:
display_error("Error parsing diagnostics");
display_error("Error parsing dignostics");
}

View File

@ -35,7 +35,6 @@ struct network {
char *identity;
char *name;
char *type;
struct l_queue *bss_list;
const struct proxy_interface *device;
};
@ -147,58 +146,11 @@ static void update_type(void *data, struct l_dbus_message_iter *variant)
network->type = l_strdup(value);
}
static bool match_path(const void *a, const void *user_data)
{
const char *path1 = a;
const char *path2 = user_data;
return !strcmp(path1, path2);
}
static void update_ess(void *data, struct l_dbus_message_iter *variant)
{
struct network *network = data;
struct l_dbus_message_iter array;
const char *path;
if (!network->bss_list)
network->bss_list = l_queue_new();
if (!l_dbus_message_iter_get_variant(variant, "ao", &array))
return;
while (l_dbus_message_iter_next_entry(&array, &path)) {
l_free(l_queue_remove_if(network->bss_list, match_path, path));
l_queue_push_head(network->bss_list, l_strdup(path));
}
}
static const char *get_ess(const void *data)
{
const struct network *network = data;
static char count[10];
snprintf(count, 10, "Count %u", l_queue_length(network->bss_list));
return count;
}
struct l_queue *network_get_bss_list(
const struct proxy_interface *network_proxy)
{
const struct network *network = proxy_interface_get_data(network_proxy);
if (!network)
return NULL;
return network->bss_list;
}
static const struct proxy_interface_property network_properties[] = {
{ "Name", "s", update_name, get_name },
{ "Connected", "b", update_connected},
{ "Device", "o", update_device},
{ "Type", "s", update_type},
{ "ExtendedServiceSet", "ao", update_ess, get_ess },
{ }
};
@ -219,7 +171,7 @@ static void network_display_inline(const char *margin, const void *data)
display("%s%s %s %s\n", margin, network->name ? network->name : "",
network->type ? network->type : "",
network->connected ? "connected" : "disconnected");
network->connected ? "connected" : "diconnected");
}
static void *network_create(void)
@ -234,7 +186,6 @@ static void network_destroy(void *data)
l_free(network->name);
l_free(network->type);
l_free(network->identity);
l_queue_destroy(network->bss_list, l_free);
network->device = NULL;

View File

@ -37,5 +37,3 @@ char *network_name_completion(const struct proxy_interface *device,
struct l_queue *network_match_by_device_and_args(
const struct proxy_interface *device,
const struct network_args *args);
struct l_queue *network_get_bss_list(
const struct proxy_interface *network_proxy);

View File

@ -175,8 +175,8 @@ static void display_addresses(const char *device_name)
continue;
have_address = true;
display_table_row(MARGIN, 3, 8, "", 20,
"IPv6 address", 47, addrstr);
display("%s%*s %-*s%-*s\n", MARGIN, 8, "", 20,
"IPv6 address", 47, addrstr);
} else if (cur->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *si =
(struct sockaddr_in *) cur->ifa_addr;
@ -283,26 +283,28 @@ static char *connect_cmd_arg_completion(const char *text, int state,
return network_name_completion(device, text, state);
}
static const struct proxy_interface *find_network(const char *device_name,
const char *name,
const char *type)
static enum cmd_status cmd_connect(const char *device_name,
char **argv, int argc)
{
struct network_args network_args;
struct l_queue *match;
const struct proxy_interface *network_proxy;
const struct proxy_interface *device_proxy;
if (argc < 1)
return CMD_STATUS_INVALID_ARGS;
device_proxy = device_proxy_find_by_name(device_name);
if (!device_proxy)
return NULL;
return CMD_STATUS_INVALID_VALUE;
network_args.name = name;
network_args.type = type;
network_args.name = argv[0];
network_args.type = argc >= 2 ? argv[1] : NULL;
match = network_match_by_device_and_args(device_proxy, &network_args);
if (!match) {
display("Invalid network name '%s'\n", network_args.name);
return NULL;
return CMD_STATUS_INVALID_VALUE;
}
if (l_queue_length(match) > 1) {
@ -313,28 +315,11 @@ static const struct proxy_interface *find_network(const char *device_name,
l_queue_destroy(match, NULL);
return NULL;
return CMD_STATUS_INVALID_VALUE;
}
network_proxy = l_queue_pop_head(match);
l_queue_destroy(match, NULL);
return network_proxy;
}
static enum cmd_status cmd_connect(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *network_proxy;
if (argc < 1)
return CMD_STATUS_INVALID_ARGS;
network_proxy = find_network(device_name, argv[0],
argc >= 2 ? argv[1] : NULL);
if (!network_proxy)
return CMD_STATUS_INVALID_VALUE;
network_connect(network_proxy);
return CMD_STATUS_TRIGGERED;
@ -723,55 +708,6 @@ static enum cmd_status cmd_show(const char *device_name,
return CMD_STATUS_TRIGGERED;
}
static enum cmd_status cmd_get_bsses(const char *device_name,
char **argv, int argc)
{
const struct proxy_interface *station_i =
device_proxy_find(device_name, IWD_STATION_INTERFACE);
const struct station *station = proxy_interface_get_data(station_i);
struct l_queue *bss_list;
const struct l_queue_entry *e;
const struct proxy_interface *network_proxy;
char header[256];
if (argc > 0)
network_proxy = find_network(device_name, argv[0],
argc >= 2 ? argv[1] : NULL);
else
network_proxy = station->connected_network;
if (!network_proxy) {
display_error("Can't find network");
return CMD_STATUS_INVALID_ARGS;
}
bss_list = network_get_bss_list(network_proxy);
if (!bss_list) {
display_error("No BSS list for network");
return CMD_STATUS_FAILED;
}
sprintf(header, "%s BasicServiceSets", network_get_name(network_proxy));
proxy_properties_display_header(header, MARGIN, 10, 18);
for (e = l_queue_get_entries(bss_list); e; e = e->next) {
const char *path = e->data;
const struct proxy_interface *bss_i = proxy_interface_find(
IWD_BSS_INTERFACE, path);
if (!bss_i)
continue;
display_table_row(MARGIN, 1, strlen(path), path);
proxy_properties_display_inline(bss_i, MARGIN, 10, 18);
display_table_row(MARGIN, 1, 1, "");
}
return CMD_STATUS_DONE;
}
static const struct command station_commands[] = {
{ NULL, "list", NULL, cmd_list, "List devices in Station mode", true },
{ "<wlan>", "connect",
@ -796,8 +732,6 @@ static const struct command station_commands[] = {
"Get hidden APs", true },
{ "<wlan>", "scan", NULL, cmd_scan, "Scan for networks" },
{ "<wlan>", "show", NULL, cmd_show, "Show station info", true },
{ "<wlan>", "get-bsses", "[network] [security]", cmd_get_bsses,
"Get BSS's for a network", true },
{ }
};

View File

@ -1,12 +1,10 @@
AC_PREREQ([2.69])
AC_INIT([iwd],[3.10])
AC_INIT([iwd],[2.17])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_AUX_DIR(build-aux)
AC_CONFIG_MACRO_DIR(build-aux)
AC_REQUIRE_AUX_FILE([tap-driver.sh])
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests silent-rules
tar-pax no-dist-gzip dist-xz])
@ -31,7 +29,6 @@ AC_PROG_CC_GCOV
AC_PROG_INSTALL
AC_PROG_MKDIR_P
AC_PROG_LN_S
AC_PROG_AWK
AC_SYS_LARGEFILE
@ -300,7 +297,7 @@ if (test "${enable_external_ell}" = "yes"); then
test "${enable_monitor}" != "no" ||
test "${enable_wired}" = "yes" ||
test "${enable_hwsim}" = "yes"); then
ell_min_version="0.77"
ell_min_version="0.64"
else
ell_min_version="0.5"
fi

View File

@ -31,12 +31,6 @@ Methods array{dict} GetDiagnostics()
TxMCS [optional] - Transmitting MCS index
InactiveTime [optional] - Time duration (in ms) for which the STA
connected to this BSS is currently inactive.
ConnectedTime [optional] - Time duration (in s) for which the STA
remains connected to this BSS.
Possible errors: net.connman.iwd.Failed
net.connman.iwd.NotConnected
net.connman.iwd.NotFound

View File

@ -1,10 +0,0 @@
Basic service set hierarchy
=================
Service net.connman.iwd
Interface net.connman.iwd.BasicServiceSet
Object path /net/connman/iwd/{phy0,phy1,...}/{1,2,...}/Xxx
Properties string Address [readonly]
MAC address of BSS

View File

@ -322,10 +322,10 @@ M18: Use appropriate logging levels
An appropriate log level should be used depending on the type of message
being logged. Logging is done using the l_log APIs in ELL:
l_error An unexpected condition occurred. These are generally fatal to the
l_error An unexpected condition ocurred. These are generally fatal to the
current connection/protocol that is running but not generally to IWD's
overall operation.
l_warn An unexpected, but non-fatal condition occurred
l_warn An unexpected, but non-fatal condition ocurred
l_notice Should not be used directly. This log level is reserved for special
event type notifications which is handled by iwd_notice().
l_info Information that is expected during normal operation. l_info's use

View File

@ -135,7 +135,7 @@ Object path /net/connman/iwd/{phy0,phy1,...}/{1,2,...}
void StartConfigurator(object agent_path)
Start a shared code configurator using an agent
(distinguished by 'agent_path') to obtain the shared
(distingushed by 'agent_path') to obtain the shared
code. This method is meant for an automated use case
where a configurator is capable of configuring multiple
enrollees, and distinguishing between them by their
@ -196,7 +196,7 @@ Methods void Release() [noreply]
string RequestSharedCode(string identifier)
This method gets called when a shared code is requested
for a particular enrollee, distinguished by the
for a particular enrollee, distingushed by the
identifier. The shared code agent should lookup the
identifier and return the shared code, or return an
error if not found.

View File

@ -5,7 +5,7 @@ credentials for your e.g. cable/cellular provider, or via a dedicated account
like Boingo. Lots of these services also allow you to roam between networks.
The underlying authentication is standard WPA2-Enterprise but Hotspot 2.0 adds a
'discovery' stage to identifying networks. This discovery is done using ANQP,
'discovery' stage to identifiying networks. This discovery is done using ANQP,
which queries the network for additional information to determine if the client
has the credentials to connect.

View File

@ -11,12 +11,6 @@ Methods void Connect()
the object path to connect to specified network.
Connecting to WEP networks is not supported.
Note: When [General].EnableNetworkConfiguration is set
to true a call to Connect() has the potential to take
a significant amount of time. Specifically if DHCP is
either slow, or is unable to complete. The timeout for
DHCP is roughly 30 seconds per BSS.
Possible errors: net.connman.iwd.Aborted
net.connman.iwd.Busy
net.connman.iwd.Failed
@ -56,8 +50,3 @@ Properties string Name [readonly]
corresponding to this Network. If the network
is not provisioned or has not been connected to
before, the property is omitted.
array(object) ExtendedServiceSet [readonly]
Contains a list of paths of each individual
BasicServiceSet object.

View File

@ -56,7 +56,7 @@ Methods array(on) GetPeers()
between requested threshold values is a compromise
between resolution and the frequency of system
wakeups and context-switches that are going to be
occurring to update the client's signal meter. Only
occuring to update the client's signal meter. Only
one agent can be registered at any time.
Possible errors: [service].Error.InvalidArguments

View File

@ -164,29 +164,6 @@ Properties string State [readonly]
for networks. net.connman.iwd.Network objects are
updated when this property goes from true to false.
object ConnectedAccessPoint [readonly, optional]
net.connman.iwd.BasicServiceSet object representing the
BSS the device is currently connected to or to which
a connection is in progress.
ao Affinities [optional] [experimental]
Array of net.connman.iwd.BasicServiceSet object paths
that will be treated with higher affinity compared to
other BSS's. Currently the only allowed value to be
set in this array is the path to the currently connected
BasicServiceSet object, i.e.
Station.ConnectedAccessPoint.
Setting the affinity will lower the roaming threshold,
effectively locking IWD to the current BSS unless the
RSSI drops below the critical threshold set by
[General].CriticalRoamThreshold{5G} at which point
IWD will proceed with normal roaming behavior.
This property is cleared on roams/disconnections.
SignalLevelAgent hierarchy
==========================

View File

@ -53,12 +53,6 @@ Methods dict GetDiagnostics()
- GCMP-256
- CCMP-256
InactiveTime [optional] - Time duration (in ms) for which this STA
is currently inactive.
ConnectedTime [optional] - Time Duration (in s) for which this STA
remains connected to the BSS.
Possible errors: net.connman.iwd.Busy
net.connman.iwd.Failed
net.connman.iwd.NotConnected

View File

@ -218,7 +218,7 @@ supplicant running IWD:
#~~~~~~~~~~~~~~~~~~~~~~~~~ hw.conf ~~~~~~~~~~~~~~~~~~~~~~~~~
# Lines starting with # are ignored
# 'SETUP' is a mandatory configuration group.
# 'SETUP' is a manditory configuration group.
[SETUP]
#
# Total number of radios requested per network setup. This includes

View File

@ -224,42 +224,129 @@ struct iwmon_interface {
char *ifname;
bool exists;
struct l_netlink *rtnl;
struct l_genl *genl;
struct l_netlink *genl;
struct l_io *io;
};
static struct iwmon_interface monitor_interface = { };
static void nl80211_appeared(const struct l_genl_family_info *info,
void *user_data)
static void genl_parse(uint16_t type, const void *data, uint32_t len,
const char *ifname)
{
const char *ifname = user_data;
const struct genlmsghdr *genlmsg = data;
const struct nlattr *nla;
char name[GENL_NAMSIZ];
uint16_t id = 0;
if (nlmon)
return;
if (type != GENL_ID_CTRL)
return;
if (genlmsg->cmd != CTRL_CMD_NEWFAMILY)
return;
for (nla = data + GENL_HDRLEN; NLA_OK(nla, len);
nla = NLA_NEXT(nla, len)) {
switch (nla->nla_type & NLA_TYPE_MASK) {
case CTRL_ATTR_FAMILY_ID:
id = *((uint16_t *) NLA_DATA(nla));
break;
case CTRL_ATTR_FAMILY_NAME:
strncpy(name, NLA_DATA(nla), GENL_NAMSIZ - 1);
break;
}
}
if (id == 0)
return;
if (strcmp(name, NL80211_GENL_NAME))
return;
monitor_interface.io = open_packet(ifname);
if (!monitor_interface.io)
goto failed;
nlmon = nlmon_open(l_genl_family_info_get_id(info),
writer_path, &config);
nlmon = nlmon_open(id, writer_path, &config);
if (!nlmon)
goto failed;
l_io_set_read_handler(monitor_interface.io, nlmon_receive, nlmon, NULL);
return;
failed:
l_main_quit();
}
static struct l_genl *genl_lookup(const char *ifname)
static void genl_notify(uint16_t type, const void *data,
uint32_t len, void *user_data)
{
struct l_genl *genl = l_genl_new();
const char *ifname = user_data;
genl_parse(type, data, len, ifname);
}
static void genl_callback(int error, uint16_t type, const void *data,
uint32_t len, void *user_data)
{
const char *ifname = user_data;
if (error < 0) {
fprintf(stderr, "Failed to lookup nl80211 family\n");
l_main_quit();
return;
}
genl_parse(type, data, len, ifname);
}
static struct l_netlink *genl_lookup(const char *ifname)
{
struct l_netlink *genl;
char buf[GENL_HDRLEN + NLA_HDRLEN + GENL_NAMSIZ];
struct genlmsghdr *genlmsg;
struct nlattr *nla;
genl = l_netlink_new(NETLINK_GENERIC);
l_netlink_register(genl, GENL_ID_CTRL, genl_notify, NULL, NULL);
genlmsg = (struct genlmsghdr *) buf;
genlmsg->cmd = CTRL_CMD_GETFAMILY;
genlmsg->version = 0;
genlmsg->reserved = 0;
nla = (struct nlattr *) (buf + GENL_HDRLEN);
nla->nla_len = NLA_HDRLEN + GENL_NAMSIZ;
nla->nla_type = CTRL_ATTR_FAMILY_NAME;
strncpy(buf + GENL_HDRLEN + NLA_HDRLEN,
NL80211_GENL_NAME, GENL_NAMSIZ);
l_netlink_send(genl, GENL_ID_CTRL, 0, buf, sizeof(buf),
genl_callback, (char *) ifname, NULL);
l_genl_request_family(genl, NL80211_GENL_NAME, nl80211_appeared,
(char *) ifname, NULL);
return genl;
}
static size_t rta_add(void *rta_buf, unsigned short type, uint16_t len,
const void *data)
{
unsigned short rta_len = RTA_LENGTH(len);
struct rtattr *rta = rta_buf;
memset(RTA_DATA(rta), 0, RTA_SPACE(len));
rta->rta_len = rta_len;
rta->rta_type = type;
if (len)
memcpy(RTA_DATA(rta), data, len);
return RTA_SPACE(len);
}
static bool rta_linkinfo_kind(struct rtattr *rta, unsigned short len,
const char* kind)
{
@ -288,9 +375,10 @@ static struct l_netlink *rtm_interface_send_message(struct l_netlink *rtnl,
{
size_t nlmon_type_len = strlen(NLMON_TYPE);
unsigned short ifname_len = 0;
struct l_netlink_message *nlm;
struct ifinfomsg ifi;
uint16_t flags = 0;
size_t bufsize;
struct ifinfomsg *rtmmsg;
void *rta_buf;
struct rtattr *linkinfo_rta;
if (ifname) {
ifname_len = strlen(ifname) + 1;
@ -299,41 +387,64 @@ static struct l_netlink *rtm_interface_send_message(struct l_netlink *rtnl,
return NULL;
}
if (!L_IN_SET(rtm_msg_type, RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK))
return NULL;
if (!rtnl)
rtnl = l_netlink_new(NETLINK_ROUTE);
if (!rtnl)
return NULL;
memset(&ifi, 0, sizeof(ifi));
ifi.ifi_family = AF_UNSPEC;
ifi.ifi_change = ~0;
bufsize = NLMSG_LENGTH(sizeof(struct ifinfomsg)) +
RTA_SPACE(ifname_len) + RTA_SPACE(0) +
RTA_SPACE(nlmon_type_len);
rtmmsg = l_malloc(bufsize);
memset(rtmmsg, 0, bufsize);
rtmmsg->ifi_family = AF_UNSPEC;
rtmmsg->ifi_change = ~0;
rta_buf = rtmmsg + 1;
if (ifname)
rta_buf += rta_add(rta_buf, IFLA_IFNAME, ifname_len, ifname);
linkinfo_rta = rta_buf;
rta_buf += rta_add(rta_buf, IFLA_LINKINFO, 0, NULL);
rta_buf += rta_add(rta_buf, IFLA_INFO_KIND, nlmon_type_len, NLMON_TYPE);
linkinfo_rta->rta_len = rta_buf - (void *) linkinfo_rta;
switch (rtm_msg_type) {
case RTM_NEWLINK:
ifi.ifi_flags = IFF_UP | IFF_ALLMULTI | IFF_NOARP;
flags = NLM_F_CREATE | NLM_F_EXCL;
rtmmsg->ifi_flags = IFF_UP | IFF_ALLMULTI | IFF_NOARP;
l_netlink_send(rtnl, RTM_NEWLINK, NLM_F_CREATE|NLM_F_EXCL,
rtmmsg, rta_buf - (void *) rtmmsg, callback,
user_data, destroy);
break;
case RTM_DELLINK:
rta_buf += rta_add(rta_buf, IFLA_IFNAME, ifname_len, ifname);
l_netlink_send(rtnl, RTM_DELLINK, 0, rtmmsg,
rta_buf - (void *)rtmmsg, callback, user_data,
destroy);
break;
case RTM_GETLINK:
flags = NLM_F_DUMP;
l_netlink_send(rtnl, RTM_GETLINK, NLM_F_DUMP, rtmmsg,
rta_buf - (void *)rtmmsg, callback, user_data,
destroy);
break;
default:
l_netlink_destroy(rtnl);
rtnl = NULL;
break;
}
nlm = l_netlink_message_new(rtm_msg_type, flags);;
l_netlink_message_add_header(nlm, &ifi, sizeof(ifi));
if (ifname)
l_netlink_message_append(nlm, IFLA_IFNAME, ifname, ifname_len);
l_netlink_message_enter_nested(nlm, IFLA_LINKINFO);
l_netlink_message_append(nlm, IFLA_INFO_KIND,
NLMON_TYPE, nlmon_type_len);
l_netlink_message_leave_nested(nlm);
l_netlink_send(rtnl, nlm, callback, user_data, destroy);
l_free(rtmmsg);
return rtnl;
}
@ -578,7 +689,7 @@ static int analyze_pcap(const char *pathname)
printf("\n");
printf(" Number of packets: %lu\n", pkt_count);
printf(" Short packets: %lu\n", pkt_short);
printf(" Truncated packets: %lu\n", pkt_trunc);
printf(" Tuncated packets: %lu\n", pkt_trunc);
printf("\n");
printf(" Ethernet packets: %lu\n", pkt_ether);
printf(" PAE packets: %lu\n", pkt_pae);
@ -718,36 +829,29 @@ static void usage(void)
"Usage:\n");
printf("\tiwmon [options]\n");
printf("Options:\n"
"\t-r, --read <file> Read netlink PCAP trace file\n"
"\t-w, --write <file> Write netlink PCAP trace file\n"
"\t-a, --analyze <file> Analyze netlink PCAP trace file\n"
"\t-i, --interface <dev> Use specified netlink monitor\n"
"\t-n, --nortnl Don't show RTNL output\n"
"\t-y, --nowiphy Don't show 'New Wiphy' output\n"
"\t-s, --noscan Don't show scan result output\n"
"\t-e, --noies Don't show IEs except SSID\n"
"\t-t, --time-format <format> Time format to display. Either\n"
"\t\t\t\t 'delta' or 'utc'.\n"
"\t-W,--pcap-count Maximum number of PCAP files\n"
"\t-C,--pcap-size Maximum size (MB) of PCAP files\n"
"\t-h, --help Show help options\n");
"\t-r, --read <file> Read netlink PCAP trace file\n"
"\t-w, --write <file> Write netlink PCAP trace file\n"
"\t-a, --analyze <file> Analyze netlink PCAP trace file\n"
"\t-i, --interface <dev> Use specified netlink monitor\n"
"\t-n, --nortnl Don't show RTNL output\n"
"\t-y, --nowiphy Don't show 'New Wiphy' output\n"
"\t-s, --noscan Don't show scan result output\n"
"\t-e, --noies Don't show IEs except SSID\n"
"\t-h, --help Show help options\n");
}
static const struct option main_options[] = {
{ "read", required_argument, NULL, 'r' },
{ "write", required_argument, NULL, 'w' },
{ "analyze", required_argument, NULL, 'a' },
{ "nl80211", required_argument, NULL, 'F' },
{ "interface", required_argument, NULL, 'i' },
{ "nortnl", no_argument, NULL, 'n' },
{ "nowiphy", no_argument, NULL, 'y' },
{ "noscan", no_argument, NULL, 's' },
{ "noies", no_argument, NULL, 'e' },
{ "time-format", required_argument, NULL, 't' },
{ "pcap-count", required_argument, NULL, 'W' },
{ "pcap-size", required_argument, NULL, 'C' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ "read", required_argument, NULL, 'r' },
{ "write", required_argument, NULL, 'w' },
{ "analyze", required_argument, NULL, 'a' },
{ "nl80211", required_argument, NULL, 'F' },
{ "interface", required_argument, NULL, 'i' },
{ "nortnl", no_argument, NULL, 'n' },
{ "nowiphy", no_argument, NULL, 'y' },
{ "noscan", no_argument, NULL, 's' },
{ "noies", no_argument, NULL, 'e' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ }
};
@ -761,7 +865,7 @@ int main(int argc, char *argv[])
for (;;) {
int opt;
opt = getopt_long(argc, argv, "r:w:a:i:t:W:C:nvhyse",
opt = getopt_long(argc, argv, "r:w:a:i:nvhyse",
main_options, NULL);
if (opt < 0)
break;
@ -791,35 +895,6 @@ int main(int argc, char *argv[])
break;
case 'e':
config.noies = true;
break;
case 't':
if (!strcmp(optarg, "delta"))
config.time_format = TIME_FORMAT_DELTA;
else if (!strcmp(optarg, "utc"))
config.time_format = TIME_FORMAT_UTC;
else {
printf("Invalid time format '%s'", optarg);
return EXIT_FAILURE;
}
break;
case 'W':
if (l_safe_atou32(optarg,
&config.pcap_file_count) < 0 ||
config.pcap_file_count == 0) {
printf("Invalid file count '%s'\n", optarg);
return EXIT_FAILURE;
}
break;
case 'C':
if (l_safe_atou32(optarg,
&config.pcap_file_size) < 0 ||
config.pcap_file_size == 0) {
printf("Invalid file size '%s'\n", optarg);
return EXIT_FAILURE;
}
break;
case 'v':
printf("%s\n", VERSION);
@ -882,7 +957,7 @@ int main(int argc, char *argv[])
l_io_destroy(monitor_interface.io);
l_netlink_destroy(monitor_interface.rtnl);
l_genl_unref(monitor_interface.genl);
l_netlink_destroy(monitor_interface.genl);
l_free(monitor_interface.ifname);
nlmon_close(nlmon);

View File

@ -29,7 +29,6 @@
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
@ -38,26 +37,16 @@
#include <linux/if.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_link.h>
#include <linux/netlink.h>
#include <linux/genetlink.h>
#include <linux/rtnetlink.h>
#include <linux/filter.h>
#include <linux/limits.h>
#include <ell/ell.h>
#ifndef ARPHRD_NETLINK
#define ARPHRD_NETLINK 824
#endif
#ifndef RMNET_FLAGS_INGRESS_MAP_CKSUMV5
#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5 (1U << 4)
#endif
#ifndef RMNET_FLAGS_EGRESS_MAP_CKSUMV5
#define RMNET_FLAGS_EGRESS_MAP_CKSUMV5 (1U << 5)
#endif
#include "linux/nl80211.h"
#include "ell/useful.h"
@ -95,8 +84,6 @@
#define BSS_CAPABILITY_APSD (1<<11)
#define BSS_CAPABILITY_DSSS_OFDM (1<<13)
#define BYTES_PER_MB 1000000
struct nlmon *cur_nlmon;
enum msg_type {
@ -117,12 +104,6 @@ struct nlmon {
bool noscan;
bool noies;
bool read;
enum time_format time_format;
char *file_prefix;
unsigned int file_idx;
unsigned int max_files;
unsigned int max_size;
};
struct nlmon_req {
@ -195,15 +176,11 @@ static void nlmon_req_free(void *data)
}
static time_t time_offset = ((time_t) -1);
static enum time_format time_format;
static inline void update_time_offset(const struct timeval *tv,
enum time_format tf)
static inline void update_time_offset(const struct timeval *tv)
{
if (tv && time_offset == ((time_t) -1)) {
if (tv && time_offset == ((time_t) -1))
time_offset = tv->tv_sec;
time_format = tf;
}
}
#define print_indent(indent, color1, prefix, title, color2, fmt, args...) \
@ -239,38 +216,15 @@ static void print_packet(const struct timeval *tv, char ident,
int n, ts_len = 0, ts_pos = 0, len = 0, pos = 0;
if (tv) {
struct tm *tm;
if (use_color()) {
n = sprintf(ts_str + ts_pos, "%s", COLOR_TIMESTAMP);
if (n > 0)
ts_pos += n;
}
switch (time_format) {
case TIME_FORMAT_DELTA:
n = sprintf(ts_str + ts_pos, " %" PRId64 ".%06" PRId64,
n = sprintf(ts_str + ts_pos, " %" PRId64 ".%06" PRId64,
(int64_t)tv->tv_sec - time_offset,
(int64_t)tv->tv_usec);
break;
case TIME_FORMAT_UTC:
tm = gmtime(&tv->tv_sec);
if (!tm) {
n = sprintf(ts_str + ts_pos, "%s",
"Time error");
break;
}
n = strftime(ts_str + ts_pos, sizeof(ts_str) - ts_pos,
"%b %d %H:%M:%S", tm);
break;
default:
/* Should never happen */
printf("Unknown time format");
l_main_quit();
return;
}
if (n > 0) {
ts_pos += n;
ts_len += n;
@ -404,7 +358,6 @@ static const struct {
{ { 0x00, 0x50, 0xf2 }, "Microsoft" },
{ { 0x00, 0x90, 0x4c }, "Epigram" },
{ { 0x50, 0x6f, 0x9a }, "Wi-Fi Alliance" },
{ { 0x00, 0x18, 0x0a }, "Cisco Meraki" },
{ }
};
@ -529,30 +482,7 @@ static void print_ie_country(unsigned int level, const char *label,
return;
}
print_attr(level, "%s: %c%c", label, code[0], code[1]);
switch (code[2]) {
case ' ':
print_attr(level + 1,
"3rd octet: 0x%02x: All environments", code[2]);
break;
case 'O':
print_attr(level + 1,
"3rd octet: 0x%02x: Outdoor environments", code[2]);
break;
case 'I':
print_attr(level + 1,
"3rd octet: 0x%02x: Indoor environments", code[2]);
break;
case 'X':
print_attr(level + 1,
"3rd octet: 0x%02x: Non-country entity", code[2]);
break;
default:
print_attr(level + 1,
"3rd octet: 0x%02x: Annex E table", code[2]);
break;
}
print_attr(level, "%s: %c%c%c", label, code[0], code[1], code[2]);
while (i < size) {
if (code[i] > 200) {
@ -1719,7 +1649,7 @@ static void print_ie_vht_capabilities(unsigned int level,
[21] = "TXOP PS",
[22] = "+HTC-VHT Capable",
[23 ... 25] = "Maximum A-MPDU Length Exponent",
[26 ... 27] = "VHT Link Adaptation Capable",
[26 ... 27] = "VHT Link Adapation Capable",
[28] = "RX Antenna Pattern Consistency",
[29] = "TX Antenna Pattern Consistency",
[30 ... 31] = "Extended NSS BW Support",
@ -1916,7 +1846,7 @@ static void print_ie_interworking(unsigned int level,
size--;
ptr++;
if (size < 2)
if (!size)
return;
/*
@ -2522,86 +2452,6 @@ static void print_reduced_neighbor_report(unsigned int level, const char *label,
}
}
static void print_neighbor_report(unsigned int level, const char *label,
const void *data, uint16_t size)
{
struct ie_tlv_iter iter;
struct ie_neighbor_report_info info;
const char *phy_type_table[] = {
[0] = NULL,
[1] = NULL,
[2] = "DSSS",
[3] = NULL,
[4] = "OFDM",
[5] = "HDRSSS",
[6] = "ERP",
[7] = "HT",
[8] = "DMG",
[9] = "VHT",
[10] = "TVHT",
[11] = "S1G",
[12] = "CDMG",
[13] = "CMMG",
[14] = "HE"
};
ie_tlv_iter_init(&iter, data - 2, size + 2);
if (!ie_tlv_iter_next(&iter))
return;
if (ie_parse_neighbor_report(&iter, &info) < 0) {
print_attr(level, "Invalid Neighbor report");
return;
}
print_attr(level, "Neighbor Report for "MAC, MAC_STR(info.addr));
print_attr(level + 1, "Operating Class: %u", info.oper_class);
print_attr(level + 1, "Channel Number: %u", info.channel_num);
if (info.phy_type <= 14 && phy_type_table[info.phy_type])
print_attr(level + 1, "Phy Type: %s",
phy_type_table[info.phy_type]);
else
print_attr(level + 1, "Phy Type: Unknown (%u)", info.phy_type);
if (info.bss_transition_pref_present)
print_attr(level + 1, "BSS Transition Preference: %u",
info.bss_transition_pref);
switch (info.reachable) {
case 1:
print_attr(level + 1, "Reachability: Not Reachable");
break;
case 2:
print_attr(level + 1, "Reachability: Unknown");
break;
case 3:
print_attr(level + 1, "Reachability: Reachable");
break;
default:
break;
}
print_attr(level + 1, "BSSID Information");
if (info.security)
print_attr(level + 2, "Security bit set");
if (info.key_scope)
print_attr(level + 2, "Key scope bit set");
if (info.spectrum_mgmt)
print_attr(level + 2, "Spectrum Mgmt bit set");
if (info.qos)
print_attr(level + 2, "QoS bit set");
if (info.apsd)
print_attr(level + 2, "APSD bit set");
if (info.md)
print_attr(level + 2, "MD bit set");
if (info.ht)
print_attr(level + 2, "HT bit set");
}
static struct attr_entry ie_entry[] = {
{ IE_TYPE_SSID, "SSID",
ATTR_CUSTOM, { .function = print_ie_ssid } },
@ -2670,8 +2520,6 @@ static struct attr_entry ie_entry[] = {
ATTR_CUSTOM, { .function = print_reduced_neighbor_report } },
{ IE_TYPE_RSNX, "RSNX",
ATTR_CUSTOM, { .function = print_rsnx } },
{ IE_TYPE_NEIGHBOR_REPORT, "Neighbor Report",
ATTR_CUSTOM, { .function = print_neighbor_report } },
{ },
};
@ -5131,7 +4979,6 @@ static void print_rm_action_frame(unsigned int level, const uint8_t *body,
print_rm_request(level + 1, body + 1, body_len - 1);
break;
case 1:
case 5:
print_rm_report(level + 1, body + 1, body_len - 1);
break;
}
@ -5688,26 +5535,8 @@ static void print_cqm_event(unsigned int level, const char *label,
}
}
static void print_cqm_thresholds(unsigned int level, const char *label,
const void *data, uint16_t size)
{
const int32_t *thresholds = data;
unsigned int i;
if (size % 4) {
printf("malformed packet");
return;
}
print_attr(level, "%s:", label);
for (i = 0; i < size / 4; i++)
print_attr(level + 1, "Threshold: %d", thresholds[i]);
}
static const struct attr_entry cqm_table[] = {
{ NL80211_ATTR_CQM_RSSI_THOLD, "RSSI thresholds", ATTR_CUSTOM,
{ .function = print_cqm_thresholds } },
{ NL80211_ATTR_CQM_RSSI_THOLD, "RSSI threshold", ATTR_U32 },
{ NL80211_ATTR_CQM_RSSI_HYST, "RSSI hysteresis", ATTR_U32 },
{ NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
"RSSI threshold event", ATTR_CUSTOM,
@ -7324,10 +7153,8 @@ static void print_message(struct nlmon *nlmon, const struct timeval *tv,
if (nlmon->nowiphy && (cmd == NL80211_CMD_NEW_WIPHY))
return;
if (nlmon->noscan && L_IN_SET(cmd, NL80211_CMD_NEW_SCAN_RESULTS,
NL80211_CMD_NEW_SURVEY_RESULTS,
NL80211_CMD_TRIGGER_SCAN,
NL80211_CMD_GET_SURVEY))
if (nlmon->noscan && ((cmd == NL80211_CMD_NEW_SCAN_RESULTS) ||
(cmd == NL80211_CMD_TRIGGER_SCAN)))
return;
switch (type) {
@ -7402,64 +7229,6 @@ static bool nlmon_req_match(const void *a, const void *b)
return (req->seq == match->seq && req->pid == match->pid);
}
/*
* Ensures that PCAP names are zero padded when needed. This makes the files
* sort correctly.
*/
static void next_pcap_name(char *buf, size_t size, const char *prefix,
unsigned int idx, unsigned int max)
{
unsigned int ndigits = 1;
while (max > 9) {
max /= 10;
ndigits++;
}
snprintf(buf, size, "%s%.*u", prefix, ndigits, idx);
}
static bool check_pcap(struct nlmon *nlmon, size_t next_size)
{
char path[PATH_MAX];
if (!nlmon->pcap)
return false;
if (!nlmon->max_size)
return true;
if (pcap_get_size(nlmon->pcap) + next_size <= nlmon->max_size)
return true;
pcap_close(nlmon->pcap);
/* Exhausted the single PCAP file */
if (nlmon->max_files < 2) {
printf("Reached maximum size of PCAP, exiting\n");
nlmon->pcap = NULL;
l_main_quit();
return false;
}
next_pcap_name(path, sizeof(path), nlmon->file_prefix,
++nlmon->file_idx, nlmon->max_files);
nlmon->pcap = pcap_create(path);
if (nlmon->max_files > nlmon->file_idx)
return true;
/* Remove oldest PCAP file */
next_pcap_name(path, sizeof(path), nlmon->file_prefix,
nlmon->file_idx - nlmon->max_files, nlmon->max_files);
if (remove(path) < 0)
printf("Failed to remove old PCAP file %s\n", path);
return true;
}
static void store_packet(struct nlmon *nlmon, const struct timeval *tv,
uint16_t pkt_type,
uint16_t arphrd_type,
@ -7468,7 +7237,7 @@ static void store_packet(struct nlmon *nlmon, const struct timeval *tv,
{
uint8_t sll_hdr[16], *buf = sll_hdr;
if (!check_pcap(nlmon, sizeof(sll_hdr) + size))
if (!nlmon->pcap)
return;
memset(sll_hdr, 0, sizeof(sll_hdr));
@ -7593,10 +7362,6 @@ struct nlmon *nlmon_create(uint16_t id, const struct nlmon_config *config)
nlmon->noscan = config->noscan;
nlmon->noies = config->noies;
nlmon->read = config->read_only;
nlmon->time_format = config->time_format;
nlmon->max_files = config->pcap_file_count;
/* Command line expects MB, but use bytes internally */
nlmon->max_size = config->pcap_file_size * BYTES_PER_MB;
return nlmon;
}
@ -7731,51 +7496,8 @@ static void flags_str(const struct flag_names *table,
pos += sprintf(str + pos, "]");
}
static void print_rmnet_flags(unsigned int indent,
const char *label, uint32_t flags)
{
if (flags & RMNET_FLAGS_INGRESS_DEAGGREGATION)
print_attr(indent, "%s: %s", label, "deaggregation");
if (flags & RMNET_FLAGS_INGRESS_MAP_COMMANDS)
print_attr(indent, "%s: %s", label, "map commands");
if (flags & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
print_attr(indent, "%s: %s", label, "ingress_mapv4");
if (flags & RMNET_FLAGS_EGRESS_MAP_CKSUMV4)
print_attr(indent, "%s: %s", label, "egress_mapv4");
if (flags & RMNET_FLAGS_INGRESS_MAP_CKSUMV5)
print_attr(indent, "%s: %s", label, "ingress_mapv5");
if (flags & RMNET_FLAGS_EGRESS_MAP_CKSUMV5)
print_attr(indent, "%s: %s", label, "egress_mapv5");
}
static void print_ifla_rmnet_flags(unsigned int indent, const char *str,
const void *buf, uint16_t size)
{
struct ifla_rmnet_flags flags;
if (size != 8) {
printf("malformed packet\n");
return;
}
memcpy(&flags, buf, size);
print_attr(indent, "%s:", str);
print_rmnet_flags(indent + 1, "Flags", flags.flags);
print_rmnet_flags(indent + 1, "Mask", flags.mask);
}
static struct attr_entry link_info_data_entry[] = {
{ IFLA_RMNET_MUX_ID, "RMNet Mux Id", ATTR_U16 },
{ IFLA_RMNET_FLAGS, "RMNet Flags", ATTR_CUSTOM,
{ .function = print_ifla_rmnet_flags } },
{ },
};
static struct attr_entry link_info_entry[] = {
{ IFLA_INFO_KIND, "Kind", ATTR_STRING },
{ IFLA_INFO_DATA, "Info Data",
ATTR_NESTED, { link_info_data_entry } },
{ },
};
@ -7932,7 +7654,7 @@ static void print_rtnl_attributes(int indent, const struct attr_entry *table,
return;
for (attr = rt_attr; RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
uint16_t rta_type = attr->rta_type & NLA_TYPE_MASK;
uint16_t rta_type = attr->rta_type;
enum attr_type type = ATTR_UNSPEC;
attr_func_t function;
const struct attr_entry *nested;
@ -8433,10 +8155,7 @@ void nlmon_print_rtnl(struct nlmon *nlmon, const struct timeval *tv,
int64_t aligned_size = NLMSG_ALIGN(size);
const struct nlmsghdr *nlmsg;
if (nlmon->nortnl)
return;
update_time_offset(tv, nlmon->time_format);
update_time_offset(tv);
for (nlmsg = data; NLMSG_OK(nlmsg, aligned_size);
nlmsg = NLMSG_NEXT(nlmsg, aligned_size)) {
@ -8474,7 +8193,7 @@ void nlmon_print_genl(struct nlmon *nlmon, const struct timeval *tv,
{
const struct nlmsghdr *nlmsg;
update_time_offset(tv, nlmon->time_format);
update_time_offset(tv);
for (nlmsg = data; NLMSG_OK(nlmsg, size);
nlmsg = NLMSG_NEXT(nlmsg, size)) {
@ -8483,8 +8202,7 @@ void nlmon_print_genl(struct nlmon *nlmon, const struct timeval *tv,
continue;
}
if (nlmsg->nlmsg_type >= NLMSG_MIN_TYPE && !nlmon->read &&
nlmsg->nlmsg_type != nlmon->id)
if (!nlmon->read && nlmsg->nlmsg_type != nlmon->id)
continue;
nlmon_message(nlmon, tv, nlmsg);
@ -8497,7 +8215,7 @@ void nlmon_print_pae(struct nlmon *nlmon, const struct timeval *tv,
{
char extra_str[16];
update_time_offset(tv, nlmon->time_format);
update_time_offset(tv);
sprintf(extra_str, "len %u", size);
@ -8624,20 +8342,13 @@ struct nlmon *nlmon_open(uint16_t id, const char *pathname,
struct nlmon *nlmon;
struct l_io *pae_io;
struct pcap *pcap;
char path[PATH_MAX];
pae_io = open_pae();
if (!pae_io)
return NULL;
if (pathname) {
if (config->pcap_file_count > 1)
next_pcap_name(path, sizeof(path), pathname,
0, config->pcap_file_count);
else
snprintf(path, sizeof(path), "%s", pathname);
pcap = pcap_create(path);
pcap = pcap_create(pathname);
if (!pcap) {
l_io_destroy(pae_io);
return NULL;
@ -8650,7 +8361,6 @@ struct nlmon *nlmon_open(uint16_t id, const char *pathname,
nlmon->pae_io = pae_io;
nlmon->pcap = pcap;
nlmon->file_prefix = l_strdup(pathname);
l_io_set_read_handler(nlmon->pae_io, pae_receive, nlmon, NULL);
@ -8673,7 +8383,5 @@ void nlmon_close(struct nlmon *nlmon)
if (nlmon->pcap)
pcap_close(nlmon->pcap);
l_free(nlmon->file_prefix);
l_free(nlmon);
}

View File

@ -25,22 +25,12 @@
struct nlmon;
enum time_format {
TIME_FORMAT_DELTA,
TIME_FORMAT_UTC,
};
struct nlmon_config {
bool nortnl;
bool nowiphy;
bool noscan;
bool noies;
bool read_only;
enum time_format time_format;
/* File size in MB */
uint32_t pcap_file_size;
uint32_t pcap_file_count;
};
struct nlmon *nlmon_open(uint16_t id, const char *pathname,

View File

@ -60,7 +60,6 @@ struct pcap {
bool closed;
uint32_t type;
uint32_t snaplen;
size_t size;
};
struct pcap *pcap_open(const char *pathname)
@ -153,8 +152,6 @@ struct pcap *pcap_create(const char *pathname)
goto failed;
}
pcap->size += len;
return pcap;
failed:
@ -191,11 +188,6 @@ uint32_t pcap_get_snaplen(struct pcap *pcap)
return pcap->snaplen;
}
size_t pcap_get_size(struct pcap *pcap)
{
return pcap->size;
}
bool pcap_read(struct pcap *pcap, struct timeval *tv,
void *data, uint32_t size, uint32_t *len, uint32_t *real_len)
{
@ -287,7 +279,5 @@ bool pcap_write(struct pcap *pcap, const struct timeval *tv,
return false;
}
pcap->size += written;
return true;
}

View File

@ -36,7 +36,6 @@ void pcap_close(struct pcap *pcap);
uint32_t pcap_get_type(struct pcap *pcap);
uint32_t pcap_get_snaplen(struct pcap *pcap);
size_t pcap_get_size(struct pcap *pcap);
bool pcap_read(struct pcap *pcap, struct timeval *tv,
void *data, uint32_t size, uint32_t *len, uint32_t *real_len);

View File

@ -94,13 +94,13 @@ static void adhoc_sta_free(void *data)
eapol_sm_free(sta->sm);
if (sta->hs_sta)
handshake_state_unref(sta->hs_sta);
handshake_state_free(sta->hs_sta);
if (sta->sm_a)
eapol_sm_free(sta->sm_a);
if (sta->hs_auth)
handshake_state_unref(sta->hs_auth);
handshake_state_free(sta->hs_auth);
end:
l_free(sta);

View File

@ -234,7 +234,7 @@ uint32_t anqp_request(uint64_t wdev_id, const uint8_t *addr,
request->anqp_cb = cb;
request->anqp_destroy = destroy;
/*
* WPA3 Specification version 3, Section 9.4:
* WPA3 Specificiation version 3, Section 9.4:
* "A STA shall use a randomized dialog token for every new GAS
* exchange."
*/

View File

@ -131,7 +131,7 @@ char **anqp_parse_nai_realms(const unsigned char *anqp, unsigned int len)
uint16_t count;
if (len < 2)
return NULL;
return false;
count = l_get_le16(anqp);

108
src/ap.c
View File

@ -67,7 +67,7 @@ struct ap_state {
ap_stopped_func_t stopped_func;
void *user_data;
char ssid[SSID_MAX_SIZE + 1];
char ssid[33];
char passphrase[64];
uint8_t psk[32];
enum band_freq band;
@ -109,8 +109,6 @@ struct ap_state {
struct l_timeout *rekey_timeout;
unsigned int rekey_time;
uint32_t pre_scan_cmd_id;
bool started : 1;
bool gtk_set : 1;
bool netconfig_set_addr4 : 1;
@ -155,7 +153,7 @@ struct ap_wsc_pbc_probe_record {
};
struct ap_network {
char ssid[SSID_MAX_SIZE + 1];
char ssid[33];
int16_t signal;
enum security security;
};
@ -183,7 +181,7 @@ static int network_signal_compare(const void *a, const void *b, void *user)
static struct ap_network *ap_network_find(struct ap_state *ap,
struct scan_bss *bss)
{
char ssid[SSID_MAX_SIZE + 1];
char ssid[33];
memcpy(ssid, bss->ssid, bss->ssid_len);
ssid[bss->ssid_len] = '\0';
@ -232,7 +230,7 @@ static void ap_stop_handshake(struct sta_state *sta)
}
if (sta->hs) {
handshake_state_unref(sta->hs);
handshake_state_free(sta->hs);
sta->hs = NULL;
}
@ -356,12 +354,6 @@ static void ap_reset(struct ap_state *ap)
l_timeout_remove(ap->rekey_timeout);
ap->rekey_timeout = NULL;
}
if (ap->pre_scan_cmd_id) {
scan_cancel(netdev_get_wdev_id(ap->netdev),
ap->pre_scan_cmd_id);
ap->pre_scan_cmd_id = 0;
}
}
static bool ap_event_done(struct ap_state *ap, bool prev_in_event)
@ -3637,7 +3629,7 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
return -ENOMSG;
len = strlen(strval);
if (len < 1 || len > SSID_MAX_SIZE) {
if (len < 1 || len > 32) {
l_error("AP SSID length outside the [1, 32] range");
return -EINVAL;
}
@ -3860,70 +3852,6 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
return 0;
}
static void ap_pre_scan_trigger(int err, void *user_data)
{
struct ap_state *ap = user_data;
if (err < 0) {
l_error("AP pre-scan failed: %i", err);
ap_start_failed(ap, err);
return;
}
}
static bool ap_check_channel(struct ap_state *ap)
{
const struct band_freq_attrs *freq_attr;
freq_attr = wiphy_get_frequency_info(netdev_get_wiphy(ap->netdev),
band_channel_to_freq(ap->channel, ap->band));
if (L_WARN_ON(!freq_attr))
return false;
/* Check if disabled/no-IR */
if (freq_attr->disabled || freq_attr->no_ir)
return false;
return true;
}
static bool ap_pre_scan_notify(int err, struct l_queue *bss_list,
const struct scan_freq_set *freqs,
void *user_data)
{
struct ap_state *ap = user_data;
if (!ap_check_channel(ap)) {
l_error("Unable to channel %u even after pre-scan",
ap->channel);
goto error;
}
if (ap_start_send(ap))
return false;
error:
ap_start_failed(ap, -ENOTSUP);
return false;
}
static void ap_pre_scan_destroy(void *user_data)
{
struct ap_state *ap = user_data;
ap->pre_scan_cmd_id = 0;
}
static bool ap_pre_scan(struct ap_state *ap)
{
ap->pre_scan_cmd_id = scan_passive(netdev_get_wdev_id(ap->netdev),
NULL, ap_pre_scan_trigger,
ap_pre_scan_notify,
ap, ap_pre_scan_destroy);
return ap->pre_scan_cmd_id != 0;
}
/*
* Start a simple independent WPA2 AP on given netdev.
*
@ -3986,34 +3914,34 @@ struct ap_state *ap_start(struct netdev *netdev, struct l_settings *config,
if (!frame_watch_add(wdev_id, 0, 0x0000 |
(MPDU_MANAGEMENT_SUBTYPE_ASSOCIATION_REQUEST << 4),
NULL, 0, false, ap_assoc_req_cb, ap, NULL))
NULL, 0, ap_assoc_req_cb, ap, NULL))
goto error;
if (!frame_watch_add(wdev_id, 0, 0x0000 |
(MPDU_MANAGEMENT_SUBTYPE_REASSOCIATION_REQUEST << 4),
NULL, 0, false, ap_reassoc_req_cb, ap, NULL))
NULL, 0, ap_reassoc_req_cb, ap, NULL))
goto error;
if (!wiphy_supports_probe_resp_offload(wiphy)) {
if (!frame_watch_add(wdev_id, 0, 0x0000 |
(MPDU_MANAGEMENT_SUBTYPE_PROBE_REQUEST << 4),
NULL, 0, false, ap_probe_req_cb, ap, NULL))
NULL, 0, ap_probe_req_cb, ap, NULL))
goto error;
}
if (!frame_watch_add(wdev_id, 0, 0x0000 |
(MPDU_MANAGEMENT_SUBTYPE_DISASSOCIATION << 4),
NULL, 0, false, ap_disassoc_cb, ap, NULL))
NULL, 0, ap_disassoc_cb, ap, NULL))
goto error;
if (!frame_watch_add(wdev_id, 0, 0x0000 |
(MPDU_MANAGEMENT_SUBTYPE_AUTHENTICATION << 4),
NULL, 0, false, ap_auth_cb, ap, NULL))
NULL, 0, ap_auth_cb, ap, NULL))
goto error;
if (!frame_watch_add(wdev_id, 0, 0x0000 |
(MPDU_MANAGEMENT_SUBTYPE_DEAUTHENTICATION << 4),
NULL, 0, false, ap_deauth_cb, ap, NULL))
NULL, 0, ap_deauth_cb, ap, NULL))
goto error;
ap->mlme_watch = l_genl_family_register(ap->nl80211, "mlme",
@ -4034,20 +3962,6 @@ struct ap_state *ap_start(struct netdev *netdev, struct l_settings *config,
return ap;
}
if (!ap_check_channel(ap)) {
l_debug("Channel %u is disabled/no-IR, pre-scanning",
ap->channel);
if (ap_pre_scan(ap)) {
if (err_out)
*err_out = 0;
return ap;
}
goto error;
}
if (ap_start_send(ap)) {
if (err_out)
*err_out = 0;

View File

@ -79,7 +79,7 @@ struct ap_ops {
void *user_data);
/*
* If not null, writes extra IEs to be added to the outgoing frame of
* given type and, if it's not a beacon frame, in response to a given
* given type and, if it's not a beacon frame, in reponse to a given
* client frame. May also react to the extra IEs in that frame.
* Returns the number of bytes written which must be less than or
* equal to the number returned by .get_extra_ies_len when called

View File

@ -54,7 +54,7 @@ void __iwd_backtrace_print(unsigned int offset)
int pathlen;
pid_t pid;
if (!program_exec)
if (program_exec == NULL)
return;
pathlen = strlen(program_path);
@ -186,7 +186,7 @@ void __iwd_backtrace_init(void)
}
}
if (!program_exec)
if (program_exec == NULL)
return;
program_path = getcwd(cwd, sizeof(cwd));

View File

@ -678,7 +678,7 @@ int band_estimate_he_rx_rate(const struct band *band, const uint8_t *hec,
}
if (!rate)
return -ENETUNREACH;
return -EBADMSG;
*out_data_rate = rate;
@ -896,7 +896,7 @@ static const struct operating_class_info e4_operating_classes[] = {
},
{
.operating_class = 136,
.starting_frequency = 5925,
.starting_frequency = 5950,
.channel_spacing = 20,
.center_frequencies = { 2 },
}
@ -1352,10 +1352,6 @@ check_e4:
const struct operating_class_info *info =
&e4_operating_classes[i];
if (band != band_oper_class_to_band(NULL,
info->operating_class))
continue;
if (e4_has_frequency(info, freq) == 0 ||
e4_has_ccfi(info, freq) == 0) {
if (out_band)
@ -1430,7 +1426,7 @@ static const char *const oper_class_eu_codes[] = {
"AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
"DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
"LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", "GB"
"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK"
};
/* Annex E, table E-1 */
@ -1489,48 +1485,15 @@ static const uint8_t oper_class_cn_to_global[] = {
/* 128 - 130 is a 1 to 1 mapping */
};
/*
* Annex C describes the country string encoding.
*
* If it is a country, the first two octets of this string is the two character
* country code as described in document ISO 3166-1. The third octet is one of
* the following:
* 1. an ASCII space character, if the regulations under which the station is
* operating encompass all environments for the current frequency band in
* the country,
* 2. an ASCII 'O' character, if the regulations under which the station is
* operating are for an outdoor environment only, or
* 3. an ASCII 'I' character, if the regulations under which the station is
* operating are for an indoor environment only.
* 4. an ASCII 'X' character, if the station is operating under a noncountry
* entity. The first two octets of the noncountry entity is two ASCII 'XX'
* characters.
* 5. the hexadecimal representation of the Operating Class table number
* currently in use, from the set of tables defined in Annex E, e.g.,
* Table E-1 is represented as x'01'.
*/
static enum band_freq oper_class_to_band(const uint8_t *country,
uint8_t oper_class,
bool ignore_country3)
enum band_freq band_oper_class_to_band(const uint8_t *country,
uint8_t oper_class)
{
unsigned int i;
int table = 0;
/*
* If a country is set, and the 3rd byte maps to some E-* table in the
* spec use that (case 5). Only caveat here is some APs erroneously set
* this 3rd byte. To work around we can fall back to case 1, where only
* the first two characters are used to lookup the table.
*/
if (!ignore_country3 && country && country[2] >= 1 && country[2] <= 5)
if (country && country[2] >= 1 && country[2] <= 5)
table = country[2];
else if (country) {
/*
* Assuming case 1, although its unlikely you would handle
* cases 2 (O) or 3 (I) any differently. Case 4 (X) is unlikely
* and we really wouldn't have enough information to correctly
* determine the band in some obscure non-country domain.
*/
for (i = 0; i < L_ARRAY_SIZE(oper_class_us_codes); i++)
if (!memcmp(oper_class_us_codes[i], country, 2)) {
/* Use table E-1 */
@ -1579,25 +1542,6 @@ static enum band_freq oper_class_to_band(const uint8_t *country,
return 0;
}
enum band_freq band_oper_class_to_band(const uint8_t *country,
uint8_t oper_class)
{
enum band_freq band = oper_class_to_band(country, oper_class, false);
if (!band) {
/* Fallback with no country string won't change anything */
if (!country)
return 0;
l_warn("Failed to find band with country string '%c%c %u' and "
"oper class %u, trying fallback",
country[0], country[1], country[2], oper_class);
return oper_class_to_band(country, oper_class, true);
}
return band;
}
const char *band_chandef_width_to_string(enum band_chandef_width width)
{
switch (width) {

View File

@ -45,42 +45,22 @@
static uint64_t blacklist_multiplier;
static uint64_t blacklist_initial_timeout;
static uint64_t blacklist_ap_busy_initial_timeout;
static uint64_t blacklist_max_timeout;
struct blacklist_entry {
uint8_t addr[6];
uint64_t added_time;
uint64_t expire_time;
enum blacklist_reason reason;
};
struct blacklist_search {
const uint8_t *addr;
enum blacklist_reason reason;
};
static struct l_queue *blacklist;
static uint64_t get_reason_timeout(enum blacklist_reason reason)
{
switch (reason) {
case BLACKLIST_REASON_CONNECT_FAILED:
return blacklist_initial_timeout;
case BLACKLIST_REASON_AP_BUSY:
return blacklist_ap_busy_initial_timeout;
default:
l_warn("Unhandled blacklist reason: %u", reason);
return 0;
}
}
static bool check_if_expired(void *data, void *user_data)
{
struct blacklist_entry *entry = data;
uint64_t now = l_get_u64(user_data);
if (l_time_after(now, entry->expire_time)) {
if (l_time_diff(now, entry->added_time) > blacklist_max_timeout) {
l_debug("Removing entry "MAC" on prune", MAC_STR(entry->addr));
l_free(entry);
return true;
@ -107,53 +87,17 @@ static bool match_addr(const void *a, const void *b)
return false;
}
static bool match_addr_and_reason(const void *a, const void *b)
{
const struct blacklist_entry *entry = a;
const struct blacklist_search *search = b;
if (entry->reason != search->reason)
return false;
if (!memcmp(entry->addr, search->addr, 6))
return true;
return false;
}
void blacklist_add_bss(const uint8_t *addr, enum blacklist_reason reason)
void blacklist_add_bss(const uint8_t *addr)
{
struct blacklist_entry *entry;
uint64_t timeout;
blacklist_prune();
timeout = get_reason_timeout(reason);
if (!timeout)
return;
entry = l_queue_find(blacklist, match_addr, addr);
if (entry) {
uint64_t offset;
if (reason < entry->reason) {
l_debug("Promoting "MAC" blacklist to reason %u",
MAC_STR(addr), reason);
/* Reset this to the new timeout and reason */
entry->reason = reason;
entry->added_time = l_time_now();
entry->expire_time = l_time_offset(entry->added_time,
timeout);
return;
} else if (reason > entry->reason) {
l_debug("Ignoring blacklist extension of "MAC", "
"current blacklist status is more severe!",
MAC_STR(addr));
return;
}
offset = l_time_diff(entry->added_time, entry->expire_time);
uint64_t offset = l_time_diff(entry->added_time,
entry->expire_time);
offset *= blacklist_multiplier;
@ -168,36 +112,40 @@ void blacklist_add_bss(const uint8_t *addr, enum blacklist_reason reason)
entry = l_new(struct blacklist_entry, 1);
entry->added_time = l_time_now();
entry->expire_time = l_time_offset(entry->added_time, timeout);
entry->reason = reason;
entry->expire_time = l_time_offset(entry->added_time,
blacklist_initial_timeout);
memcpy(entry->addr, addr, 6);
l_queue_push_tail(blacklist, entry);
}
bool blacklist_contains_bss(const uint8_t *addr, enum blacklist_reason reason)
bool blacklist_contains_bss(const uint8_t *addr)
{
struct blacklist_search search = {
.addr = addr,
.reason = reason
};
bool ret;
uint64_t time_now;
struct blacklist_entry *entry;
blacklist_prune();
return l_queue_find(blacklist, match_addr_and_reason, &search) != NULL;
entry = l_queue_find(blacklist, match_addr, addr);
if (!entry)
return false;
time_now = l_time_now();
ret = l_time_after(time_now, entry->expire_time) ? false : true;
return ret;
}
void blacklist_remove_bss(const uint8_t *addr, enum blacklist_reason reason)
void blacklist_remove_bss(const uint8_t *addr)
{
struct blacklist_entry *entry;
struct blacklist_search search = {
.addr = addr,
.reason = reason
};
blacklist_prune();
entry = l_queue_remove_if(blacklist, match_addr_and_reason, &search);
entry = l_queue_remove_if(blacklist, match_addr, addr);
if (!entry)
return;
@ -214,47 +162,19 @@ static int blacklist_init(void)
blacklist_initial_timeout = BLACKLIST_DEFAULT_TIMEOUT;
/* For easier user configuration the timeout values are in seconds */
blacklist_initial_timeout *= L_USEC_PER_SEC;
if (!l_settings_get_uint64(config, "Blacklist",
"InitialRoamRequestedTimeout",
&blacklist_ap_busy_initial_timeout))
blacklist_ap_busy_initial_timeout = BLACKLIST_DEFAULT_TIMEOUT;
else
l_warn("[Blacklist].InitialRoamRequestedTimeout is deprecated, "
"use [Blacklist].InitialAccessPointBusyTimeout");
if (!l_settings_get_uint64(config, "Blacklist",
"InitialAccessPointBusyTimeout",
&blacklist_ap_busy_initial_timeout))
blacklist_ap_busy_initial_timeout = BLACKLIST_DEFAULT_TIMEOUT;
/* For easier user configuration the timeout values are in seconds */
blacklist_ap_busy_initial_timeout *= L_USEC_PER_SEC;
blacklist_initial_timeout *= 1000000;
if (!l_settings_get_uint64(config, "Blacklist",
"Multiplier",
&blacklist_multiplier))
blacklist_multiplier = BLACKLIST_DEFAULT_MULTIPLIER;
if (blacklist_multiplier == 0) {
l_warn("[Blacklist].Multiplier cannot be zero, setting to 1");
blacklist_multiplier = 1;
}
if (!l_settings_get_uint64(config, "Blacklist",
"MaximumTimeout",
&blacklist_max_timeout))
blacklist_max_timeout = BLACKLIST_DEFAULT_MAX_TIMEOUT;
blacklist_max_timeout *= L_USEC_PER_SEC;
if (blacklist_initial_timeout > blacklist_max_timeout)
l_warn("[Blacklist].InitialTimeout exceeded "
"[Blacklist].MaximumTimeout!");
if (!blacklist_initial_timeout)
l_debug("initial timeout was zero, blacklist will be disabled");
blacklist_max_timeout *= 1000000;
blacklist = l_queue_new();

View File

@ -20,23 +20,6 @@
*
*/
enum blacklist_reason {
/*
* When a BSS is blacklisted using this reason IWD will refuse to
* connect to it via autoconnect
*/
BLACKLIST_REASON_CONNECT_FAILED,
/*
* This type of blacklist is added when an AP indicates that its unable
* to handle more connections. This is done via BSS-TM requests or
* denied authentications/associations with certain status codes.
*
* Once this type of blacklist is applied to a BSS IWD will attempt to
* avoid roaming to it for a configured period of time.
*/
BLACKLIST_REASON_AP_BUSY,
};
void blacklist_add_bss(const uint8_t *addr, enum blacklist_reason reason);
bool blacklist_contains_bss(const uint8_t *addr, enum blacklist_reason reason);
void blacklist_remove_bss(const uint8_t *addr, enum blacklist_reason reason);
void blacklist_add_bss(const uint8_t *addr);
bool blacklist_contains_bss(const uint8_t *addr);
void blacklist_remove_bss(const uint8_t *addr);

View File

@ -35,7 +35,6 @@
#include "ell/useful.h"
#include "src/missing.h"
#include "src/defs.h"
#include "src/crypto.h"
#define ARC4_MIN_KEY_SIZE 1
@ -568,7 +567,7 @@ int crypto_psk_from_passphrase(const char *passphrase,
if (!crypto_passphrase_is_valid(passphrase))
return -ERANGE;
if (ssid_len == 0 || ssid_len > SSID_MAX_SIZE)
if (ssid_len == 0 || ssid_len > 32)
return -ERANGE;
result = l_cert_pkcs5_pbkdf2(L_CHECKSUM_SHA1, passphrase,
@ -1212,7 +1211,7 @@ struct l_ecc_point *crypto_derive_sae_pwe_from_pt_ecc(const uint8_t *mac1,
struct l_ecc_point *pwe;
if (!pt || !curve)
return NULL;
return false;
hash = crypto_sae_hash_from_ecc_prime_len(CRYPTO_SAE_HASH_TO_ELEMENT,
l_ecc_curve_get_scalar_bytes(curve));

View File

@ -134,12 +134,6 @@ struct l_dbus_message *dbus_error_not_hidden(struct l_dbus_message *msg)
"Not hidden");
}
struct l_dbus_message *dbus_error_permission_denied(struct l_dbus_message *msg)
{
return l_dbus_message_new_error(msg, IWD_SERVICE ".PermissionDenied",
"Permission Denied");
}
struct l_dbus_message *dbus_error_from_errno(int err,
struct l_dbus_message *msg)
{

Some files were not shown because too many files have changed in this diff Show More