3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2025-04-21 12:17:50 +02:00

Compare commits

..

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

36 changed files with 132 additions and 1103 deletions

View File

@ -1,18 +1,3 @@
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.

View File

@ -71,9 +71,7 @@ ell_headers = ell/util.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 \
@ -441,7 +439,7 @@ unit_tests += unit/test-cmac-aes \
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-pmksa
endif
if CLIENT
@ -605,11 +603,6 @@ 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
@ -625,9 +618,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 \

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]
InitialRoamRequestedTimeout=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=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

@ -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

@ -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

@ -1,12 +1,10 @@
AC_PREREQ([2.69])
AC_INIT([iwd],[3.6])
AC_INIT([iwd],[3.2])
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.72"
ell_min_version="0.69"
else
ell_min_version="0.5"
fi

View File

@ -718,36 +718,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 +754,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 +784,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);

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>
@ -43,7 +42,6 @@
#include <linux/genetlink.h>
#include <linux/rtnetlink.h>
#include <linux/filter.h>
#include <linux/limits.h>
#include <ell/ell.h>
#ifndef ARPHRD_NETLINK
@ -95,8 +93,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 +113,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 +185,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 +225,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;
@ -1915,7 +1878,7 @@ static void print_ie_interworking(unsigned int level,
size--;
ptr++;
if (size < 2)
if (!size)
return;
/*
@ -7401,64 +7364,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,
@ -7467,7 +7372,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));
@ -7592,10 +7497,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;
}
@ -8432,10 +8333,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)) {
@ -8473,7 +8371,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)) {
@ -8496,7 +8394,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);
@ -8623,20 +8521,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;
@ -8649,7 +8540,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);
@ -8672,7 +8562,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

@ -45,42 +45,22 @@
static uint64_t blacklist_multiplier;
static uint64_t blacklist_initial_timeout;
static uint64_t blacklist_roam_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_ROAM_REQUESTED:
return blacklist_roam_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,39 +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_roam_initial_timeout))
blacklist_roam_initial_timeout = BLACKLIST_DEFAULT_TIMEOUT;
/* For easier user configuration the timeout values are in seconds */
blacklist_roam_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,21 +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 a BSS requests IWD roams
* elsewhere. This is to aid in preventing IWD from roaming/connecting
* back to that BSS in the future unless there are no other "good"
* candidates to connect to.
*/
BLACKLIST_REASON_ROAM_REQUESTED,
};
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

@ -1166,34 +1166,21 @@ struct dpp_uri_info *dpp_parse_uri(const char *uri)
switch (*pos) {
case 'C':
if (L_WARN_ON(info->freqs))
goto free_info;
info->freqs = dpp_parse_class_and_channel(pos + 2, len);
if (!info->freqs)
goto free_info;
break;
case 'M':
if (L_WARN_ON(!l_memeqzero(info->mac,
sizeof(info->mac))))
goto free_info;
ret = dpp_parse_mac(pos + 2, len, info->mac);
if (ret < 0)
goto free_info;
break;
case 'V':
if (L_WARN_ON(info->version != 0))
goto free_info;
ret = dpp_parse_version(pos + 2, len, &info->version);
if (ret < 0)
goto free_info;
break;
case 'K':
if (L_WARN_ON(info->boot_public))
goto free_info;
info->boot_public = dpp_parse_key(pos + 2, len);
if (!info->boot_public)
goto free_info;

View File

@ -544,8 +544,7 @@ static bool eap_mschapv2_load_settings(struct eap_state *eap,
return true;
error:
l_free(state->user);
l_free(state);
free(state);
return false;
}

View File

@ -1239,7 +1239,7 @@ static struct pmksa *handshake_state_steal_pmksa(struct handshake_state *s)
s->have_pmksa = false;
if (l_time_after(now, pmksa->expiration)) {
pmksa_cache_free(pmksa);
l_free(pmksa);
pmksa = NULL;
}
@ -1272,15 +1272,13 @@ void handshake_state_cache_pmksa(struct handshake_state *s)
{
struct pmksa *pmksa = handshake_state_steal_pmksa(s);
if (!pmksa) {
l_debug("No PMKSA for "MAC, MAC_STR(s->aa));
return;
}
l_debug("%p", pmksa);
l_debug("Caching PMKSA for "MAC, MAC_STR(s->aa));
if (!pmksa)
return;
if (L_WARN_ON(pmksa_cache_put(pmksa) < 0))
pmksa_cache_free(pmksa);
l_free(pmksa);
}
bool handshake_state_remove_pmksa(struct handshake_state *s)
@ -1294,7 +1292,7 @@ bool handshake_state_remove_pmksa(struct handshake_state *s)
if (!pmksa)
return false;
pmksa_cache_free(pmksa);
l_free(pmksa);
return true;
}

View File

@ -290,17 +290,9 @@ control how long a misbehaved BSS spends on the blacklist.
* - InitialTimeout
- Values: uint64 value in seconds (default: **60**)
The initial time that a BSS spends on the blacklist. Setting this to zero
will disable blacklisting functionality in IWD.
* - InitialRoamRequestedTimeout
- Values: uint64 value in seconds (default: **30**)
The initial time that a BSS will be marked after a BSS requests a roam.
This is to aid in avoiding roaming back to BSS's which are likely
overloaded. Setting this to zero will disabled this form of blacklisting.
The initial time that a BSS spends on the blacklist.
* - Multiplier
- Values: unsigned int value greater than zero, in seconds
(default: **30**)
- Values: unsigned int value in seconds (default: **30**)
If the BSS was blacklisted previously and another connection attempt
has failed after the initial timeout has expired, then the BSS blacklist
@ -473,14 +465,6 @@ are buggy or just don't behave similar enough to the majority of other drivers.
If a driver in use matches one in this list, multicast RX will be
disabled.
* - SaeDisable
- Values: comma-separated list of drivers or glob matches
If a driver in use matches one in this list, SAE/WPA3 will be disabled
for connections. This will prevent connections to WPA3-only networks, but
will allow for connections to WPA3/WPA2 hybrid networks by utilizing
WPA2.
SEE ALSO
========

View File

@ -463,14 +463,6 @@ uint8_t netdev_get_rssi_level_idx(struct netdev *netdev)
return netdev->cur_rssi_level_idx;
}
int netdev_get_low_signal_threshold(uint32_t frequency)
{
if (frequency > 4000)
return LOW_SIGNAL_THRESHOLD_5GHZ;
return LOW_SIGNAL_THRESHOLD;
}
static void netdev_set_powered_result(int error, uint16_t type,
const void *data,
uint32_t len, void *user_data)
@ -1109,7 +1101,6 @@ static void netdev_free(void *data)
l_timeout_remove(netdev->rssi_poll_timeout);
scan_wdev_remove(netdev->wdev_id);
frame_watch_wdev_remove(netdev->wdev_id);
watchlist_destroy(&netdev->station_watches);
@ -1507,105 +1498,6 @@ static void netdev_setting_keys_failed(struct netdev_handshake_state *nhs,
handshake_event(&nhs->super, HANDSHAKE_EVENT_SETTING_KEYS_FAILED, &err);
}
static bool netdev_match_addr(const void *a, const void *b)
{
const struct netdev *netdev = a;
const uint8_t *addr = b;
return memcmp(netdev->addr, addr, ETH_ALEN) == 0;
}
static struct netdev *netdev_find_by_address(const uint8_t *addr)
{
return l_queue_find(netdev_list, netdev_match_addr, addr);
}
static void netdev_pmksa_driver_add(const struct pmksa *pmksa)
{
struct l_genl_msg *msg;
struct netdev *netdev = netdev_find_by_address(pmksa->spa);
uint32_t expiration = (uint32_t)pmksa->expiration;
if (!netdev)
return;
/* Only need to set the PMKSA into the kernel for fullmac drivers */
if (wiphy_supports_cmds_auth_assoc(netdev->wiphy))
return;
l_debug("Adding PMKSA to kernel");
msg = l_genl_msg_new(NL80211_CMD_SET_PMKSA);
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
l_genl_msg_append_attr(msg, NL80211_ATTR_PMKID, 16, pmksa->pmkid);
l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, pmksa->aa);
l_genl_msg_append_attr(msg, NL80211_ATTR_SSID,
pmksa->ssid_len, pmksa->ssid);
l_genl_msg_append_attr(msg, NL80211_ATTR_PMK_LIFETIME, 4, &expiration);
l_genl_msg_append_attr(msg, NL80211_ATTR_PMK,
pmksa->pmk_len, pmksa->pmk);
if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL))
l_error("error sending SET_PMKSA");
}
static void netdev_pmksa_driver_remove(const struct pmksa *pmksa)
{
struct l_genl_msg *msg;
struct netdev *netdev = netdev_find_by_address(pmksa->spa);
if (!netdev)
return;
/* Only need to set the PMKSA into the kernel for fullmac drivers */
if (wiphy_supports_cmds_auth_assoc(netdev->wiphy))
return;
l_debug("Removing PMKSA from kernel");
msg = l_genl_msg_new(NL80211_CMD_DEL_PMKSA);
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
l_genl_msg_append_attr(msg, NL80211_ATTR_PMKID, 16, pmksa->pmkid);
l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, pmksa->aa);
l_genl_msg_append_attr(msg, NL80211_ATTR_SSID,
pmksa->ssid_len, pmksa->ssid);
if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL))
l_error("error sending DEL_PMKSA");
}
static void netdev_flush_pmksa(struct netdev *netdev)
{
struct l_genl_msg *msg;
/*
* We only utilize the kernel's PMKSA cache for fullmac cards,
* so no need to flush if this is a softmac.
*/
if (wiphy_supports_cmds_auth_assoc(netdev->wiphy))
return;
msg = l_genl_msg_new(NL80211_CMD_FLUSH_PMKSA);
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL))
l_error("Failed to flush PMKSA for %u", netdev->index);
}
static void netdev_pmksa_driver_flush(void)
{
const struct l_queue_entry *e;
for (e = l_queue_get_entries(netdev_list); e; e = e->next) {
struct netdev *netdev = e->data;
netdev_flush_pmksa(netdev);
}
}
static void try_handshake_complete(struct netdev_handshake_state *nhs)
{
l_debug("ptk_installed: %u, gtk_installed: %u, igtk_installed: %u",
@ -3591,13 +3483,6 @@ static void netdev_external_auth_sae_tx_associate(void *user_data)
netdev_send_external_auth(netdev, MMPDU_STATUS_CODE_SUCCESS);
netdev_ensure_eapol_registered(netdev);
/*
* Free the auth proto now. With external auth there is no associate
* event which is where this normally gets cleaned up.
*/
auth_proto_free(netdev->ap);
netdev->ap = NULL;
}
struct rtnl_data {
@ -3924,15 +3809,6 @@ static void netdev_cmd_set_cqm_cb(struct l_genl_msg *msg, void *user_data)
static int netdev_cqm_rssi_update(struct netdev *netdev)
{
struct l_genl_msg *msg;
struct netdev_handshake_state *nhs = l_container_of(netdev->handshake,
struct netdev_handshake_state, super);
/*
* Fullmac cards handle roaming in firmware, there is no need to set
* CQM thresholds
*/
if (nhs->type == CONNECTION_TYPE_FULLMAC)
return 0;
l_debug("");
@ -5621,18 +5497,23 @@ static void netdev_external_auth_event(struct l_genl_msg *msg,
}
if (action == NL80211_EXTERNAL_AUTH_ABORT) {
l_warn("External Auth Aborted");
iwd_notice(IWD_NOTICE_CONNECT_INFO, "External Auth Aborted");
goto error;
}
iwd_notice(IWD_NOTICE_CONNECT_INFO,
"External Auth to SSID: %s, bssid: "MAC,
util_ssid_to_utf8(ssid.iov_len, ssid.iov_base),
MAC_STR(bssid));
if (hs->ssid_len != ssid.iov_len ||
memcmp(hs->ssid, ssid.iov_base, hs->ssid_len)) {
l_warn("Target SSID mismatch");
iwd_notice(IWD_NOTICE_CONNECT_INFO, "Target SSID mismatch");
goto error;
}
if (memcmp(hs->aa, bssid, ETH_ALEN)) {
l_warn("Target BSSID mismatch");
iwd_notice(IWD_NOTICE_CONNECT_INFO, "Target BSSID mismatch");
goto error;
}
@ -6641,16 +6522,6 @@ struct netdev *netdev_create_from_genl(struct l_genl_msg *msg,
netdev_get_link(netdev);
/*
* Call the netdev-specific variant to flush only this devices PMKSA
* cache in the kernel. This will make IWD's cache and the kernel's
* cache consistent, i.e. no entries
*
* TODO: If we ever are storing PMKSA's on disk we would first need to
* flush, then add all the PMKSA entries at this time.
*/
netdev_flush_pmksa(netdev);
return netdev;
}
@ -6766,10 +6637,6 @@ static int netdev_init(void)
__ft_set_tx_frame_func(netdev_tx_ft_frame);
__pmksa_set_driver_callbacks(netdev_pmksa_driver_add,
netdev_pmksa_driver_remove,
netdev_pmksa_driver_flush);
unicast_watch = l_genl_add_unicast_watch(genl, NL80211_GENL_NAME,
netdev_unicast_notify,
NULL, NULL);

View File

@ -158,7 +158,6 @@ const char *netdev_get_name(struct netdev *netdev);
bool netdev_get_is_up(struct netdev *netdev);
const char *netdev_get_path(struct netdev *netdev);
uint8_t netdev_get_rssi_level_idx(struct netdev *netdev);
int netdev_get_low_signal_threshold(uint32_t frequency);
struct handshake_state *netdev_handshake_state_new(struct netdev *netdev);
struct handshake_state *netdev_get_handshake(struct netdev *netdev);

View File

@ -1280,8 +1280,7 @@ struct scan_bss *network_bss_select(struct network *network,
if (l_queue_find(network->blacklist, match_bss, bss))
continue;
if (blacklist_contains_bss(bss->addr,
BLACKLIST_REASON_CONNECT_FAILED))
if (blacklist_contains_bss(bss->addr))
continue;
/* OWE Transition BSS */

View File

@ -40,9 +40,6 @@
static uint64_t dot11RSNAConfigPMKLifetime = 43200ULL * L_USEC_PER_SEC;
static uint32_t pmksa_cache_capacity = 255;
static pmksa_cache_add_func_t driver_add;
static pmksa_cache_remove_func_t driver_remove;
static pmksa_cache_flush_func_t driver_flush;
struct min_heap {
struct pmksa **data;
@ -145,7 +142,7 @@ int pmksa_cache_put(struct pmksa *pmksa)
l_debug("Adding entry with PMKID: "PMKID, PMKID_STR(pmksa->pmkid));
if (cache.used == cache.capacity) {
pmksa_cache_free(cache.data[0]);
l_free(cache.data[0]);
cache.data[0] = pmksa;
__minheap_sift_down(cache.data, cache.used, 0, &ops);
return 0;
@ -155,9 +152,6 @@ int pmksa_cache_put(struct pmksa *pmksa)
__minheap_sift_up(cache.data, cache.used, &ops);
cache.used += 1;
if (driver_add)
driver_add(pmksa);
return 0;
}
@ -173,7 +167,7 @@ int pmksa_cache_expire(uint64_t cutoff)
for (i = 0; i < used; i++) {
if (cache.data[i]->expiration <= cutoff) {
pmksa_cache_free(cache.data[i]);
l_free(cache.data[i]);
continue;
}
@ -196,30 +190,11 @@ int pmksa_cache_flush(void)
{
uint32_t i;
/*
* The driver flush operation is done via a single kernel API call which
* is why below we use l_free instead of pmksa_cache_free as to not
* induce a DEL_PMKSA kernel call for each entry.
*/
if (driver_flush)
driver_flush();
for (i = 0; i < cache.used; i++)
l_free(cache.data[i]);
memset(cache.data, 0, cache.capacity * sizeof(struct pmksa *));
cache.used = 0;
return 0;
}
int pmksa_cache_free(struct pmksa *pmksa)
{
if (driver_remove)
driver_remove(pmksa);
l_free(pmksa);
return 0;
}
@ -242,15 +217,6 @@ void __pmksa_set_config(const struct l_settings *config)
&pmksa_cache_capacity);
}
void __pmksa_set_driver_callbacks(pmksa_cache_add_func_t add,
pmksa_cache_remove_func_t remove,
pmksa_cache_flush_func_t flush)
{
driver_add = add;
driver_remove = remove;
driver_flush = flush;
}
static int pmksa_init(void)
{
cache.capacity = pmksa_cache_capacity;

View File

@ -32,10 +32,6 @@ struct pmksa {
size_t pmk_len;
};
typedef void (*pmksa_cache_add_func_t)(const struct pmksa *pmksa);
typedef void (*pmksa_cache_remove_func_t)(const struct pmksa *pmksa);
typedef void (*pmksa_cache_flush_func_t)(void);
struct pmksa **__pmksa_cache_get_all(uint32_t *out_n_entries);
struct pmksa *pmksa_cache_get(const uint8_t spa[static 6],
@ -45,11 +41,6 @@ struct pmksa *pmksa_cache_get(const uint8_t spa[static 6],
int pmksa_cache_put(struct pmksa *pmksa);
int pmksa_cache_expire(uint64_t cutoff);
int pmksa_cache_flush(void);
int pmksa_cache_free(struct pmksa *pmksa);
uint64_t pmksa_lifetime(void);
void __pmksa_set_config(const struct l_settings *config);
void __pmksa_set_driver_callbacks(pmksa_cache_add_func_t add,
pmksa_cache_remove_func_t remove,
pmksa_cache_flush_func_t flush);

View File

@ -143,9 +143,9 @@ struct scan_survey {
};
struct scan_survey_results {
struct scan_survey survey_2_4[15];
struct scan_survey survey_5[197];
struct scan_survey survey_6[234];
struct scan_survey survey_2_4[14];
struct scan_survey survey_5[196];
struct scan_survey survey_6[233];
};
struct scan_results {

View File

@ -155,55 +155,6 @@ struct anqp_entry {
uint32_t pending;
};
/*
* Rather than sorting BSS's purely based on ranking a higher level grouping
* is used. The purpose of this higher order grouping is the consider the BSS's
* roam blacklist status. The roam blacklist is a "soft" blacklist in that we
* still should connect to these BSS's if they are the only "good" option.
* The question here is: what makes a BSS "good" vs "bad".
*
* For an initial (probably naive) approach here we can use the
* RoamThreshold[5G] which indicates the signal level that would not
* be of an acceptable connection quality. BSS can then be sorted either
* above or below this threshold. Within each of these groups a BSS may be
* blacklisted, meaning it should get sorted lower on the list compared to
* others within the same group.
*
* This sorting is achieved by extending rank to a uint32_t where the first 16
* bits are the standard rank calculated by scan.c. Above that bits can be
* reserved for this higher level grouping:
*
* Bit 16 indicates the BSS is not blacklisted
* Bit 17 indicates the BSS is above the critical signal threshold
*/
#define ABOVE_THRESHOLD_BIT 17
#define NOT_BLACKLISTED_BIT 16
static uint32_t evaluate_bss_group_rank(const uint8_t *addr, uint32_t freq,
int16_t signal_strength, uint16_t rank)
{
int signal = signal_strength / 100;
bool roam_blacklist;
bool good_signal;
uint32_t rank_out = (uint32_t) rank;
if (blacklist_contains_bss(addr, BLACKLIST_REASON_CONNECT_FAILED))
return 0;
roam_blacklist = blacklist_contains_bss(addr,
BLACKLIST_REASON_ROAM_REQUESTED);
good_signal = signal >= netdev_get_low_signal_threshold(freq);
if (good_signal)
set_bit(&rank_out, ABOVE_THRESHOLD_BIT);
if (!roam_blacklist)
set_bit(&rank_out, NOT_BLACKLISTED_BIT);
return rank_out;
}
/*
* Used as entries for the roam list since holding scan_bss pointers directly
* from station->bss_list is not 100% safe due to the possibility of the
@ -211,13 +162,13 @@ static uint32_t evaluate_bss_group_rank(const uint8_t *addr, uint32_t freq,
*/
struct roam_bss {
uint8_t addr[6];
uint32_t rank;
uint16_t rank;
int32_t signal_strength;
bool ft_failed: 1;
};
static struct roam_bss *roam_bss_from_scan_bss(const struct scan_bss *bss,
uint32_t rank)
uint16_t rank)
{
struct roam_bss *rbss = l_new(struct roam_bss, 1);
@ -2854,7 +2805,7 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
struct handshake_state *hs = netdev_get_handshake(station->netdev);
struct scan_bss *current_bss = station->connected_bss;
struct scan_bss *bss;
uint32_t cur_bss_group_rank = 0;
double cur_bss_rank = 0.0;
static const double RANK_FT_FACTOR = 1.3;
uint16_t mdid;
enum security orig_security, security;
@ -2883,15 +2834,10 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
*/
bss = l_queue_find(bss_list, bss_match_bssid, current_bss->addr);
if (bss && !station->ap_directed_roaming) {
double cur_bss_rank = bss->rank;
cur_bss_rank = bss->rank;
if (hs->mde && bss->mde_present && l_get_le16(bss->mde) == mdid)
cur_bss_rank *= RANK_FT_FACTOR;
cur_bss_group_rank = evaluate_bss_group_rank(bss->addr,
bss->frequency,
bss->signal_strength,
(uint16_t) cur_bss_rank);
}
/*
@ -2913,7 +2859,6 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
while ((bss = l_queue_pop_head(bss_list))) {
double rank;
struct roam_bss *rbss;
uint32_t group_rank;
station_print_scan_bss(bss);
@ -2935,8 +2880,7 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
if (network_can_connect_bss(network, bss) < 0)
goto next;
if (blacklist_contains_bss(bss->addr,
BLACKLIST_REASON_CONNECT_FAILED))
if (blacklist_contains_bss(bss->addr))
goto next;
rank = bss->rank;
@ -2944,11 +2888,7 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
if (hs->mde && bss->mde_present && l_get_le16(bss->mde) == mdid)
rank *= RANK_FT_FACTOR;
group_rank = evaluate_bss_group_rank(bss->addr, bss->frequency,
bss->signal_strength,
(uint16_t) rank);
if (group_rank <= cur_bss_group_rank)
if (rank <= cur_bss_rank)
goto next;
/*
@ -2957,7 +2897,7 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
*/
station_update_roam_bss(station, bss);
rbss = roam_bss_from_scan_bss(bss, group_rank);
rbss = roam_bss_from_scan_bss(bss, rank);
l_queue_insert(station->roam_bss_list, rbss,
roam_bss_rank_compare, NULL);
@ -3225,10 +3165,12 @@ static void station_ap_directed_roam(struct station *station,
uint8_t req_mode;
uint16_t dtimer;
uint8_t valid_interval;
bool can_roam = !station_cannot_roam(station);
l_debug("ifindex: %u", netdev_get_ifindex(station->netdev));
if (station_cannot_roam(station))
return;
if (station->state != STATION_STATE_CONNECTED) {
l_debug("roam: unexpected AP directed roam -- ignore");
return;
@ -3292,13 +3234,8 @@ static void station_ap_directed_roam(struct station *station,
* disassociating us. If either of these bits are set, set the
* ap_directed_roaming flag. Otherwise still try roaming but don't
* treat it any different than a normal roam.
*
* The only exception here is if we are in the middle of roaming
* (can_roam == false) since we cannot reliably know if the roam scan
* included frequencies from potential candidates in this request,
* forcing a roam in this case might result in unintended behavior.
*/
if (can_roam && req_mode & (WNM_REQUEST_MODE_DISASSOCIATION_IMMINENT |
if (req_mode & (WNM_REQUEST_MODE_DISASSOCIATION_IMMINENT |
WNM_REQUEST_MODE_TERMINATION_IMMINENT |
WNM_REQUEST_MODE_ESS_DISASSOCIATION_IMMINENT))
station->ap_directed_roaming = true;
@ -3325,19 +3262,6 @@ static void station_ap_directed_roam(struct station *station,
pos += url_len;
}
blacklist_add_bss(station->connected_bss->addr,
BLACKLIST_REASON_ROAM_REQUESTED);
station_debug_event(station, "ap-roam-blacklist-added");
/*
* Validating the frame and blacklisting should still be done even if
* we are mid-roam. Its important to track the BSS requesting the
* transition so when the current roam completes IWD will be less likely
* to roam back to the current BSS.
*/
if (!can_roam)
return;
station->preparing_roam = true;
l_timeout_remove(station->roam_trigger_timeout);
@ -3476,15 +3400,7 @@ static bool station_retry_with_reason(struct station *station,
break;
}
blacklist_add_bss(station->connected_bss->addr,
BLACKLIST_REASON_CONNECT_FAILED);
/*
* Network blacklist the BSS as well, since the timeout blacklist could
* be disabled
*/
network_blacklist_add(station->connected_network,
station->connected_bss);
blacklist_add_bss(station->connected_bss->addr);
try_next:
return station_try_next_bss(station);
@ -3533,10 +3449,6 @@ static bool station_pmksa_fallback(struct station *station, uint16_t status)
static bool station_retry_with_status(struct station *station,
uint16_t status_code)
{
/* If PMKSA failed don't blacklist so we can retry this BSS */
if (station_pmksa_fallback(station, status_code))
goto try_next;
/*
* Certain Auth/Assoc failures should not cause a timeout blacklist.
* In these cases we want to only temporarily blacklist the BSS until
@ -3547,19 +3459,12 @@ static bool station_retry_with_status(struct station *station,
* specific BSS on our next attempt. There is currently no way to
* obtain that IE, but this should be done in the future.
*/
if (!IS_TEMPORARY_STATUS(status_code))
blacklist_add_bss(station->connected_bss->addr,
BLACKLIST_REASON_CONNECT_FAILED);
if (IS_TEMPORARY_STATUS(status_code))
network_blacklist_add(station->connected_network,
station->connected_bss);
else if (!station_pmksa_fallback(station, status_code))
blacklist_add_bss(station->connected_bss->addr);
/*
* Unconditionally network blacklist the BSS if we are retrying. This
* will allow network_bss_select to traverse the BSS list and ignore
* BSS's which have previously failed
*/
network_blacklist_add(station->connected_network,
station->connected_bss);
try_next:
iwd_notice(IWD_NOTICE_CONNECT_FAILED, "status: %u", status_code);
return station_try_next_bss(station);
@ -3644,8 +3549,7 @@ static void station_connect_cb(struct netdev *netdev, enum netdev_result result,
switch (result) {
case NETDEV_RESULT_OK:
blacklist_remove_bss(station->connected_bss->addr,
BLACKLIST_REASON_CONNECT_FAILED);
blacklist_remove_bss(station->connected_bss->addr);
station_connect_ok(station);
return;
case NETDEV_RESULT_DISCONNECTED:
@ -4836,8 +4740,7 @@ static struct l_dbus_message *station_property_set_affinities(
return dbus_error_invalid_args(message);
/* Get first entry, there should be only one */
if (!l_dbus_message_iter_next_entry(&array, &new_path))
return dbus_error_invalid_args(message);
l_dbus_message_iter_next_entry(&array, &new_path);
if (l_dbus_message_iter_next_entry(&array, &new_path))
return dbus_error_invalid_args(message);

View File

@ -500,13 +500,6 @@ int __storage_decrypt(struct l_settings *settings, const char *ssid,
return 0;
}
/*
* It should likely be far larger than this, but that will get caught
* later when reloading the decrypted data.
*/
if (elen < 16)
return -EBADMSG;
/*
* AES-SIV automatically verifies the IV (16 bytes) and returns only
* the decrypted data portion. We add one here for the NULL terminator

View File

@ -74,7 +74,6 @@ enum driver_flag {
POWER_SAVE_DISABLE = 0x4,
OWE_DISABLE = 0x8,
MULTICAST_RX_DISABLE = 0x10,
SAE_DISABLE = 0x20,
};
struct driver_flag_name {
@ -107,8 +106,7 @@ static const struct driver_flag_name driver_flag_names[] = {
{ "ForcePae", FORCE_PAE },
{ "PowerSaveDisable", POWER_SAVE_DISABLE },
{ "OweDisable", OWE_DISABLE },
{ "MulticastRxDisable", MULTICAST_RX_DISABLE },
{ "SaeDisable", SAE_DISABLE },
{ "MulticastRxDisable", MULTICAST_RX_DISABLE }
};
struct wiphy {
@ -204,9 +202,6 @@ uint16_t wiphy_get_supported_ciphers(struct wiphy *wiphy, uint16_t mask)
static bool wiphy_can_connect_sae(struct wiphy *wiphy)
{
if (wiphy->driver_flags & SAE_DISABLE)
return false;
/*
* WPA3 Specification version 3, Section 2.2:
* A STA shall not enable WEP and TKIP
@ -1376,12 +1371,6 @@ static void wiphy_print_basic_info(struct wiphy *wiphy)
if (wiphy->driver_flags & OWE_DISABLE)
flags = l_strv_append(flags, "OweDisable");
if (wiphy->driver_flags & MULTICAST_RX_DISABLE)
flags = l_strv_append(flags, "MulticastRxDisable");
if (wiphy->driver_flags & SAE_DISABLE)
flags = l_strv_append(flags, "SaeDisable");
joined = l_strjoinv(flags, ' ');
l_info("\tDriver Flags: %s", joined);

View File

@ -116,29 +116,6 @@ struct dpp_test_info bad_channels[] = {
},
};
struct dpp_test_info duplicates[] = {
/* Duplicate key */
{
.uri = "DPP:K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
.expect_fail = true
},
/* Duplicate frequencies*/
{
.uri = "DPP:C:81/1,115/36;C:81/1,115/36;;",
.expect_fail = true
},
/* Duplicate MACs*/
{
.uri = "DPP:M:5254005828e5;M:5254005828e5;;",
.expect_fail = true
},
/* Duplicate versions */
{
.uri = "DPP:V:2;V:2;;",
.expect_fail = true
},
};
static bool verify_info(const struct dpp_uri_info *parsed,
const struct dpp_test_info *result)
{
@ -181,14 +158,6 @@ static void test_bad_channels(const void *data)
test_uri_parse(&bad_channels[i]);
}
static void test_duplicate_in_uri(const void *data)
{
unsigned int i;
for (i = 0; i < L_ARRAY_SIZE(duplicates); i++)
test_uri_parse(&duplicates[i]);
}
struct dpp_test_vector {
/* Initiator values */
const char *i_proto_public;
@ -607,7 +576,6 @@ int main(int argc, char *argv[])
l_test_add("DPP URI bad key", test_uri_parse, &bad_key);
l_test_add("DPP URI bad channels", test_bad_channels, &bad_channels);
l_test_add("DPP URI unexpected ID", test_uri_parse, &unexpected_id);
l_test_add("DPP URI duplicates", test_duplicate_in_uri, &duplicates);
return l_test_run();
}

View File

@ -341,7 +341,7 @@ static const struct p2p_probe_req_data p2p_probe_req_data_1 = {
.group_caps = 0,
},
.listen_channel = {
.country = { 'X', 'X', '\x04' },
.country = "XX\x04",
.oper_class = 81,
.channel_num = 1,
},

View File

@ -1,55 +0,0 @@
/*
*
* Wireless daemon for Linux
*
* Copyright (C) 2025 Locus Robotics. All rights reserved.
*
* 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 <assert.h>
#include <ell/ell.h>
#include "src/storage.h"
static void test_short_encrypted_bytes(const void *data)
{
struct l_settings *settings = l_settings_new();
bool changed;
l_settings_set_string(settings, "Security", "EncryptedSecurity", "012345");
l_settings_set_string(settings, "Security", "EncryptedSalt", "012345");
assert(__storage_decrypt(settings, "mySSID", &changed) < 0);
l_settings_free(settings);
}
int main(int argc, char *argv[])
{
l_test_init(&argc, &argv);
storage_init((const uint8_t *)"abc123", 6);
l_test_add("/storage/profile encryption",
test_short_encrypted_bytes, NULL);
return l_test_run();
}