Merge ~antoinelassagne/ubuntu/+source/wpa:plucky-sru-2117497 into ubuntu/+source/wpa:ubuntu/plucky

Proposed by Antoine Lassagne
Status: Needs review
Proposed branch: ~antoinelassagne/ubuntu/+source/wpa:plucky-sru-2117497
Merge into: ubuntu/+source/wpa:ubuntu/plucky
Diff against target: 123627 lines (+66346/-12714)
368 files modified
CONTRIBUTIONS (+1/-1)
README (+1/-1)
debian/changelog (+12/-0)
debian/control (+2/-1)
debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch (+45/-0)
debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch (+5/-15)
debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch (+25/-0)
debian/patches/series (+2/-7)
debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch (+14/-10)
dev/null (+0/-36)
hostapd/Android.mk (+27/-1)
hostapd/ChangeLog (+37/-0)
hostapd/Makefile (+28/-2)
hostapd/README (+1/-1)
hostapd/android.config (+6/-0)
hostapd/config_file.c (+428/-53)
hostapd/config_file.h (+2/-5)
hostapd/ctrl_iface.c (+1020/-440)
hostapd/defconfig (+18/-3)
hostapd/hostapd.conf (+346/-10)
hostapd/hostapd.eap_user (+2/-2)
hostapd/hostapd_cli.c (+181/-36)
hostapd/main.c (+136/-6)
hs20/client/Android.mk (+10/-0)
hs20/client/est.c (+5/-32)
hs20/client/osu_client.c (+79/-36)
hs20/client/spp_client.c (+0/-1)
hs20/server/spp_server.c (+4/-1)
src/Makefile (+1/-1)
src/ap/acs.c (+471/-97)
src/ap/acs.h (+3/-0)
src/ap/airtime_policy.c (+1/-1)
src/ap/ap_config.c (+173/-32)
src/ap/ap_config.h (+214/-12)
src/ap/ap_drv_ops.c (+306/-53)
src/ap/ap_drv_ops.h (+73/-11)
src/ap/ap_list.c (+3/-3)
src/ap/ap_mlme.c (+2/-2)
src/ap/authsrv.c (+94/-0)
src/ap/beacon.c (+1020/-192)
src/ap/beacon.h (+4/-0)
src/ap/bss_load.c (+1/-1)
src/ap/comeback_token.c (+139/-0)
src/ap/comeback_token.h (+21/-0)
src/ap/ctrl_iface_ap.c (+586/-13)
src/ap/ctrl_iface_ap.h (+17/-0)
src/ap/dfs.c (+452/-156)
src/ap/dpp_hostapd.c (+1355/-62)
src/ap/dpp_hostapd.h (+5/-0)
src/ap/drv_callbacks.c (+781/-100)
src/ap/fils_hlp.c (+5/-5)
src/ap/gas_query_ap.c (+7/-3)
src/ap/gas_serv.c (+6/-5)
src/ap/gas_serv.h (+1/-1)
src/ap/hostapd.c (+1311/-130)
src/ap/hostapd.h (+163/-6)
src/ap/hw_features.c (+206/-27)
src/ap/hw_features.h (+12/-0)
src/ap/ieee802_11.c (+2426/-1604)
src/ap/ieee802_11.h (+75/-8)
src/ap/ieee802_11_auth.c (+131/-31)
src/ap/ieee802_11_auth.h (+4/-1)
src/ap/ieee802_11_eht.c (+1405/-0)
src/ap/ieee802_11_he.c (+68/-19)
src/ap/ieee802_11_ht.c (+2/-3)
src/ap/ieee802_11_shared.c (+174/-41)
src/ap/ieee802_11_vht.c (+23/-9)
src/ap/ieee802_1x.c (+187/-46)
src/ap/ieee802_1x.h (+1/-1)
src/ap/nan_usd_ap.c (+267/-0)
src/ap/nan_usd_ap.h (+46/-0)
src/ap/ndisc_snoop.c (+1/-0)
src/ap/neighbor_db.c (+59/-15)
src/ap/neighbor_db.h (+1/-0)
src/ap/pmksa_cache_auth.c (+24/-8)
src/ap/pmksa_cache_auth.h (+4/-0)
src/ap/preauth_auth.c (+2/-2)
src/ap/rrm.c (+121/-0)
src/ap/rrm.h (+2/-0)
src/ap/sta_info.c (+395/-74)
src/ap/sta_info.h (+65/-31)
src/ap/utils.c (+13/-1)
src/ap/wmm.c (+0/-7)
src/ap/wnm_ap.c (+204/-12)
src/ap/wpa_auth.c (+2012/-447)
src/ap/wpa_auth.h (+93/-10)
src/ap/wpa_auth_ft.c (+400/-215)
src/ap/wpa_auth_glue.c (+236/-33)
src/ap/wpa_auth_i.h (+42/-5)
src/ap/wpa_auth_ie.c (+81/-14)
src/ap/wpa_auth_kay.c (+9/-36)
src/ap/wps_hostapd.c (+3/-2)
src/ap/x_snoop.c (+5/-0)
src/build.rules (+1/-1)
src/common/brcm_vendor.h (+4/-4)
src/common/common_module_tests.c (+1/-1)
src/common/defs.h (+62/-5)
src/common/dpp.c (+827/-56)
src/common/dpp.h (+124/-8)
src/common/dpp_crypto.c (+201/-38)
src/common/dpp_i.h (+14/-5)
src/common/dpp_pkex.c (+37/-22)
src/common/dpp_reconfig.c (+17/-1)
src/common/dpp_tcp.c (+875/-41)
src/common/dragonfly.c (+6/-3)
src/common/gas_server.c (+61/-18)
src/common/gas_server.h (+4/-1)
src/common/hw_features_common.c (+266/-37)
src/common/hw_features_common.h (+9/-3)
src/common/ieee802_11_common.c (+895/-195)
src/common/ieee802_11_common.h (+60/-29)
src/common/ieee802_11_defs.h (+642/-80)
src/common/nan.h (+98/-0)
src/common/nan_de.c (+1395/-0)
src/common/nan_de.h (+145/-0)
src/common/ocv.c (+2/-3)
src/common/ptksa_cache.c (+70/-4)
src/common/ptksa_cache.h (+9/-38)
src/common/qca-vendor.h (+6164/-159)
src/common/sae.c (+125/-14)
src/common/sae.h (+11/-3)
src/common/version.h (+1/-1)
src/common/wpa_common.c (+760/-235)
src/common/wpa_common.h (+123/-11)
src/common/wpa_ctrl.c (+13/-3)
src/common/wpa_ctrl.h (+36/-0)
src/crypto/crypto.h (+114/-3)
src/crypto/crypto_gnutls.c (+5/-0)
src/crypto/crypto_internal.c (+5/-0)
src/crypto/crypto_libtomcrypt.c (+5/-0)
src/crypto/crypto_linux.c (+5/-0)
src/crypto/crypto_module_tests.c (+281/-0)
src/crypto/crypto_nettle.c (+5/-0)
src/crypto/crypto_none.c (+5/-0)
src/crypto/crypto_openssl.c (+2481/-141)
src/crypto/crypto_wolfssl.c (+1889/-154)
src/crypto/fips_prf_internal.c (+4/-7)
src/crypto/fips_prf_openssl.c (+15/-0)
src/crypto/sha1-pbkdf2.c (+3/-0)
src/crypto/sha256-internal.c (+0/-3)
src/crypto/sha256.c (+15/-6)
src/crypto/sha384.c (+3/-3)
src/crypto/sha512-internal.c (+0/-3)
src/crypto/sha512.c (+3/-3)
src/crypto/tls.h (+12/-6)
src/crypto/tls_gnutls.c (+1/-0)
src/crypto/tls_internal.c (+2/-9)
src/crypto/tls_none.c (+1/-0)
src/crypto/tls_openssl.c (+409/-155)
src/crypto/tls_openssl_ocsp.c (+11/-15)
src/crypto/tls_wolfssl.c (+195/-89)
src/drivers/driver.h (+900/-64)
src/drivers/driver_atheros.c (+16/-15)
src/drivers/driver_bsd.c (+9/-7)
src/drivers/driver_common.c (+44/-0)
src/drivers/driver_hostap.c (+11/-9)
src/drivers/driver_macsec_linux.c (+72/-4)
src/drivers/driver_macsec_qca.c (+2/-2)
src/drivers/driver_ndis.c (+4/-4)
src/drivers/driver_nl80211.c (+2673/-770)
src/drivers/driver_nl80211.h (+95/-18)
src/drivers/driver_nl80211_capa.c (+286/-68)
src/drivers/driver_nl80211_event.c (+1180/-111)
src/drivers/driver_nl80211_scan.c (+90/-37)
src/drivers/driver_roboswitch.c (+1/-1)
src/drivers/driver_wext.c (+6/-5)
src/drivers/driver_wired.c (+1/-1)
src/drivers/linux_ioctl.c (+10/-1)
src/drivers/ndis_events.c (+3/-2)
src/drivers/netlink.c (+4/-2)
src/drivers/nl80211_copy.h (+598/-28)
src/eap_common/eap_defs.h (+1/-1)
src/eap_common/eap_pwd_common.c (+19/-4)
src/eap_common/eap_sake_common.c (+13/-6)
src/eap_peer/eap.c (+44/-0)
src/eap_peer/eap_aka.c (+154/-44)
src/eap_peer/eap_config.h (+28/-18)
src/eap_peer/eap_fast.c (+2/-12)
src/eap_peer/eap_i.h (+9/-0)
src/eap_peer/eap_mschapv2.c (+25/-5)
src/eap_peer/eap_peap.c (+37/-3)
src/eap_peer/eap_pwd.c (+26/-7)
src/eap_peer/eap_sim.c (+158/-44)
src/eap_peer/eap_teap.c (+34/-27)
src/eap_peer/eap_tls.c (+11/-4)
src/eap_peer/eap_tls_common.c (+18/-9)
src/eap_peer/eap_tls_common.h (+5/-0)
src/eap_peer/eap_ttls.c (+29/-3)
src/eap_peer/eap_wsc.c (+12/-2)
src/eap_server/eap.h (+12/-0)
src/eap_server/eap_i.h (+7/-0)
src/eap_server/eap_server_aka.c (+117/-9)
src/eap_server/eap_server_eke.c (+1/-0)
src/eap_server/eap_server_fast.c (+2/-12)
src/eap_server/eap_server_mschapv2.c (+25/-3)
src/eap_server/eap_server_peap.c (+18/-0)
src/eap_server/eap_server_pwd.c (+26/-7)
src/eap_server/eap_server_sim.c (+127/-6)
src/eap_server/eap_server_teap.c (+36/-3)
src/eap_server/eap_server_tls.c (+9/-1)
src/eap_server/eap_server_tls_common.c (+15/-3)
src/eap_server/eap_server_ttls.c (+2/-1)
src/eap_server/eap_tls_common.h (+2/-0)
src/eapol_auth/eapol_auth_sm.c (+19/-7)
src/eapol_auth/eapol_auth_sm.h (+3/-2)
src/eapol_auth/eapol_auth_sm_i.h (+4/-0)
src/eapol_supp/eapol_supp_sm.c (+16/-1)
src/eapol_supp/eapol_supp_sm.h (+16/-2)
src/fst/fst_group.c (+8/-4)
src/fst/fst_iface.c (+1/-1)
src/fst/fst_session.c (+2/-4)
src/l2_packet/l2_packet_freebsd.c (+13/-2)
src/l2_packet/l2_packet_linux.c (+2/-2)
src/p2p/p2p.c (+80/-43)
src/p2p/p2p.h (+9/-3)
src/p2p/p2p_build.c (+13/-7)
src/p2p/p2p_dev_disc.c (+5/-5)
src/p2p/p2p_go_neg.c (+94/-27)
src/p2p/p2p_group.c (+7/-7)
src/p2p/p2p_i.h (+15/-4)
src/p2p/p2p_invitation.c (+23/-8)
src/p2p/p2p_parse.c (+24/-3)
src/p2p/p2p_pd.c (+29/-14)
src/p2p/p2p_sd.c (+15/-8)
src/p2p/p2p_utils.c (+80/-4)
src/pae/ieee802_1x_cp.c (+11/-4)
src/pae/ieee802_1x_kay.c (+58/-16)
src/pae/ieee802_1x_kay.h (+4/-1)
src/pae/ieee802_1x_secy_ops.c (+20/-0)
src/pae/ieee802_1x_secy_ops.h (+1/-0)
src/pasn/Makefile (+16/-0)
src/pasn/pasn_common.c (+232/-0)
src/pasn/pasn_common.h (+228/-0)
src/pasn/pasn_initiator.c (+1406/-0)
src/pasn/pasn_responder.c (+1032/-0)
src/radius/radius.c (+238/-59)
src/radius/radius.h (+33/-2)
src/radius/radius_client.c (+580/-209)
src/radius/radius_client.h (+26/-1)
src/radius/radius_das.c (+10/-0)
src/radius/radius_server.c (+15/-0)
src/rsn_supp/pmksa_cache.c (+231/-29)
src/rsn_supp/pmksa_cache.h (+17/-88)
src/rsn_supp/preauth.c (+11/-8)
src/rsn_supp/tdls.c (+259/-73)
src/rsn_supp/wpa.c (+1817/-373)
src/rsn_supp/wpa.h (+75/-13)
src/rsn_supp/wpa_ft.c (+189/-139)
src/rsn_supp/wpa_i.h (+54/-11)
src/rsn_supp/wpa_ie.c (+28/-8)
src/tls/libtommath.c (+0/-8)
src/tls/pkcs1.c (+4/-2)
src/tls/tlsv1_client_read.c (+2/-1)
src/tls/tlsv1_common.c (+4/-2)
src/tls/tlsv1_common.h (+2/-1)
src/tls/tlsv1_server_write.c (+1/-1)
src/utils/browser.c (+10/-0)
src/utils/common.c (+14/-1)
src/utils/common.h (+38/-0)
src/utils/crc32.c (+1/-1)
src/utils/crc32.h (+1/-1)
src/utils/http-utils.h (+1/-0)
src/utils/http_curl.c (+28/-45)
src/utils/ip_addr.c (+19/-0)
src/utils/ip_addr.h (+2/-0)
src/utils/os.h (+36/-6)
src/utils/os_unix.c (+107/-88)
src/utils/trace.c (+3/-3)
src/utils/wpa_debug.c (+9/-1)
src/utils/wpa_debug.h (+1/-0)
src/utils/wpabuf.h (+6/-0)
src/wps/ndef.c (+6/-0)
src/wps/wps.c (+3/-2)
src/wps/wps.h (+5/-0)
src/wps/wps_attr_parse.c (+12/-1)
src/wps/wps_enrollee.c (+2/-4)
src/wps/wps_er.c (+2/-2)
src/wps/wps_i.h (+1/-0)
src/wps/wps_registrar.c (+7/-8)
wpa_supplicant/Android.mk (+217/-11)
wpa_supplicant/ChangeLog (+50/-0)
wpa_supplicant/Makefile (+288/-20)
wpa_supplicant/README (+3/-1)
wpa_supplicant/README-HS20 (+32/-1)
wpa_supplicant/README-NAN-USD (+147/-0)
wpa_supplicant/README-WPS (+9/-15)
wpa_supplicant/android.config (+15/-0)
wpa_supplicant/ap.c (+266/-27)
wpa_supplicant/ap.h (+22/-2)
wpa_supplicant/bgscan.h (+1/-1)
wpa_supplicant/bgscan_learn.c (+5/-5)
wpa_supplicant/bgscan_simple.c (+61/-3)
wpa_supplicant/bss.c (+523/-40)
wpa_supplicant/bss.h (+29/-0)
wpa_supplicant/bssid_ignore.c (+15/-15)
wpa_supplicant/config.c (+409/-78)
wpa_supplicant/config.h (+127/-23)
wpa_supplicant/config_file.c (+89/-19)
wpa_supplicant/config_none.c (+2/-1)
wpa_supplicant/config_ssid.h (+110/-4)
wpa_supplicant/config_winreg.c (+2/-3)
wpa_supplicant/ctrl_iface.c (+1451/-256)
wpa_supplicant/ctrl_iface.h (+2/-0)
wpa_supplicant/ctrl_iface_unix.c (+3/-0)
wpa_supplicant/dbus/dbus_dict_helpers.c (+100/-0)
wpa_supplicant/dbus/dbus_dict_helpers.h (+9/-0)
wpa_supplicant/dbus/dbus_new.c (+141/-1)
wpa_supplicant/dbus/dbus_new.h (+24/-0)
wpa_supplicant/dbus/dbus_new_handlers.c (+660/-124)
wpa_supplicant/dbus/dbus_new_handlers.h (+7/-0)
wpa_supplicant/dbus/dbus_new_handlers_p2p.c (+73/-21)
wpa_supplicant/dbus/dbus_new_helpers.c (+193/-16)
wpa_supplicant/dbus/dbus_new_helpers.h (+5/-0)
wpa_supplicant/dbus/dbus_new_introspect.c (+1/-1)
wpa_supplicant/defconfig (+53/-0)
wpa_supplicant/doc/docbook/wpa_supplicant.sgml (+35/-13)
wpa_supplicant/dpp_supplicant.c (+1992/-192)
wpa_supplicant/dpp_supplicant.h (+5/-0)
wpa_supplicant/driver_i.h (+91/-33)
wpa_supplicant/eapol_test.c (+109/-37)
wpa_supplicant/events.c (+1464/-277)
wpa_supplicant/examples/dpp-nfc.py (+8/-2)
wpa_supplicant/gas_query.c (+36/-20)
wpa_supplicant/hs20_supplicant.c (+8/-9)
wpa_supplicant/ibss_rsn.c (+18/-14)
wpa_supplicant/ibss_rsn.h (+2/-1)
wpa_supplicant/interworking.c (+79/-45)
wpa_supplicant/main.c (+2/-0)
wpa_supplicant/mbo.c (+21/-4)
wpa_supplicant/mesh.c (+11/-5)
wpa_supplicant/mesh_mpm.c (+55/-19)
wpa_supplicant/mesh_rsn.c (+23/-4)
wpa_supplicant/nan_usd.c (+513/-0)
wpa_supplicant/nan_usd.h (+46/-0)
wpa_supplicant/notify.c (+94/-9)
wpa_supplicant/notify.h (+13/-1)
wpa_supplicant/offchannel.c (+5/-5)
wpa_supplicant/op_classes.c (+130/-20)
wpa_supplicant/p2p_supplicant.c (+310/-173)
wpa_supplicant/p2p_supplicant.h (+6/-7)
wpa_supplicant/p2p_supplicant_sd.c (+12/-2)
wpa_supplicant/pasn_supplicant.c (+489/-1219)
wpa_supplicant/preauth_test.c (+5/-3)
wpa_supplicant/robust_av.c (+296/-45)
wpa_supplicant/rrm.c (+94/-38)
wpa_supplicant/scan.c (+631/-143)
wpa_supplicant/scan.h (+21/-9)
wpa_supplicant/sme.c (+811/-137)
wpa_supplicant/sme.h (+4/-10)
wpa_supplicant/systemd/wpa_supplicant-nl80211.service.arg.in (+1/-1)
wpa_supplicant/systemd/wpa_supplicant.service.arg.in (+1/-1)
wpa_supplicant/utils/log2pcap.py (+5/-4)
wpa_supplicant/wmm_ac.c (+3/-3)
wpa_supplicant/wnm_sta.c (+312/-220)
wpa_supplicant/wnm_sta.h (+28/-2)
wpa_supplicant/wpa_cli.c (+129/-15)
wpa_supplicant/wpa_passphrase.c (+24/-1)
wpa_supplicant/wpa_priv.c (+8/-3)
wpa_supplicant/wpa_supplicant.c (+1272/-407)
wpa_supplicant/wpa_supplicant.conf (+99/-10)
wpa_supplicant/wpa_supplicant_i.h (+205/-81)
wpa_supplicant/wpa_supplicant_template.conf (+2/-0)
wpa_supplicant/wpas_glue.c (+115/-44)
wpa_supplicant/wpas_glue.h (+2/-0)
wpa_supplicant/wpas_kay.c (+16/-37)
wpa_supplicant/wpas_module_tests.c (+3/-0)
wpa_supplicant/wps_supplicant.c (+122/-44)
wpa_supplicant/wps_supplicant.h (+13/-0)
Reviewer Review Type Date Requested Status
Nick Rosbrook (community) Needs Information
git-ubuntu import Pending
Review via email: mp+493297@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Nick Rosbrook (enr0n) wrote :
review: Needs Information

Unmerged commits

5a2ab65... by Antoine Lassagne

Changelog update

827a47a... by Tobias Heider

Changelog

0f7ffd1... by Tobias Heider

Revert commit breaking authentication on brcmfmac

13c020a... by Mitchell Augustin

Bump DEFAULT_BSS_MAX_COUNT to 1000 (LP: #2117180)

e8728b7... by Antoine Lassagne

2:2.11-0ubuntu1 (patches unapplied)

Imported using git-ubuntu import.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/CONTRIBUTIONS b/CONTRIBUTIONS
index b2064dc..6c8187c 100644
--- a/CONTRIBUTIONS
+++ b/CONTRIBUTIONS
@@ -37,7 +37,7 @@ without moderation. You can subscribe to the list at this address:
37http://lists.infradead.org/mailman/listinfo/hostap37http://lists.infradead.org/mailman/listinfo/hostap
3838
39The message should contain an inlined patch against the current39The message should contain an inlined patch against the current
40development branch (i.e., the master branch of40development branch (i.e., the main branch of
41git://w1.fi/hostap.git). Please make sure the software you use for41git://w1.fi/hostap.git). Please make sure the software you use for
42sending the patch does not corrupt whitespace. If that cannot be fixed42sending the patch does not corrupt whitespace. If that cannot be fixed
43for some reason, it is better to include an attached version of the43for some reason, it is better to include an attached version of the
diff --git a/README b/README
index 1470c4f..8392bb3 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
1wpa_supplicant and hostapd1wpa_supplicant and hostapd
2--------------------------2--------------------------
33
4Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors4Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> and contributors
5All Rights Reserved.5All Rights Reserved.
66
7These programs are licensed under the BSD license (the one with7These programs are licensed under the BSD license (the one with
diff --git a/debian/.gitignore b/debian/.gitignore
8deleted file mode 1006448deleted file mode 100644
index 66fe32a..0000000
--- a/debian/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
1*.debhelper
2*.substvars
3.debhelper/
4debhelper-build-stamp
5eapoltest/
6files
7hostapd/
8libwpa-client-dev/
9wpagui/
10wpasupplicant-udeb/
11wpasupplicant/
diff --git a/debian/changelog b/debian/changelog
index 6eff64f..9630d1e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
1wpa (2:2.11-0ubuntu3~25.04.1) plucky; urgency=medium
2
3 * Backport of Questing's version to Plucky
4
5 -- Antoine Lassagne <antoine.lassagne@canonical.com> Thu, 25 Sep 2025 12:21:04 +0200
6
7wpa (2:2.10-24ubuntu0.1) plucky; urgency=medium
8
9 * Bump DEFAULT_BSS_MAX_COUNT to 1000 (LP: #2117180)
10
11 -- Mitchell Augustin <mitchell.augustin@canonical.com> Mon, 21 Jul 2025 18:13:31 -0500
12
1wpa (2:2.10-24) unstable; urgency=medium13wpa (2:2.10-24) unstable; urgency=medium
214
3 [ Hlib Korzhynskyy ]15 [ Hlib Korzhynskyy ]
diff --git a/debian/control b/debian/control
index 803df6b..3be6d04 100644
--- a/debian/control
+++ b/debian/control
@@ -1,5 +1,6 @@
1Source: wpa1Source: wpa
2Maintainer: Debian wpasupplicant Maintainers <wpa@packages.debian.org>2Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
3XSBC-Original-Maintainer: Debian wpasupplicant Maintainers <wpa@packages.debian.org>
3Uploaders:4Uploaders:
4 Andrej Shadura <andrewsh@debian.org>5 Andrej Shadura <andrewsh@debian.org>
5Section: net6Section: net
diff --git a/debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch b/debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch
6new file mode 1006447new file mode 100644
index 0000000..09b239f
--- /dev/null
+++ b/debian/patches/0015-Revert-Mark-authorization-completed-on-driver-indica.patch
@@ -0,0 +1,45 @@
1From: Tobias Heider <me@tobhe.de>
2Date: Mon, 1 Sep 2025 22:18:55 +0200
3Subject: Revert "Mark authorization completed on driver indication during
4 4-way HS offload"
5
6---
7 wpa_supplicant/events.c | 25 ++++++++-----------------
8 1 file changed, 8 insertions(+), 17 deletions(-)
9
10diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
11index 7a6133c..56a9b81 100644
12--- a/wpa_supplicant/events.c
13+++ b/wpa_supplicant/events.c
14@@ -4327,23 +4327,14 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
15 eapol_sm_notify_eap_success(wpa_s->eapol, true);
16 } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
17 wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
18- if (already_authorized) {
19- /*
20- * We are done; the driver will take care of RSN 4-way
21- * handshake.
22- */
23- wpa_supplicant_cancel_auth_timeout(wpa_s);
24- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
25- eapol_sm_notify_portValid(wpa_s->eapol, true);
26- eapol_sm_notify_eap_success(wpa_s->eapol, true);
27- } else {
28- /* Update port, WPA_COMPLETED state from the
29- * EVENT_PORT_AUTHORIZED handler when the driver is done
30- * with the 4-way handshake.
31- */
32- wpa_msg(wpa_s, MSG_DEBUG,
33- "ASSOC INFO: wait for driver port authorized indication");
34- }
35+ /*
36+ * We are done; the driver will take care of RSN 4-way
37+ * handshake.
38+ */
39+ wpa_supplicant_cancel_auth_timeout(wpa_s);
40+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
41+ eapol_sm_notify_portValid(wpa_s->eapol, true);
42+ eapol_sm_notify_eap_success(wpa_s->eapol, true);
43 } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
44 wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
45 /*
diff --git a/debian/patches/0017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch b/debian/patches/0017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch
0deleted file mode 10064446deleted file mode 100644
index 19abe4e..0000000
--- a/debian/patches/0017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch
+++ /dev/null
@@ -1,211 +0,0 @@
1From: Jouni Malinen <j@w1.fi>
2Date: Sat, 8 Jul 2023 19:55:32 +0300
3Subject: CVE-2023-52160 PEAP client: Update Phase 2 authentication
4 requirements
5
6The previous PEAP client behavior allowed the server to skip Phase 2
7authentication with the expectation that the server was authenticated
8during Phase 1 through TLS server certificate validation. Various PEAP
9specifications are not exactly clear on what the behavior on this front
10is supposed to be and as such, this ended up being more flexible than
11the TTLS/FAST/TEAP cases. However, this is not really ideal when
12unfortunately common misconfiguration of PEAP is used in deployed
13devices where the server trust root (ca_cert) is not configured or the
14user has an easy option for allowing this validation step to be skipped.
15
16Change the default PEAP client behavior to be to require Phase 2
17authentication to be successfully completed for cases where TLS session
18resumption is not used and the client certificate has not been
19configured. Those two exceptions are the main cases where a deployed
20authentication server might skip Phase 2 and as such, where a more
21strict default behavior could result in undesired interoperability
22issues. Requiring Phase 2 authentication will end up disabling TLS
23session resumption automatically to avoid interoperability issues.
24
25Allow Phase 2 authentication behavior to be configured with a new phase1
26configuration parameter option:
27'phase2_auth' option can be used to control Phase 2 (i.e., within TLS
28tunnel) behavior for PEAP:
29 * 0 = do not require Phase 2 authentication
30 * 1 = require Phase 2 authentication when client certificate
31 (private_key/client_cert) is no used and TLS session resumption was
32 not used (default)
33 * 2 = require Phase 2 authentication in all cases
34
35Signed-off-by: Jouni Malinen <j@w1.fi>
36origin: https://w1.fi/cgit/hostap/commit/?id=8e6485a1bcb0baffdea9e55255a81270b768439c
37bug: https://www.top10vpn.com/research/wifi-vulnerabilities/
38bug-debian-security: https://security-tracker.debian.org/tracker/CVE-2023-52160
39bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064061
40---
41 src/eap_peer/eap_config.h | 8 ++++++++
42 src/eap_peer/eap_peap.c | 40 +++++++++++++++++++++++++++++++++++---
43 src/eap_peer/eap_tls_common.c | 6 ++++++
44 src/eap_peer/eap_tls_common.h | 5 +++++
45 wpa_supplicant/wpa_supplicant.conf | 7 +++++++
46 5 files changed, 63 insertions(+), 3 deletions(-)
47
48diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
49index 3238f74..047eec2 100644
50--- a/src/eap_peer/eap_config.h
51+++ b/src/eap_peer/eap_config.h
52@@ -469,6 +469,14 @@ struct eap_peer_config {
53 * 1 = use cryptobinding if server supports it
54 * 2 = require cryptobinding
55 *
56+ * phase2_auth option can be used to control Phase 2 (i.e., within TLS
57+ * tunnel) behavior for PEAP:
58+ * 0 = do not require Phase 2 authentication
59+ * 1 = require Phase 2 authentication when client certificate
60+ * (private_key/client_cert) is no used and TLS session resumption was
61+ * not used (default)
62+ * 2 = require Phase 2 authentication in all cases
63+ *
64 * EAP-WSC (WPS) uses following options: pin=Device_Password and
65 * uuid=Device_UUID
66 *
67diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
68index 12e30df..6080697 100644
69--- a/src/eap_peer/eap_peap.c
70+++ b/src/eap_peer/eap_peap.c
71@@ -67,6 +67,7 @@ struct eap_peap_data {
72 u8 cmk[20];
73 int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP)
74 * is enabled. */
75+ enum { NO_AUTH, FOR_INITIAL, ALWAYS } phase2_auth;
76 };
77
78
79@@ -114,6 +115,19 @@ static void eap_peap_parse_phase1(struct eap_peap_data *data,
80 wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding");
81 }
82
83+ if (os_strstr(phase1, "phase2_auth=0")) {
84+ data->phase2_auth = NO_AUTH;
85+ wpa_printf(MSG_DEBUG,
86+ "EAP-PEAP: Do not require Phase 2 authentication");
87+ } else if (os_strstr(phase1, "phase2_auth=1")) {
88+ data->phase2_auth = FOR_INITIAL;
89+ wpa_printf(MSG_DEBUG,
90+ "EAP-PEAP: Require Phase 2 authentication for initial connection");
91+ } else if (os_strstr(phase1, "phase2_auth=2")) {
92+ data->phase2_auth = ALWAYS;
93+ wpa_printf(MSG_DEBUG,
94+ "EAP-PEAP: Require Phase 2 authentication for all cases");
95+ }
96 #ifdef EAP_TNC
97 if (os_strstr(phase1, "tnc=soh2")) {
98 data->soh = 2;
99@@ -142,6 +156,7 @@ static void * eap_peap_init(struct eap_sm *sm)
100 data->force_peap_version = -1;
101 data->peap_outer_success = 2;
102 data->crypto_binding = OPTIONAL_BINDING;
103+ data->phase2_auth = FOR_INITIAL;
104
105 if (config && config->phase1)
106 eap_peap_parse_phase1(data, config->phase1);
107@@ -454,6 +469,20 @@ static int eap_tlv_validate_cryptobinding(struct eap_sm *sm,
108 }
109
110
111+static bool peap_phase2_sufficient(struct eap_sm *sm,
112+ struct eap_peap_data *data)
113+{
114+ if ((data->phase2_auth == ALWAYS ||
115+ (data->phase2_auth == FOR_INITIAL &&
116+ !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn) &&
117+ !data->ssl.client_cert_conf) ||
118+ data->phase2_eap_started) &&
119+ !data->phase2_eap_success)
120+ return false;
121+ return true;
122+}
123+
124+
125 /**
126 * eap_tlv_process - Process a received EAP-TLV message and generate a response
127 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
128@@ -568,6 +597,11 @@ static int eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data,
129 " - force failed Phase 2");
130 resp_status = EAP_TLV_RESULT_FAILURE;
131 ret->decision = DECISION_FAIL;
132+ } else if (!peap_phase2_sufficient(sm, data)) {
133+ wpa_printf(MSG_INFO,
134+ "EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed");
135+ resp_status = EAP_TLV_RESULT_FAILURE;
136+ ret->decision = DECISION_FAIL;
137 } else {
138 resp_status = EAP_TLV_RESULT_SUCCESS;
139 ret->decision = DECISION_UNCOND_SUCC;
140@@ -887,8 +921,7 @@ continue_req:
141 /* EAP-Success within TLS tunnel is used to indicate
142 * shutdown of the TLS channel. The authentication has
143 * been completed. */
144- if (data->phase2_eap_started &&
145- !data->phase2_eap_success) {
146+ if (!peap_phase2_sufficient(sm, data)) {
147 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 "
148 "Success used to indicate success, "
149 "but Phase 2 EAP was not yet "
150@@ -1199,8 +1232,9 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
151 static bool eap_peap_has_reauth_data(struct eap_sm *sm, void *priv)
152 {
153 struct eap_peap_data *data = priv;
154+
155 return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
156- data->phase2_success;
157+ data->phase2_success && data->phase2_auth != ALWAYS;
158 }
159
160
161diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
162index c1837db..a53eeb1 100644
163--- a/src/eap_peer/eap_tls_common.c
164+++ b/src/eap_peer/eap_tls_common.c
165@@ -239,6 +239,12 @@ static int eap_tls_params_from_conf(struct eap_sm *sm,
166
167 sm->ext_cert_check = !!(params->flags & TLS_CONN_EXT_CERT_CHECK);
168
169+ if (!phase2)
170+ data->client_cert_conf = params->client_cert ||
171+ params->client_cert_blob ||
172+ params->private_key ||
173+ params->private_key_blob;
174+
175 return 0;
176 }
177
178diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
179index 9ac0012..3348634 100644
180--- a/src/eap_peer/eap_tls_common.h
181+++ b/src/eap_peer/eap_tls_common.h
182@@ -79,6 +79,11 @@ struct eap_ssl_data {
183 * tls_v13 - Whether TLS v1.3 or newer is used
184 */
185 int tls_v13;
186+
187+ /**
188+ * client_cert_conf: Whether client certificate has been configured
189+ */
190+ bool client_cert_conf;
191 };
192
193
194diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
195index 6619d6b..d63f73c 100644
196--- a/wpa_supplicant/wpa_supplicant.conf
197+++ b/wpa_supplicant/wpa_supplicant.conf
198@@ -1321,6 +1321,13 @@ fast_reauth=1
199 # * 0 = do not use cryptobinding (default)
200 # * 1 = use cryptobinding if server supports it
201 # * 2 = require cryptobinding
202+# 'phase2_auth' option can be used to control Phase 2 (i.e., within TLS
203+# tunnel) behavior for PEAP:
204+# * 0 = do not require Phase 2 authentication
205+# * 1 = require Phase 2 authentication when client certificate
206+# (private_key/client_cert) is no used and TLS session resumption was
207+# not used (default)
208+# * 2 = require Phase 2 authentication in all cases
209 # EAP-WSC (WPS) uses following options: pin=<Device Password> or
210 # pbc=1.
211 #
diff --git a/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch b/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
index 0cbb7dd..6a982e6 100644
--- a/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
+++ b/debian/patches/0019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
@@ -24,22 +24,12 @@ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
24index f55e184..25b0c24 10064424index f55e184..25b0c24 100644
25--- a/wpa_supplicant/events.c25--- a/wpa_supplicant/events.c
26+++ b/wpa_supplicant/events.c26+++ b/wpa_supplicant/events.c
27@@ -5447,12 +5447,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,27@@ -6590,7 +6590,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
28 data->eapol_rx.data_len);28 data->eapol_rx.encrypted);
29 break;29 break;
30 case EVENT_SIGNAL_CHANGE:30 case EVENT_SIGNAL_CHANGE:
31- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE31- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
32- "above=%d signal=%d noise=%d txrate=%d",
33- data->signal_change.above_threshold,
34- data->signal_change.current_signal,
35- data->signal_change.current_noise,
36- data->signal_change.current_txrate);
37+ wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE32+ wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
38+ "above=%d signal=%d noise=%d txrate=%d",33 "above=%d signal=%d noise=%d txrate=%lu",
39+ data->signal_change.above_threshold,34 data->signal_change.above_threshold,
40+ data->signal_change.current_signal,35 data->signal_change.data.signal,
41+ data->signal_change.current_noise,
42+ data->signal_change.current_txrate);
43 wpa_bss_update_level(wpa_s->current_bss,
44 data->signal_change.current_signal);
45 bgscan_notify_signal_change(
diff --git a/debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch b/debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch
46new file mode 10064436new file mode 100644
index 0000000..688a343
--- /dev/null
+++ b/debian/patches/Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch
@@ -0,0 +1,25 @@
1Description: Bump DEFAULT_BSS_MAX_COUNT to 1000
2 Many congested areas have more than 200 APs in range
3 of a typical device. When the number of APs exceeds
4 BSS_MAX_COUNT, even nearby APs can be absent from
5 the scanning device's AP list.
6 This patch bumps the default to 1000 to be more in
7 line with a realistic modern max number of APs
8 in a given area.
9Author: Mitchell Augustin <mitchell.augustin@canonical.com>
10Bug-Ubuntu: https://bugs.launchpad.net/bugs/2117180
11
12---
13Last-Update: 2025-07-21
14
15--- wpa-2.10.orig/wpa_supplicant/config.h
16+++ wpa-2.10/wpa_supplicant/config.h
17@@ -29,7 +29,7 @@
18 #define DEFAULT_P2P_INTRA_BSS 1
19 #define DEFAULT_P2P_GO_MAX_INACTIVITY (5 * 60)
20 #define DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN 0
21-#define DEFAULT_BSS_MAX_COUNT 200
22+#define DEFAULT_BSS_MAX_COUNT 1000
23 #define DEFAULT_BSS_EXPIRATION_AGE 180
24 #define DEFAULT_BSS_EXPIRATION_SCAN_COUNT 2
25 #define DEFAULT_MAX_NUM_STA 128
diff --git a/debian/patches/CVE-2022-37660.patch b/debian/patches/CVE-2022-37660.patch
0deleted file mode 10064426deleted file mode 100644
index e95c20f..0000000
--- a/debian/patches/CVE-2022-37660.patch
+++ /dev/null
@@ -1,122 +0,0 @@
1[Ubuntu note: hostapd_dpp_pkex_done() in dpp_hostapd.c and
2wpas_dpp_pkex_done() in dpp_supplicant.c were introduced in 2.11
3--Hlib Korzhynskyy]
4
5Backport of:
6
7From 15af83cf1846870873a011ed4d714732f01cd2e4 Mon Sep 17 00:00:00 2001
8From: Jouni Malinen <quic_jouni@quicinc.com>
9Date: Tue, 19 Jul 2022 21:23:04 +0300
10Subject: DPP: Delete PKEX code and identifier on success completion of PKEX
11
12We are not supposed to reuse these without being explicitly requested to
13perform PKEX again. There is not a strong use case for being able to
14provision an Enrollee multiple times with PKEX, so this should have no
15issues on the Enrollee. For a Configurator, there might be some use
16cases that would benefit from being able to use the same code with
17multiple Enrollee devices, e.g., for guess access with a laptop and a
18smart phone. That case will now require a new DPP_PKEX_ADD command on
19the Configurator after each completion of the provisioning exchange.
20
21Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
22---
23 src/ap/dpp_hostapd.c | 22 +++++++++++++++++++++-
24 wpa_supplicant/dpp_supplicant.c | 21 ++++++++++++++++++++-
25 2 files changed, 41 insertions(+), 2 deletions(-)
26
27Index: wpa-2.10/src/ap/dpp_hostapd.c
28===================================================================
29--- wpa-2.10.orig/src/ap/dpp_hostapd.c
30+++ wpa-2.10/src/ap/dpp_hostapd.c
31@@ -216,6 +216,22 @@ static void hostapd_dpp_auth_resp_retry(
32 }
33
34
35+static void hostapd_dpp_pkex_clear_code(struct hostapd_data *hapd)
36+{
37+ if (!hapd->dpp_pkex_code && !hapd->dpp_pkex_identifier)
38+ return;
39+
40+ /* Delete PKEX code and identifier on successful completion of
41+ * PKEX. We are not supposed to reuse these without being
42+ * explicitly requested to perform PKEX again. */
43+ wpa_printf(MSG_DEBUG, "DPP: Delete PKEX code/identifier");
44+ os_free(hapd->dpp_pkex_code);
45+ hapd->dpp_pkex_code = NULL;
46+ os_free(hapd->dpp_pkex_identifier);
47+ hapd->dpp_pkex_identifier = NULL;
48+}
49+
50+
51 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
52 const u8 *data, size_t data_len, int ok)
53 {
54@@ -1842,6 +1858,7 @@ hostapd_dpp_rx_pkex_commit_reveal_req(st
55 wpabuf_head(msg), wpabuf_len(msg));
56 wpabuf_free(msg);
57
58+ hostapd_dpp_pkex_clear_code(hapd);
59 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
60 if (!bi)
61 return;
62@@ -1873,6 +1890,7 @@ hostapd_dpp_rx_pkex_commit_reveal_resp(s
63 return;
64 }
65
66+ hostapd_dpp_pkex_clear_code(hapd);
67 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
68 if (!bi)
69 return;
70@@ -2215,7 +2233,7 @@ int hostapd_dpp_pkex_remove(struct hosta
71 return -1;
72 }
73
74- if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
75+ if ((id_val != 0 && id_val != 1))
76 return -1;
77
78 /* TODO: Support multiple PKEX entries */
79Index: wpa-2.10/wpa_supplicant/dpp_supplicant.c
80===================================================================
81--- wpa-2.10.orig/wpa_supplicant/dpp_supplicant.c
82+++ wpa-2.10/wpa_supplicant/dpp_supplicant.c
83@@ -2557,6 +2557,22 @@ static int wpas_dpp_pkex_next_channel(st
84 }
85
86
87+static void wpas_dpp_pkex_clear_code(struct wpa_supplicant *wpa_s)
88+{
89+ if (!wpa_s->dpp_pkex_code && !wpa_s->dpp_pkex_identifier)
90+ return;
91+
92+ /* Delete PKEX code and identifier on successful completion of
93+ * PKEX. We are not supposed to reuse these without being
94+ * explicitly requested to perform PKEX again. */
95+ os_free(wpa_s->dpp_pkex_code);
96+ wpa_s->dpp_pkex_code = NULL;
97+ os_free(wpa_s->dpp_pkex_identifier);
98+ wpa_s->dpp_pkex_identifier = NULL;
99+
100+}
101+
102+
103 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
104 {
105 struct wpa_supplicant *wpa_s = eloop_ctx;
106@@ -2739,6 +2755,7 @@ wpas_dpp_pkex_finish(struct wpa_supplica
107 {
108 struct dpp_bootstrap_info *bi;
109
110+ wpas_dpp_pkex_clear_code(wpa_s);
111 bi = dpp_pkex_finish(wpa_s->dpp, wpa_s->dpp_pkex, peer, freq);
112 if (!bi)
113 return NULL;
114@@ -3369,7 +3386,7 @@ int wpas_dpp_pkex_remove(struct wpa_supp
115 return -1;
116 }
117
118- if ((id_val != 0 && id_val != 1) || !wpa_s->dpp_pkex_code)
119+ if ((id_val != 0 && id_val != 1))
120 return -1;
121
122 /* TODO: Support multiple PKEX entries */
diff --git a/debian/patches/series b/debian/patches/series
index 4a7edee..96640f3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -7,14 +7,9 @@ systemd-add-reload-support.patch
7manpage-replace-wheel-with-netdev.patch7manpage-replace-wheel-with-netdev.patch
8upstream-fixes/0001-nl80211-add-extra-ies-only-if-allowed-by-driver.patch8upstream-fixes/0001-nl80211-add-extra-ies-only-if-allowed-by-driver.patch
9upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch9upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
10upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch
11allow-legacy-renegotiation.patch10allow-legacy-renegotiation.patch
12wpa_service_netdev.patch11wpa_service_netdev.patch
13upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch
14upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch
15upstream-fixes/0015-Abort-ongoing-scan.patch
16upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch
170017-CVE-2023-52160-PEAP-client-Update-Phase-2-authentica.patch
18CVE-2022-37660.patch
19CVE-2024-5290-lib_engine_trusted_path.patch12CVE-2024-5290-lib_engine_trusted_path.patch
200019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch130019-Send-CTRL-EVENT-SIGNAL-CHANGE-message-to-control-int.patch
14Bump-DEFAULT_BSS_MAX_COUNT-to-1000.patch
150015-Revert-Mark-authorization-completed-on-driver-indica.patch
diff --git a/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch b/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
index 6509bcd..8748cf6 100644
--- a/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
+++ b/debian/patches/upstream-fixes/0002-AP-guard-FT-SAE-code-with-CONFIG_IEEE80211R_AP.patch
@@ -14,11 +14,9 @@ Signed-off-by: Beniamino Galvani <bgalvani@redhat.com>
14 src/ap/wpa_auth_ie.c | 6 ++++++14 src/ap/wpa_auth_ie.c | 6 ++++++
15 1 file changed, 6 insertions(+)15 1 file changed, 6 insertions(+)
1616
17diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c
18index 524922e..d63cbeb 100644
19--- a/src/ap/wpa_auth_ie.c17--- a/src/ap/wpa_auth_ie.c
20+++ b/src/ap/wpa_auth_ie.c18+++ b/src/ap/wpa_auth_ie.c
21@@ -228,11 +228,13 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,19@@ -241,6 +241,7 @@
22 pos += RSN_SELECTOR_LEN;20 pos += RSN_SELECTOR_LEN;
23 num_suites++;21 num_suites++;
24 }22 }
@@ -26,31 +24,37 @@ index 524922e..d63cbeb 100644
26 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {24 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
27 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);25 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
28 pos += RSN_SELECTOR_LEN;26 pos += RSN_SELECTOR_LEN;
27@@ -251,6 +252,7 @@
28 pos += RSN_SELECTOR_LEN;
29 num_suites++;29 num_suites++;
30 }30 }
31+#endif /* CONFIG_IEEE80211R_AP */31+#endif /* CONFIG_IEEE80211R_AP */
32 #endif /* CONFIG_SAE */32 #endif /* CONFIG_SAE */
33 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {33 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
34 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);34 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
35@@ -670,8 +672,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,35@@ -700,10 +702,12 @@
36 #ifdef CONFIG_SAE
37 else if (data.key_mgmt & WPA_KEY_MGMT_SAE)
38 selector = RSN_AUTH_KEY_MGMT_SAE;36 selector = RSN_AUTH_KEY_MGMT_SAE;
37 else if (data.key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY)
38 selector = RSN_AUTH_KEY_MGMT_SAE_EXT_KEY;
39+#ifdef CONFIG_IEEE80211R_AP39+#ifdef CONFIG_IEEE80211R_AP
40 else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)40 else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)
41 selector = RSN_AUTH_KEY_MGMT_FT_SAE;41 selector = RSN_AUTH_KEY_MGMT_FT_SAE;
42 else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY)
43 selector = RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY;
42+#endif /* CONFIG_IEEE80211R_AP */44+#endif /* CONFIG_IEEE80211R_AP */
43 #endif /* CONFIG_SAE */45 #endif /* CONFIG_SAE */
44 else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)46 else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
45 selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;47 selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
46@@ -778,8 +782,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,48@@ -820,10 +824,12 @@
47 #ifdef CONFIG_SAE
48 else if (key_mgmt & WPA_KEY_MGMT_SAE)
49 sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;49 sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
50 else if (key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY)
51 sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
50+#ifdef CONFIG_IEEE80211R_AP52+#ifdef CONFIG_IEEE80211R_AP
51 else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)53 else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)
52 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;54 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;
53+#endif /* CONFIG_IEEE80211R_AP */55 else if (key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY)
56 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE_EXT_KEY;
57+#endif /* CONFIG_IEEE80211R_AP */
54 #endif /* CONFIG_SAE */58 #endif /* CONFIG_SAE */
55 else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)59 else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
56 sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;60 sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
diff --git a/debian/patches/upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch b/debian/patches/upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch
57deleted file mode 10064461deleted file mode 100644
index 18f879c..0000000
--- a/debian/patches/upstream-fixes/0003-OpenSSL-Drop-security-level-to-0-with-OpenSSL-3.0-wh.patch
+++ /dev/null
@@ -1,57 +0,0 @@
1From: Jouni Malinen <j@w1.fi>
2Date: Sun, 22 May 2022 17:01:35 +0300
3Subject: OpenSSL: Drop security level to 0 with OpenSSL 3.0 when using TLS 1.0/1.1
4
5Commit 9afb68b03976 ("OpenSSL: Allow systemwide secpolicy overrides for
6TLS version") with commit 58bbcfa31b18 ("OpenSSL: Update security level
7drop for TLS 1.0/1.1 with OpenSSL 3.0") allow this workaround to be
8enabled with an explicit network configuration parameter. However, the
9default settings are still allowing TLS 1.0 and 1.1 to be negotiated
10just to see them fail immediately when using OpenSSL 3.0. This is not
11exactly helpful especially when the OpenSSL error message for this
12particular case is "internal error" which does not really say anything
13about the reason for the error.
14
15It is is a bit inconvenient to update the security policy for this
16particular issue based on the negotiated TLS version since that happens
17in the middle of processing for the first message from the server.
18However, this can be done by using the debug callback for printing out
19the received TLS messages during processing.
20
21Drop the OpenSSL security level to 0 if that is the only option to
22continue the TLS negotiation, i.e., when TLS 1.0/1.1 are still allowed
23in wpa_supplicant default configuration and OpenSSL 3.0 with the
24constraint on MD5-SHA1 use.
25
26Signed-off-by: Jouni Malinen <j@w1.fi>
27
28Bug-Debian: https://bugs.debian.org/1011121
29Bug-Ubuntu: https://bugs.launchpad.net/bugs/1958267
30Origin: upstream, commit:bc99366f9b960150aa2e369048bbc2218c1d414e
31---
32 src/crypto/tls_openssl.c | 9 +++++++++
33 1 file changed, 9 insertions(+)
34
35diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
36index 6602ac64f591..78621d926dab 100644
37--- a/src/crypto/tls_openssl.c
38+++ b/src/crypto/tls_openssl.c
39@@ -1557,6 +1557,15 @@ static void tls_msg_cb(int write_p, int version, int content_type,
40 struct tls_connection *conn = arg;
41 const u8 *pos = buf;
42
43+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
44+ if ((SSL_version(ssl) == TLS1_VERSION ||
45+ SSL_version(ssl) == TLS1_1_VERSION) &&
46+ SSL_get_security_level(ssl) > 0) {
47+ wpa_printf(MSG_DEBUG,
48+ "OpenSSL: Drop security level to 0 to allow TLS 1.0/1.1 use of MD5-SHA1 signature algorithm");
49+ SSL_set_security_level(ssl, 0);
50+ }
51+#endif /* OpenSSL version >= 3.0 */
52 if (write_p == 2) {
53 wpa_printf(MSG_DEBUG,
54 "OpenSSL: session ver=0x%x content_type=%d",
55--
562.39.0
57
diff --git a/debian/patches/upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch b/debian/patches/upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch
58deleted file mode 1006440deleted file mode 100644
index d36a6e5..0000000
--- a/debian/patches/upstream-fixes/0013-wnm-Choose-best-available-bss-not-just-first-one.patch
+++ /dev/null
@@ -1,117 +0,0 @@
1From: Ben Greear <greearb@candelatech.com>
2Date: Thu, 27 Jul 2023 09:02:11 -0700
3Subject: wnm: Choose best available bss, not just first one.
4
5This should allow STA to make better choice about which
6BSS to roam to.
7
8Use estimated-throughput as comparison value. Can improve
9the est-tput measurement to improve this selection criteria
10if wanted in the future.
11
12Signed-off-by: Ben Greear <greearb@candelatech.com>
13---
14 wpa_supplicant/wnm_sta.c | 55 ++++++++++++++++++++++++++++++------------------
15 1 file changed, 34 insertions(+), 21 deletions(-)
16
17diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
18index 96160dc..36cc8e4 100644
19--- a/wpa_supplicant/wnm_sta.c
20+++ b/wpa_supplicant/wnm_sta.c
21@@ -609,22 +609,6 @@ static void wnm_clear_acceptable(struct wpa_supplicant *wpa_s)
22 wpa_s->wnm_neighbor_report_elements[i].acceptable = 0;
23 }
24
25-
26-static struct wpa_bss * get_first_acceptable(struct wpa_supplicant *wpa_s)
27-{
28- unsigned int i;
29- struct neighbor_report *nei;
30-
31- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
32- nei = &wpa_s->wnm_neighbor_report_elements[i];
33- if (nei->acceptable)
34- return wpa_bss_get_bssid(wpa_s, nei->bssid);
35- }
36-
37- return NULL;
38-}
39-
40-
41 #ifdef CONFIG_MBO
42 static struct wpa_bss *
43 get_mbo_transition_candidate(struct wpa_supplicant *wpa_s,
44@@ -718,6 +702,19 @@ end:
45 }
46 #endif /* CONFIG_MBO */
47
48+struct wpa_bss* find_best_target(struct wpa_bss* a, struct wpa_bss* b)
49+{
50+ if (a->est_throughput > b->est_throughput) {
51+ wpa_printf(MSG_DEBUG, "WNM: A is best: " MACSTR " est-tput: %d B: " MACSTR " est-tput: %d",
52+ MAC2STR(a->bssid), a->est_throughput,
53+ MAC2STR(b->bssid), b->est_throughput);
54+ return a;
55+ }
56+ wpa_printf(MSG_DEBUG, "WNM: B is best, A: " MACSTR " est-tput: %d B: " MACSTR " est-tput: %d",
57+ MAC2STR(a->bssid), a->est_throughput,
58+ MAC2STR(b->bssid), b->est_throughput);
59+ return b;
60+}
61
62 static struct wpa_bss *
63 compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
64@@ -726,6 +723,9 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
65 u8 i;
66 struct wpa_bss *bss = wpa_s->current_bss;
67 struct wpa_bss *target;
68+ struct wpa_bss *best_target = bss;
69+ struct wpa_bss *bss_in_list = NULL;
70+ long diff;
71
72 if (!bss)
73 return NULL;
74@@ -812,25 +812,38 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
75 }
76
77 nei->acceptable = 1;
78+
79+ best_target = find_best_target(target, best_target);
80+ if (target == bss)
81+ bss_in_list = bss;
82 }
83
84 #ifdef CONFIG_MBO
85 if (wpa_s->wnm_mbo_trans_reason_present)
86 target = get_mbo_transition_candidate(wpa_s, reason);
87 else
88- target = get_first_acceptable(wpa_s);
89+ target = best_target;
90 #else /* CONFIG_MBO */
91- target = get_first_acceptable(wpa_s);
92+ target = best_target;
93 #endif /* CONFIG_MBO */
94
95 if (target) {
96 wpa_printf(MSG_DEBUG,
97 "WNM: Found an acceptable preferred transition candidate BSS "
98- MACSTR " (RSSI %d)",
99- MAC2STR(target->bssid), target->level);
100+ MACSTR " (RSSI %d, tput: %d bss-tput: %d)",
101+ MAC2STR(target->bssid), target->level, target->est_throughput,
102+ bss->est_throughput);
103 }
104
105- return target;
106+ if (!bss_in_list)
107+ return target;
108+
109+ diff = target->est_throughput - bss_in_list->est_throughput;
110+ if (diff > bss_in_list->est_throughput >> 4) {
111+ /* It is more than 100/16 percent better, so switch. */
112+ return target;
113+ }
114+ return bss_in_list; /* stay with our existing bss, not enough change in est rate to switch. */
115 }
116
117
diff --git a/debian/patches/upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch b/debian/patches/upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch
118deleted file mode 1006440deleted file mode 100644
index 841d0d8..0000000
--- a/debian/patches/upstream-fixes/0014-wpa_supplicant-Fix-wpa_supplicant-configuration-pars.patch
+++ /dev/null
@@ -1,28 +0,0 @@
1From: Michael Lee <michael-cy.lee@mediatek.com>
2Date: Thu, 27 Jul 2023 16:29:22 +0800
3Subject: wpa_supplicant: Fix wpa_supplicant configuration parsing error
4
5In the original flow, after hostapd_config_tx_queue successfully
6parses a tx_queue variable, it would not return immediately. Then it
7would print out "unknow global field" later and set return val to -1.
8
9This patch returns immediately after hostapd_config_tx_queue
10successfully parses a tx_queue variable.
11
12Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
13---
14 wpa_supplicant/config.c | 1 +
15 1 file changed, 1 insertion(+)
16
17diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
18index bf062b0..de08fff 100644
19--- a/wpa_supplicant/config.c
20+++ b/wpa_supplicant/config.c
21@@ -5397,6 +5397,7 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
22 line);
23 return -1;
24 }
25+ return ret;
26 }
27
28 if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
diff --git a/debian/patches/upstream-fixes/0015-Abort-ongoing-scan.patch b/debian/patches/upstream-fixes/0015-Abort-ongoing-scan.patch
29deleted file mode 1006440deleted file mode 100644
index 671af84..0000000
--- a/debian/patches/upstream-fixes/0015-Abort-ongoing-scan.patch
+++ /dev/null
@@ -1,25 +0,0 @@
1From: Chaitanya Tata <chaitanya.mgit@gmail.com>
2Date: Tue, 18 Jul 2023 01:21:37 +0530
3Subject: Abort ongoing scan
4
5Along with canceling queued scan, abort ongoing scan if any, this
6ensures Wi-Fi interface is in usable state after disconnect is issued,
7else subsequent scan after disconnect might fail with EBUSY.
8
9Signed-off-by: Chaitanya Tata <Chaitanya.Tata@nordicsemi.no>
10---
11 wpa_supplicant/wpa_supplicant.c | 1 +
12 1 file changed, 1 insertion(+)
13
14diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
15index d37a994..917aca4 100644
16--- a/wpa_supplicant/wpa_supplicant.c
17+++ b/wpa_supplicant/wpa_supplicant.c
18@@ -8181,6 +8181,7 @@ void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
19 wpa_s->disconnected = 1;
20 wpa_supplicant_cancel_sched_scan(wpa_s);
21 wpa_supplicant_cancel_scan(wpa_s);
22+ wpas_abort_ongoing_scan(wpa_s);
23 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
24 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
25 radio_remove_works(wpa_s, "connect", 0);
diff --git a/debian/patches/upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch b/debian/patches/upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch
26deleted file mode 1006440deleted file mode 100644
index 2b432d6..0000000
--- a/debian/patches/upstream-fixes/0016-Override-ieee80211w-from-pmf-for-AP-mode-in-wpa_supp.patch
+++ /dev/null
@@ -1,36 +0,0 @@
1From 5f3cdc06489ff1ec16d75c3ff41f5ac7c2f62c7c Mon Sep 17 00:00:00 2001
2From: Chaoli Zhou <quic_zchaoli@quicinc.com>
3Date: Thu, 8 Sep 2022 17:43:32 +0800
4Subject: [PATCH] Override ieee80211w from pmf for AP mode in wpa_supplicant
5
6Since NetworkManager doesn't support setting ieee80211w to
7wpa_supplicant and only support pmf, so override ieee80211w from pmf for
8AP mode if ieee80211w not configurated. Do not change behavior for the
9P2P GO cases.
10
11Signed-off-by: Chaoli Zhou <quic_zchaoli@quicinc.com>
12---
13 wpa_supplicant/ap.c | 6 +++++-
14 1 file changed, 5 insertions(+), 1 deletion(-)
15
16diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
17index 67f2d8ac1..653f15f54 100644
18--- a/wpa_supplicant/ap.c
19+++ b/wpa_supplicant/ap.c
20@@ -701,8 +701,12 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
21 bss->wpa_group_rekey = 86400;
22 }
23
24- if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
25+ if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT) {
26 bss->ieee80211w = ssid->ieee80211w;
27+ } else if (wpa_s->conf->pmf != MGMT_FRAME_PROTECTION_DEFAULT) {
28+ if (ssid->mode == WPAS_MODE_AP)
29+ bss->ieee80211w = wpa_s->conf->pmf;
30+ }
31
32 #ifdef CONFIG_OCV
33 bss->ocv = ssid->ocv;
34--
352.42.0
36
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index bf26e41..573564d 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -154,6 +154,7 @@ OBJS += src/utils/crc32.c
154OBJS += src/common/ieee802_11_common.c154OBJS += src/common/ieee802_11_common.c
155OBJS += src/common/wpa_common.c155OBJS += src/common/wpa_common.c
156OBJS += src/common/hw_features_common.c156OBJS += src/common/hw_features_common.c
157OBJS += src/common/ptksa_cache.c
157158
158OBJS += src/eapol_auth/eapol_auth_sm.c159OBJS += src/eapol_auth/eapol_auth_sm.c
159160
@@ -237,6 +238,8 @@ L_CFLAGS += -DCONFIG_OCV
237OBJS += src/common/ocv.c238OBJS += src/common/ocv.c
238endif239endif
239240
241NEED_AES_UNWRAP=y
242
240ifdef CONFIG_IEEE80211R243ifdef CONFIG_IEEE80211R
241L_CFLAGS += -DCONFIG_IEEE80211R -DCONFIG_IEEE80211R_AP244L_CFLAGS += -DCONFIG_IEEE80211R -DCONFIG_IEEE80211R_AP
242OBJS += src/ap/wpa_auth_ft.c245OBJS += src/ap/wpa_auth_ft.c
@@ -256,6 +259,7 @@ L_CFLAGS += -DCONFIG_SAE
256OBJS += src/common/sae.c259OBJS += src/common/sae.c
257ifdef CONFIG_SAE_PK260ifdef CONFIG_SAE_PK
258L_CFLAGS += -DCONFIG_SAE_PK261L_CFLAGS += -DCONFIG_SAE_PK
262NEED_AES_SIV=y
259OBJS += src/common/sae_pk.c263OBJS += src/common/sae_pk.c
260endif264endif
261NEED_ECC=y265NEED_ECC=y
@@ -294,6 +298,12 @@ ifdef CONFIG_IEEE80211AC
294L_CFLAGS += -DCONFIG_IEEE80211AC298L_CFLAGS += -DCONFIG_IEEE80211AC
295endif299endif
296300
301ifdef CONFIG_IEEE80211BE
302CONFIG_IEEE80211AX=y
303L_CFLAGS += -DCONFIG_IEEE80211BE
304OBJS += src/ap/ieee802_11_eht.c
305endif
306
297ifdef CONFIG_IEEE80211AX307ifdef CONFIG_IEEE80211AX
298L_CFLAGS += -DCONFIG_IEEE80211AX308L_CFLAGS += -DCONFIG_IEEE80211AX
299endif309endif
@@ -572,6 +582,12 @@ L_CFLAGS += -DCONFIG_DPP3
572endif582endif
573endif583endif
574584
585ifdef CONFIG_NAN_USD
586OBJS += src/common/nan_de.c
587OBJS += src/ap/nan_usd_ap.c
588L_CFLAGS += -DCONFIG_NAN_USD
589endif
590
575ifdef CONFIG_PASN591ifdef CONFIG_PASN
576L_CFLAGS += -DCONFIG_PASN592L_CFLAGS += -DCONFIG_PASN
577L_CFLAGS += -DCONFIG_PTKSA_CACHE593L_CFLAGS += -DCONFIG_PTKSA_CACHE
@@ -579,7 +595,6 @@ NEED_HMAC_SHA256_KDF=y
579NEED_HMAC_SHA384_KDF=y595NEED_HMAC_SHA384_KDF=y
580NEED_SHA256=y596NEED_SHA256=y
581NEED_SHA384=y597NEED_SHA384=y
582OBJS += src/common/ptksa_cache.c
583endif598endif
584599
585ifdef CONFIG_EAP_IKEV2600ifdef CONFIG_EAP_IKEV2
@@ -632,6 +647,11 @@ ifdef CHAP
632OBJS += src/eap_common/chap.c647OBJS += src/eap_common/chap.c
633endif648endif
634649
650ifdef CONFIG_RADIUS_TLS
651TLS_FUNCS=y
652L_CFLAGS += -DCONFIG_RADIUS_TLS
653endif
654
635ifdef TLS_FUNCS655ifdef TLS_FUNCS
636NEED_DES=y656NEED_DES=y
637# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)657# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
@@ -653,6 +673,7 @@ L_CFLAGS += -DCONFIG_TLSV12
653endif673endif
654674
655ifeq ($(CONFIG_TLS), openssl)675ifeq ($(CONFIG_TLS), openssl)
676L_CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
656ifdef TLS_FUNCS677ifdef TLS_FUNCS
657OBJS += src/crypto/tls_openssl.c678OBJS += src/crypto/tls_openssl.c
658OBJS += src/crypto/tls_openssl_ocsp.c679OBJS += src/crypto/tls_openssl_ocsp.c
@@ -825,7 +846,9 @@ endif
825ifdef NEED_AES_ENCBLOCK846ifdef NEED_AES_ENCBLOCK
826AESOBJS += src/crypto/aes-encblock.c847AESOBJS += src/crypto/aes-encblock.c
827endif848endif
849ifneq ($(CONFIG_TLS), openssl)
828AESOBJS += src/crypto/aes-omac1.c850AESOBJS += src/crypto/aes-omac1.c
851endif
829ifdef NEED_AES_UNWRAP852ifdef NEED_AES_UNWRAP
830ifneq ($(CONFIG_TLS), openssl)853ifneq ($(CONFIG_TLS), openssl)
831NEED_AES_DEC=y854NEED_AES_DEC=y
@@ -1026,6 +1049,9 @@ endif
1026ifdef NEED_AP_MLME1049ifdef NEED_AP_MLME
1027OBJS += src/ap/wmm.c1050OBJS += src/ap/wmm.c
1028OBJS += src/ap/ap_list.c1051OBJS += src/ap/ap_list.c
1052OBJS += src/ap/comeback_token.c
1053OBJS += src/pasn/pasn_responder.c
1054OBJS += src/pasn/pasn_common.c
1029OBJS += src/ap/ieee802_11.c1055OBJS += src/ap/ieee802_11.c
1030OBJS += src/ap/hw_features.c1056OBJS += src/ap/hw_features.c
1031OBJS += src/ap/dfs.c1057OBJS += src/ap/dfs.c
diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog
index 279298e..1c8240d 100644
--- a/hostapd/ChangeLog
+++ b/hostapd/ChangeLog
@@ -1,5 +1,42 @@
1ChangeLog for hostapd1ChangeLog for hostapd
22
32024-07-20 - v2.11
4 * Wi-Fi Easy Connect
5 - add support for DPP release 3
6 - allow Configurator parameters to be provided during config exchange
7 * HE/IEEE 802.11ax/Wi-Fi 6
8 - various fixes
9 * EHT/IEEE 802.11be/Wi-Fi 7
10 - add preliminary support
11 * SAE: add support for fetching the password from a RADIUS server
12 * support OpenSSL 3.0 API changes
13 * support background radar detection and CAC with some additional
14 drivers
15 * support RADIUS ACL/PSK check during 4-way handshake (wpa_psk_radius=3)
16 * EAP-SIM/AKA: support IMSI privacy
17 * improve 4-way handshake operations
18 - use Secure=1 in message 3 during PTK rekeying
19 * OCV: do not check Frequency Segment 1 Channel Number for 160 MHz cases
20 to avoid interoperability issues
21 * support new SAE AKM suites with variable length keys
22 * support new AKM for 802.1X/EAP with SHA384
23 * extend PASN support for secure ranging
24 * FT: Use SHA256 to derive PMKID for AKM 00-0F-AC:3 (FT-EAP)
25 - this is based on additional details being added in the IEEE 802.11
26 standard
27 - the new implementation is not backwards compatible
28 * improved ACS to cover additional channel types/bandwidths
29 * extended Multiple BSSID support
30 * fix beacon protection with FT protocol (incorrect BIGTK was provided)
31 * support unsynchronized service discovery (USD)
32 * add preliminary support for RADIUS/TLS
33 * add support for explicit SSID protection in 4-way handshake
34 (a mitigation for CVE-2023-52424; disabled by default for now, can be
35 enabled with ssid_protection=1)
36 * fix SAE H2E rejected groups validation to avoid downgrade attacks
37 * use stricter validation for some RADIUS messages
38 * a large number of other fixes, cleanup, and extensions
39
32022-01-16 - v2.10402022-01-16 - v2.10
4 * SAE changes41 * SAE changes
5 - improved protection against side channel attacks42 - improved protection against side channel attacks
diff --git a/hostapd/Makefile b/hostapd/Makefile
index e37c13b..ca44392 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -84,6 +84,7 @@ OBJS += ../src/ap/beacon.o
84OBJS += ../src/ap/bss_load.o84OBJS += ../src/ap/bss_load.o
85OBJS += ../src/ap/neighbor_db.o85OBJS += ../src/ap/neighbor_db.o
86OBJS += ../src/ap/rrm.o86OBJS += ../src/ap/rrm.o
87OBJS += ../src/common/ptksa_cache.o
8788
88OBJS_c = hostapd_cli.o89OBJS_c = hostapd_cli.o
89OBJS_c += ../src/common/wpa_ctrl.o90OBJS_c += ../src/common/wpa_ctrl.o
@@ -167,7 +168,7 @@ OBJS += ../src/eapol_auth/eapol_auth_sm.o
167168
168169
169ifdef CONFIG_CODE_COVERAGE170ifdef CONFIG_CODE_COVERAGE
170CFLAGS += -O0 -fprofile-arcs -ftest-coverage171CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE
171LIBS += -lgcov172LIBS += -lgcov
172LIBS_c += -lgcov173LIBS_c += -lgcov
173LIBS_h += -lgcov174LIBS_h += -lgcov
@@ -276,6 +277,8 @@ CFLAGS += -DCONFIG_OCV
276OBJS += ../src/common/ocv.o277OBJS += ../src/common/ocv.o
277endif278endif
278279
280NEED_AES_UNWRAP=y
281
279ifdef CONFIG_IEEE80211R282ifdef CONFIG_IEEE80211R
280CFLAGS += -DCONFIG_IEEE80211R -DCONFIG_IEEE80211R_AP283CFLAGS += -DCONFIG_IEEE80211R -DCONFIG_IEEE80211R_AP
281OBJS += ../src/ap/wpa_auth_ft.o284OBJS += ../src/ap/wpa_auth_ft.o
@@ -295,6 +298,7 @@ CFLAGS += -DCONFIG_SAE
295OBJS += ../src/common/sae.o298OBJS += ../src/common/sae.o
296ifdef CONFIG_SAE_PK299ifdef CONFIG_SAE_PK
297CFLAGS += -DCONFIG_SAE_PK300CFLAGS += -DCONFIG_SAE_PK
301NEED_AES_SIV=y
298OBJS += ../src/common/sae_pk.o302OBJS += ../src/common/sae_pk.o
299endif303endif
300NEED_ECC=y304NEED_ECC=y
@@ -339,6 +343,12 @@ ifdef CONFIG_IEEE80211AC
339CFLAGS += -DCONFIG_IEEE80211AC343CFLAGS += -DCONFIG_IEEE80211AC
340endif344endif
341345
346ifdef CONFIG_IEEE80211BE
347CONFIG_IEEE80211AX=y
348CFLAGS += -DCONFIG_IEEE80211BE
349OBJS += ../src/ap/ieee802_11_eht.o
350endif
351
342ifdef CONFIG_IEEE80211AX352ifdef CONFIG_IEEE80211AX
343CFLAGS += -DCONFIG_IEEE80211AX353CFLAGS += -DCONFIG_IEEE80211AX
344OBJS += ../src/ap/ieee802_11_he.o354OBJS += ../src/ap/ieee802_11_he.o
@@ -598,6 +608,12 @@ CFLAGS += -DCONFIG_DPP3
598endif608endif
599endif609endif
600610
611ifdef CONFIG_NAN_USD
612OBJS += ../src/common/nan_de.o
613OBJS += ../src/ap/nan_usd_ap.o
614CFLAGS += -DCONFIG_NAN_USD
615endif
616
601ifdef CONFIG_PASN617ifdef CONFIG_PASN
602CFLAGS += -DCONFIG_PASN618CFLAGS += -DCONFIG_PASN
603CFLAGS += -DCONFIG_PTKSA_CACHE619CFLAGS += -DCONFIG_PTKSA_CACHE
@@ -605,7 +621,6 @@ NEED_HMAC_SHA256_KDF=y
605NEED_HMAC_SHA384_KDF=y621NEED_HMAC_SHA384_KDF=y
606NEED_SHA256=y622NEED_SHA256=y
607NEED_SHA384=y623NEED_SHA384=y
608OBJS += ../src/common/ptksa_cache.o
609endif624endif
610625
611ifdef CONFIG_EAP_IKEV2626ifdef CONFIG_EAP_IKEV2
@@ -667,6 +682,11 @@ ifdef CHAP
667OBJS += ../src/eap_common/chap.o682OBJS += ../src/eap_common/chap.o
668endif683endif
669684
685ifdef CONFIG_RADIUS_TLS
686TLS_FUNCS=y
687CFLAGS += -DCONFIG_RADIUS_TLS
688endif
689
670ifdef TLS_FUNCS690ifdef TLS_FUNCS
671NEED_DES=y691NEED_DES=y
672# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)692# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
@@ -708,6 +728,7 @@ endif
708endif728endif
709729
710ifeq ($(CONFIG_TLS), openssl)730ifeq ($(CONFIG_TLS), openssl)
731CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
711CONFIG_CRYPTO=openssl732CONFIG_CRYPTO=openssl
712ifdef TLS_FUNCS733ifdef TLS_FUNCS
713OBJS += ../src/crypto/tls_openssl.o734OBJS += ../src/crypto/tls_openssl.o
@@ -932,11 +953,13 @@ endif
932ifdef NEED_AES_ENCBLOCK953ifdef NEED_AES_ENCBLOCK
933AESOBJS += ../src/crypto/aes-encblock.o954AESOBJS += ../src/crypto/aes-encblock.o
934endif955endif
956ifneq ($(CONFIG_TLS), openssl)
935ifneq ($(CONFIG_TLS), linux)957ifneq ($(CONFIG_TLS), linux)
936ifneq ($(CONFIG_TLS), wolfssl)958ifneq ($(CONFIG_TLS), wolfssl)
937AESOBJS += ../src/crypto/aes-omac1.o959AESOBJS += ../src/crypto/aes-omac1.o
938endif960endif
939endif961endif
962endif
940ifdef NEED_AES_UNWRAP963ifdef NEED_AES_UNWRAP
941ifneq ($(CONFIG_TLS), openssl)964ifneq ($(CONFIG_TLS), openssl)
942ifneq ($(CONFIG_TLS), linux)965ifneq ($(CONFIG_TLS), linux)
@@ -1172,6 +1195,9 @@ endif
1172ifdef NEED_AP_MLME1195ifdef NEED_AP_MLME
1173OBJS += ../src/ap/wmm.o1196OBJS += ../src/ap/wmm.o
1174OBJS += ../src/ap/ap_list.o1197OBJS += ../src/ap/ap_list.o
1198OBJS += ../src/ap/comeback_token.o
1199OBJS += ../src/pasn/pasn_responder.o
1200OBJS += ../src/pasn/pasn_common.o
1175OBJS += ../src/ap/ieee802_11.o1201OBJS += ../src/ap/ieee802_11.o
1176OBJS += ../src/ap/hw_features.o1202OBJS += ../src/ap/hw_features.o
1177OBJS += ../src/ap/dfs.o1203OBJS += ../src/ap/dfs.o
diff --git a/hostapd/README b/hostapd/README
index 739c964..1a0248f 100644
--- a/hostapd/README
+++ b/hostapd/README
@@ -2,7 +2,7 @@ hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
2 Authenticator and RADIUS authentication server2 Authenticator and RADIUS authentication server
3================================================================3================================================================
44
5Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors5Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> and contributors
6All Rights Reserved.6All Rights Reserved.
77
8This program is licensed under the BSD license (the one with8This program is licensed under the BSD license (the one with
diff --git a/hostapd/android.config b/hostapd/android.config
index c8b3afa..522de87 100644
--- a/hostapd/android.config
+++ b/hostapd/android.config
@@ -121,6 +121,9 @@ CONFIG_PKCS12=y
121# Build IPv6 support for RADIUS operations121# Build IPv6 support for RADIUS operations
122CONFIG_IPV6=y122CONFIG_IPV6=y
123123
124# Include support fo RADIUS/TLS into the RADIUS client
125#CONFIG_RADIUS_TLS=y
126
124# IEEE Std 802.11r-2008 (Fast BSS Transition)127# IEEE Std 802.11r-2008 (Fast BSS Transition)
125#CONFIG_IEEE80211R=y128#CONFIG_IEEE80211R=y
126129
@@ -212,3 +215,6 @@ CONFIG_NO_RANDOM_POOL=y
212# release under this optional build parameter. This functionality is subject to215# release under this optional build parameter. This functionality is subject to
213# be completely removed in a future release.216# be completely removed in a future release.
214CONFIG_WEP=y217CONFIG_WEP=y
218
219# Wi-Fi Aware unsynchronized service discovery (NAN USD)
220#CONFIG_NAN_USD=y
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index b14728d..3fb0597 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -1,6 +1,6 @@
1/*1/*
2 * hostapd / Configuration file parser2 * hostapd / Configuration file parser
3 * Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi>3 * Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
4 *4 *
5 * This software may be distributed under the terms of the BSD license.5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.6 * See README for more details.
@@ -118,52 +118,6 @@ static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
118#endif /* CONFIG_NO_VLAN */118#endif /* CONFIG_NO_VLAN */
119119
120120
121int hostapd_acl_comp(const void *a, const void *b)
122{
123 const struct mac_acl_entry *aa = a;
124 const struct mac_acl_entry *bb = b;
125 return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
126}
127
128
129int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num,
130 int vlan_id, const u8 *addr)
131{
132 struct mac_acl_entry *newacl;
133
134 newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl));
135 if (!newacl) {
136 wpa_printf(MSG_ERROR, "MAC list reallocation failed");
137 return -1;
138 }
139
140 *acl = newacl;
141 os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
142 os_memset(&(*acl)[*num].vlan_id, 0, sizeof((*acl)[*num].vlan_id));
143 (*acl)[*num].vlan_id.untagged = vlan_id;
144 (*acl)[*num].vlan_id.notempty = !!vlan_id;
145 (*num)++;
146
147 return 0;
148}
149
150
151void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num,
152 const u8 *addr)
153{
154 int i = 0;
155
156 while (i < *num) {
157 if (os_memcmp((*acl)[i].addr, addr, ETH_ALEN) == 0) {
158 os_remove_in_array(*acl, *num, sizeof(**acl), i);
159 (*num)--;
160 } else {
161 i++;
162 }
163 }
164}
165
166
167static int hostapd_config_read_maclist(const char *fname,121static int hostapd_config_read_maclist(const char *fname,
168 struct mac_acl_entry **acl, int *num)122 struct mac_acl_entry **acl, int *num)
169{123{
@@ -713,6 +667,10 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
713 val |= WPA_KEY_MGMT_FT_IEEE8021X_SHA384;667 val |= WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
714#endif /* CONFIG_SHA384 */668#endif /* CONFIG_SHA384 */
715#endif /* CONFIG_IEEE80211R_AP */669#endif /* CONFIG_IEEE80211R_AP */
670#ifdef CONFIG_SHA384
671 else if (os_strcmp(start, "WPA-EAP-SHA384") == 0)
672 val |= WPA_KEY_MGMT_IEEE8021X_SHA384;
673#endif /* CONFIG_SHA384 */
716 else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)674 else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
717 val |= WPA_KEY_MGMT_PSK_SHA256;675 val |= WPA_KEY_MGMT_PSK_SHA256;
718 else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)676 else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
@@ -720,8 +678,12 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
720#ifdef CONFIG_SAE678#ifdef CONFIG_SAE
721 else if (os_strcmp(start, "SAE") == 0)679 else if (os_strcmp(start, "SAE") == 0)
722 val |= WPA_KEY_MGMT_SAE;680 val |= WPA_KEY_MGMT_SAE;
681 else if (os_strcmp(start, "SAE-EXT-KEY") == 0)
682 val |= WPA_KEY_MGMT_SAE_EXT_KEY;
723 else if (os_strcmp(start, "FT-SAE") == 0)683 else if (os_strcmp(start, "FT-SAE") == 0)
724 val |= WPA_KEY_MGMT_FT_SAE;684 val |= WPA_KEY_MGMT_FT_SAE;
685 else if (os_strcmp(start, "FT-SAE-EXT-KEY") == 0)
686 val |= WPA_KEY_MGMT_FT_SAE_EXT_KEY;
725#endif /* CONFIG_SAE */687#endif /* CONFIG_SAE */
726#ifdef CONFIG_SUITEB688#ifdef CONFIG_SUITEB
727 else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)689 else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
@@ -1058,6 +1020,78 @@ static int add_r1kh(struct hostapd_bss_config *bss, char *value)
10581020
1059 return 0;1021 return 0;
1060}1022}
1023
1024
1025int hostapd_config_read_rxkh_file(struct hostapd_bss_config *conf,
1026 const char *fname)
1027{
1028 FILE *f;
1029 char buf[256], *pos;
1030 int line = 0, errors = 0;
1031
1032 if (!fname)
1033 return 0;
1034
1035 f = fopen(fname, "r");
1036 if (!f) {
1037 wpa_printf(MSG_ERROR, "rxkh file '%s' not found.", fname);
1038 return -1;
1039 }
1040
1041 while (fgets(buf, sizeof(buf), f)) {
1042 line++;
1043
1044 if (buf[0] == '#')
1045 continue;
1046 pos = buf;
1047 while (*pos != '\0') {
1048 if (*pos == '\n') {
1049 *pos = '\0';
1050 break;
1051 }
1052 pos++;
1053 }
1054 if (buf[0] == '\0')
1055 continue;
1056
1057 pos = os_strchr(buf, '=');
1058 if (!pos) {
1059 wpa_printf(MSG_ERROR, "Line %d: Invalid line '%s'",
1060 line, buf);
1061 errors++;
1062 continue;
1063 }
1064 *pos = '\0';
1065 pos++;
1066
1067 if (os_strcmp(buf, "r0kh") == 0) {
1068 if (add_r0kh(conf, pos) < 0) {
1069 wpa_printf(MSG_ERROR,
1070 "Line %d: Invalid r0kh '%s'",
1071 line, pos);
1072 errors++;
1073 }
1074 } else if (os_strcmp(buf, "r1kh") == 0) {
1075 if (add_r1kh(conf, pos) < 0) {
1076 wpa_printf(MSG_ERROR,
1077 "Line %d: Invalid r1kh '%s'",
1078 line, pos);
1079 errors++;
1080 }
1081 }
1082 }
1083
1084 fclose(f);
1085
1086 if (errors) {
1087 wpa_printf(MSG_ERROR,
1088 "%d errors in configuring RxKHs from '%s'",
1089 errors, fname);
1090 return -1;
1091 }
1092 return 0;
1093}
1094
1061#endif /* CONFIG_IEEE80211R_AP */1095#endif /* CONFIG_IEEE80211R_AP */
10621096
10631097
@@ -1644,6 +1678,8 @@ static int parse_anqp_elem(struct hostapd_bss_config *bss, char *buf, int line)
1644 return 0;1678 return 0;
1645}1679}
16461680
1681#endif /* CONFIG_INTERWORKING */
1682
16471683
1648static int parse_qos_map_set(struct hostapd_bss_config *bss,1684static int parse_qos_map_set(struct hostapd_bss_config *bss,
1649 char *buf, int line)1685 char *buf, int line)
@@ -1685,8 +1721,6 @@ static int parse_qos_map_set(struct hostapd_bss_config *bss,
1685 return 0;1721 return 0;
1686}1722}
16871723
1688#endif /* CONFIG_INTERWORKING */
1689
16901724
1691#ifdef CONFIG_HS201725#ifdef CONFIG_HS20
1692static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,1726static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
@@ -2197,6 +2231,7 @@ static int add_airtime_weight(struct hostapd_bss_config *bss, char *value)
21972231
21982232
2199#ifdef CONFIG_SAE2233#ifdef CONFIG_SAE
2234
2200static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)2235static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
2201{2236{
2202 struct sae_password_entry *pw;2237 struct sae_password_entry *pw;
@@ -2300,6 +2335,40 @@ fail:
2300 os_free(pw);2335 os_free(pw);
2301 return -1;2336 return -1;
2302}2337}
2338
2339
2340static int parse_sae_password_file(struct hostapd_bss_config *bss,
2341 const char *fname)
2342{
2343 FILE *f;
2344 char buf[500], *pos;
2345 unsigned int line = 0;
2346
2347 f = fopen(fname, "r");
2348 if (!f) {
2349 wpa_printf(MSG_ERROR, "sae_password_file '%s' not found.",
2350 fname);
2351 return -1;
2352 }
2353
2354 while (fgets(buf, sizeof(buf), f)) {
2355 pos = os_strchr(buf, '\n');
2356 if (pos)
2357 *pos = '\0';
2358 line++;
2359 if (parse_sae_password(bss, buf)) {
2360 wpa_printf(MSG_ERROR,
2361 "Invalid SAE password at line %d in '%s'",
2362 line, fname);
2363 fclose(f);
2364 return -1;
2365 }
2366 }
2367
2368 fclose(f);
2369 return 0;
2370}
2371
2303#endif /* CONFIG_SAE */2372#endif /* CONFIG_SAE */
23042373
23052374
@@ -2349,6 +2418,24 @@ static int get_hex_config(u8 *buf, size_t max_len, int line,
2349}2418}
23502419
23512420
2421#ifdef CONFIG_IEEE80211BE
2422static int get_u16(const char *pos, int line, u16 *ret_val)
2423{
2424 char *end;
2425 long int val = strtol(pos, &end, 0);
2426
2427 if (*end || val < 0 || val > 0xffff) {
2428 wpa_printf(MSG_ERROR, "Line %d: Invalid value '%s'",
2429 line, pos);
2430 return -1;
2431 }
2432
2433 *ret_val = val;
2434 return 0;
2435}
2436#endif /* CONFIG_IEEE80211BE */
2437
2438
2352static int hostapd_config_fill(struct hostapd_config *conf,2439static int hostapd_config_fill(struct hostapd_config *conf,
2353 struct hostapd_bss_config *bss,2440 struct hostapd_bss_config *bss,
2354 const char *buf, char *pos, int line)2441 const char *buf, char *pos, int line)
@@ -2358,6 +2445,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2358 sizeof(conf->bss[0]->iface));2445 sizeof(conf->bss[0]->iface));
2359 } else if (os_strcmp(buf, "bridge") == 0) {2446 } else if (os_strcmp(buf, "bridge") == 0) {
2360 os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));2447 os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
2448 } else if (os_strcmp(buf, "bridge_hairpin") == 0) {
2449 bss->bridge_hairpin = atoi(pos);
2361 } else if (os_strcmp(buf, "vlan_bridge") == 0) {2450 } else if (os_strcmp(buf, "vlan_bridge") == 0) {
2362 os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));2451 os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
2363 } else if (os_strcmp(buf, "wds_bridge") == 0) {2452 } else if (os_strcmp(buf, "wds_bridge") == 0) {
@@ -2407,7 +2496,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2407 }2496 }
2408 os_memcpy(ssid->ssid, pos, ssid->ssid_len);2497 os_memcpy(ssid->ssid, pos, ssid->ssid_len);
2409 ssid->ssid_set = 1;2498 ssid->ssid_set = 1;
2410 ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);2499 ssid->short_ssid = ieee80211_crc32(ssid->ssid, ssid->ssid_len);
2411 } else if (os_strcmp(buf, "ssid2") == 0) {2500 } else if (os_strcmp(buf, "ssid2") == 0) {
2412 struct hostapd_ssid *ssid = &bss->ssid;2501 struct hostapd_ssid *ssid = &bss->ssid;
2413 size_t slen;2502 size_t slen;
@@ -2421,7 +2510,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2421 os_memcpy(ssid->ssid, str, slen);2510 os_memcpy(ssid->ssid, str, slen);
2422 ssid->ssid_len = slen;2511 ssid->ssid_len = slen;
2423 ssid->ssid_set = 1;2512 ssid->ssid_set = 1;
2424 ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);2513 ssid->short_ssid = ieee80211_crc32(ssid->ssid, ssid->ssid_len);
2425 os_free(str);2514 os_free(str);
2426 } else if (os_strcmp(buf, "utf8_ssid") == 0) {2515 } else if (os_strcmp(buf, "utf8_ssid") == 0) {
2427 bss->ssid.utf8_ssid = atoi(pos) > 0;2516 bss->ssid.utf8_ssid = atoi(pos) > 0;
@@ -2460,6 +2549,30 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2460 bss->ap_max_inactivity = atoi(pos);2549 bss->ap_max_inactivity = atoi(pos);
2461 } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {2550 } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
2462 bss->skip_inactivity_poll = atoi(pos);2551 bss->skip_inactivity_poll = atoi(pos);
2552 } else if (os_strcmp(buf, "bss_max_idle") == 0) {
2553 int val = atoi(pos);
2554
2555 if (val < 0 || val > 2) {
2556 wpa_printf(MSG_ERROR,
2557 "Line %d: Invalid bss_max_idle value", line);
2558 return 1;
2559 }
2560 bss->bss_max_idle = val;
2561 } else if (os_strcmp(buf, "max_acceptable_idle_period") == 0) {
2562 bss->max_acceptable_idle_period = atoi(pos);
2563 } else if (os_strcmp(buf, "no_disconnect_on_group_keyerror") == 0) {
2564 int val = atoi(pos);
2565
2566 if (val < 0 || val > 1) {
2567 wpa_printf(MSG_ERROR,
2568 "Line %d: Invalid no_disconnect_on_group_keyerror",
2569 line);
2570 return 1;
2571 }
2572 bss->no_disconnect_on_group_keyerror = val;
2573 } else if (os_strcmp(buf, "config_id") == 0) {
2574 os_free(bss->config_id);
2575 bss->config_id = os_strdup(pos);
2463 } else if (os_strcmp(buf, "country_code") == 0) {2576 } else if (os_strcmp(buf, "country_code") == 0) {
2464 if (pos[0] < 'A' || pos[0] > 'Z' ||2577 if (pos[0] < 'A' || pos[0] > 'Z' ||
2465 pos[1] < 'A' || pos[1] > 'Z') {2578 pos[1] < 'A' || pos[1] > 'Z') {
@@ -2624,6 +2737,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2624 bss->eap_teap_separate_result = atoi(pos);2737 bss->eap_teap_separate_result = atoi(pos);
2625 } else if (os_strcmp(buf, "eap_teap_id") == 0) {2738 } else if (os_strcmp(buf, "eap_teap_id") == 0) {
2626 bss->eap_teap_id = atoi(pos);2739 bss->eap_teap_id = atoi(pos);
2740 } else if (os_strcmp(buf, "eap_teap_method_sequence") == 0) {
2741 bss->eap_teap_method_sequence = atoi(pos);
2627#endif /* EAP_SERVER_TEAP */2742#endif /* EAP_SERVER_TEAP */
2628#ifdef EAP_SERVER_SIM2743#ifdef EAP_SERVER_SIM
2629 } else if (os_strcmp(buf, "eap_sim_db") == 0) {2744 } else if (os_strcmp(buf, "eap_sim_db") == 0) {
@@ -2635,6 +2750,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2635 bss->eap_sim_aka_result_ind = atoi(pos);2750 bss->eap_sim_aka_result_ind = atoi(pos);
2636 } else if (os_strcmp(buf, "eap_sim_id") == 0) {2751 } else if (os_strcmp(buf, "eap_sim_id") == 0) {
2637 bss->eap_sim_id = atoi(pos);2752 bss->eap_sim_id = atoi(pos);
2753 } else if (os_strcmp(buf, "imsi_privacy_key") == 0) {
2754 os_free(bss->imsi_privacy_key);
2755 bss->imsi_privacy_key = os_strdup(pos);
2756 } else if (os_strcmp(buf, "eap_sim_aka_fast_reauth_limit") == 0) {
2757 bss->eap_sim_aka_fast_reauth_limit = atoi(pos);
2638#endif /* EAP_SERVER_SIM */2758#endif /* EAP_SERVER_SIM */
2639#ifdef EAP_SERVER_TNC2759#ifdef EAP_SERVER_TNC
2640 } else if (os_strcmp(buf, "tnc") == 0) {2760 } else if (os_strcmp(buf, "tnc") == 0) {
@@ -2770,6 +2890,37 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2770 os_free(bss->radius->auth_server->shared_secret);2890 os_free(bss->radius->auth_server->shared_secret);
2771 bss->radius->auth_server->shared_secret = (u8 *) os_strdup(pos);2891 bss->radius->auth_server->shared_secret = (u8 *) os_strdup(pos);
2772 bss->radius->auth_server->shared_secret_len = len;2892 bss->radius->auth_server->shared_secret_len = len;
2893 } else if (bss->radius->auth_server &&
2894 os_strcmp(buf, "auth_server_type") == 0) {
2895 if (os_strcmp(pos, "UDP") == 0) {
2896 bss->radius->auth_server->tls = false;
2897#ifdef CONFIG_RADIUS_TLS
2898 } else if (os_strcmp(pos, "TLS") == 0) {
2899 bss->radius->auth_server->tls = true;
2900#endif /* CONFIG_RADIUS_TLS */
2901 } else {
2902 wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
2903 line, pos);
2904 return 1;
2905 }
2906#ifdef CONFIG_RADIUS_TLS
2907 } else if (bss->radius->auth_server &&
2908 os_strcmp(buf, "auth_server_ca_cert") == 0) {
2909 os_free(bss->radius->auth_server->ca_cert);
2910 bss->radius->auth_server->ca_cert = os_strdup(pos);
2911 } else if (bss->radius->auth_server &&
2912 os_strcmp(buf, "auth_server_client_cert") == 0) {
2913 os_free(bss->radius->auth_server->client_cert);
2914 bss->radius->auth_server->client_cert = os_strdup(pos);
2915 } else if (bss->radius->auth_server &&
2916 os_strcmp(buf, "auth_server_private_key") == 0) {
2917 os_free(bss->radius->auth_server->private_key);
2918 bss->radius->auth_server->private_key = os_strdup(pos);
2919 } else if (bss->radius->auth_server &&
2920 os_strcmp(buf, "auth_server_private_key_passwd") == 0) {
2921 os_free(bss->radius->auth_server->private_key_passwd);
2922 bss->radius->auth_server->private_key_passwd = os_strdup(pos);
2923#endif /* CONFIG_RADIUS_TLS */
2773 } else if (os_strcmp(buf, "acct_server_addr") == 0) {2924 } else if (os_strcmp(buf, "acct_server_addr") == 0) {
2774 if (hostapd_config_read_radius_addr(2925 if (hostapd_config_read_radius_addr(
2775 &bss->radius->acct_servers,2926 &bss->radius->acct_servers,
@@ -2804,8 +2955,42 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2804 os_free(bss->radius->acct_server->shared_secret);2955 os_free(bss->radius->acct_server->shared_secret);
2805 bss->radius->acct_server->shared_secret = (u8 *) os_strdup(pos);2956 bss->radius->acct_server->shared_secret = (u8 *) os_strdup(pos);
2806 bss->radius->acct_server->shared_secret_len = len;2957 bss->radius->acct_server->shared_secret_len = len;
2958 } else if (bss->radius->acct_server &&
2959 os_strcmp(buf, "acct_server_type") == 0) {
2960 if (os_strcmp(pos, "UDP") == 0) {
2961 bss->radius->acct_server->tls = false;
2962#ifdef CONFIG_RADIUS_TLS
2963 } else if (os_strcmp(pos, "TLS") == 0) {
2964 bss->radius->acct_server->tls = true;
2965#endif /* CONFIG_RADIUS_TLS */
2966 } else {
2967 wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
2968 line, pos);
2969 return 1;
2970 }
2971#ifdef CONFIG_RADIUS_TLS
2972 } else if (bss->radius->acct_server &&
2973 os_strcmp(buf, "acct_server_ca_cert") == 0) {
2974 os_free(bss->radius->acct_server->ca_cert);
2975 bss->radius->acct_server->ca_cert = os_strdup(pos);
2976 } else if (bss->radius->acct_server &&
2977 os_strcmp(buf, "acct_server_client_cert") == 0) {
2978 os_free(bss->radius->acct_server->client_cert);
2979 bss->radius->acct_server->client_cert = os_strdup(pos);
2980 } else if (bss->radius->acct_server &&
2981 os_strcmp(buf, "acct_server_private_key") == 0) {
2982 os_free(bss->radius->acct_server->private_key);
2983 bss->radius->acct_server->private_key = os_strdup(pos);
2984 } else if (bss->radius->acct_server &&
2985 os_strcmp(buf, "acct_server_private_key_passwd") == 0) {
2986 os_free(bss->radius->acct_server->private_key_passwd);
2987 bss->radius->acct_server->private_key_passwd = os_strdup(pos);
2988#endif /* CONFIG_RADIUS_TLS */
2807 } else if (os_strcmp(buf, "radius_retry_primary_interval") == 0) {2989 } else if (os_strcmp(buf, "radius_retry_primary_interval") == 0) {
2808 bss->radius->retry_primary_interval = atoi(pos);2990 bss->radius->retry_primary_interval = atoi(pos);
2991 } else if (os_strcmp(buf,
2992 "radius_require_message_authenticator") == 0) {
2993 bss->radius_require_message_authenticator = atoi(pos);
2809 } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0) {2994 } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0) {
2810 bss->acct_interim_interval = atoi(pos);2995 bss->acct_interim_interval = atoi(pos);
2811 } else if (os_strcmp(buf, "radius_request_cui") == 0) {2996 } else if (os_strcmp(buf, "radius_request_cui") == 0) {
@@ -2975,7 +3160,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
2975 bss->wpa_psk_radius = atoi(pos);3160 bss->wpa_psk_radius = atoi(pos);
2976 if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&3161 if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
2977 bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&3162 bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
2978 bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {3163 bss->wpa_psk_radius != PSK_RADIUS_REQUIRED &&
3164 bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS) {
2979 wpa_printf(MSG_ERROR,3165 wpa_printf(MSG_ERROR,
2980 "Line %d: unknown wpa_psk_radius %d",3166 "Line %d: unknown wpa_psk_radius %d",
2981 line, bss->wpa_psk_radius);3167 line, bss->wpa_psk_radius);
@@ -3072,6 +3258,21 @@ static int hostapd_config_fill(struct hostapd_config *conf,
3072 line, pos);3258 line, pos);
3073 return 1;3259 return 1;
3074 }3260 }
3261 } else if (os_strcmp(buf, "rxkh_file") == 0) {
3262 os_free(bss->rxkh_file);
3263 bss->rxkh_file = os_strdup(pos);
3264 if (!bss->rxkh_file) {
3265 wpa_printf(MSG_ERROR, "Line %d: allocation failed",
3266 line);
3267 return 1;
3268 }
3269 if (hostapd_config_read_rxkh_file(bss, pos)) {
3270 wpa_printf(MSG_DEBUG,
3271 "Line %d: failed to read rxkh_file '%s'",
3272 line, pos);
3273 /* Allow the file to be created later and read into
3274 * already operating AP context. */
3275 }
3075 } else if (os_strcmp(buf, "pmk_r1_push") == 0) {3276 } else if (os_strcmp(buf, "pmk_r1_push") == 0) {
3076 bss->pmk_r1_push = atoi(pos);3277 bss->pmk_r1_push = atoi(pos);
3077 } else if (os_strcmp(buf, "ft_over_ds") == 0) {3278 } else if (os_strcmp(buf, "ft_over_ds") == 0) {
@@ -3139,6 +3340,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
3139 line, pos);3340 line, pos);
3140 return 1;3341 return 1;
3141 }3342 }
3343 conf->hw_mode_set = true;
3142 } else if (os_strcmp(buf, "wps_rf_bands") == 0) {3344 } else if (os_strcmp(buf, "wps_rf_bands") == 0) {
3143 if (os_strcmp(pos, "ad") == 0)3345 if (os_strcmp(pos, "ad") == 0)
3144 bss->wps_rf_bands = WPS_RF_60GHZ;3346 bss->wps_rf_bands = WPS_RF_60GHZ;
@@ -3193,6 +3395,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
3193 conf->acs_freq_list_present = 1;3395 conf->acs_freq_list_present = 1;
3194 } else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) {3396 } else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) {
3195 conf->acs_exclude_6ghz_non_psc = atoi(pos);3397 conf->acs_exclude_6ghz_non_psc = atoi(pos);
3398 } else if (os_strcmp(buf, "enable_background_radar") == 0) {
3399 conf->enable_background_radar = atoi(pos);
3196 } else if (os_strcmp(buf, "min_tx_power") == 0) {3400 } else if (os_strcmp(buf, "min_tx_power") == 0) {
3197 int val = atoi(pos);3401 int val = atoi(pos);
31983402
@@ -3484,6 +3688,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
3484 }3688 }
3485 } else if (os_strcmp(buf, "require_ht") == 0) {3689 } else if (os_strcmp(buf, "require_ht") == 0) {
3486 conf->require_ht = atoi(pos);3690 conf->require_ht = atoi(pos);
3691 } else if (os_strcmp(buf, "ht_vht_twt_responder") == 0) {
3692 conf->ht_vht_twt_responder = atoi(pos);
3487 } else if (os_strcmp(buf, "obss_interval") == 0) {3693 } else if (os_strcmp(buf, "obss_interval") == 0) {
3488 conf->obss_interval = atoi(pos);3694 conf->obss_interval = atoi(pos);
3489#ifdef CONFIG_IEEE80211AC3695#ifdef CONFIG_IEEE80211AC
@@ -3511,6 +3717,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
3511#ifdef CONFIG_IEEE80211AX3717#ifdef CONFIG_IEEE80211AX
3512 } else if (os_strcmp(buf, "ieee80211ax") == 0) {3718 } else if (os_strcmp(buf, "ieee80211ax") == 0) {
3513 conf->ieee80211ax = atoi(pos);3719 conf->ieee80211ax = atoi(pos);
3720 } else if (os_strcmp(buf, "require_he") == 0) {
3721 conf->require_he = atoi(pos);
3514 } else if (os_strcmp(buf, "he_su_beamformer") == 0) {3722 } else if (os_strcmp(buf, "he_su_beamformer") == 0) {
3515 conf->he_phy_capab.he_su_beamformer = atoi(pos);3723 conf->he_phy_capab.he_su_beamformer = atoi(pos);
3516 } else if (os_strcmp(buf, "he_su_beamformee") == 0) {3724 } else if (os_strcmp(buf, "he_su_beamformee") == 0) {
@@ -3642,6 +3850,20 @@ static int hostapd_config_fill(struct hostapd_config *conf,
3642 line, pos);3850 line, pos);
3643 return 1;3851 return 1;
3644 }3852 }
3853 } else if (os_strcmp(buf, "he_6ghz_reg_pwr_type") == 0) {
3854 conf->he_6ghz_reg_pwr_type = atoi(pos);
3855 if (conf->he_6ghz_reg_pwr_type > HE_REG_INFO_6GHZ_AP_TYPE_MAX) {
3856 wpa_printf(MSG_ERROR,
3857 "Line %d: invalid he_6ghz_reg_pwr_type value",
3858 line);
3859 return 1;
3860 }
3861 } else if (os_strcmp(buf, "reg_def_cli_eirp_psd") == 0) {
3862 conf->reg_def_cli_eirp_psd = atoi(pos);
3863 } else if (os_strcmp(buf, "reg_sub_cli_eirp_psd") == 0) {
3864 conf->reg_sub_cli_eirp_psd = atoi(pos);
3865 } else if (os_strcmp(buf, "reg_def_cli_eirp") == 0) {
3866 conf->reg_def_cli_eirp = atoi(pos);
3645 } else if (os_strcmp(buf, "he_oper_chwidth") == 0) {3867 } else if (os_strcmp(buf, "he_oper_chwidth") == 0) {
3646 conf->he_oper_chwidth = atoi(pos);3868 conf->he_oper_chwidth = atoi(pos);
3647 } else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) {3869 } else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) {
@@ -3666,6 +3888,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
3666 return 1;3888 return 1;
3667 }3889 }
3668 bss->unsol_bcast_probe_resp_interval = val;3890 bss->unsol_bcast_probe_resp_interval = val;
3891 } else if (os_strcmp(buf, "mbssid") == 0) {
3892 int mbssid = atoi(pos);
3893 if (mbssid < 0 || mbssid > ENHANCED_MBSSID_ENABLED) {
3894 wpa_printf(MSG_ERROR,
3895 "Line %d: invalid mbssid (%d): '%s'.",
3896 line, mbssid, pos);
3897 return 1;
3898 }
3899 conf->mbssid = mbssid;
3669#endif /* CONFIG_IEEE80211AX */3900#endif /* CONFIG_IEEE80211AX */
3670 } else if (os_strcmp(buf, "max_listen_interval") == 0) {3901 } else if (os_strcmp(buf, "max_listen_interval") == 0) {
3671 bss->max_listen_interval = atoi(pos);3902 bss->max_listen_interval = atoi(pos);
@@ -4053,10 +4284,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4053 bss->gas_frag_limit = val;4284 bss->gas_frag_limit = val;
4054 } else if (os_strcmp(buf, "gas_comeback_delay") == 0) {4285 } else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
4055 bss->gas_comeback_delay = atoi(pos);4286 bss->gas_comeback_delay = atoi(pos);
4287#endif /* CONFIG_INTERWORKING */
4056 } else if (os_strcmp(buf, "qos_map_set") == 0) {4288 } else if (os_strcmp(buf, "qos_map_set") == 0) {
4057 if (parse_qos_map_set(bss, pos, line) < 0)4289 if (parse_qos_map_set(bss, pos, line) < 0)
4058 return 1;4290 return 1;
4059#endif /* CONFIG_INTERWORKING */
4060#ifdef CONFIG_RADIUS_TEST4291#ifdef CONFIG_RADIUS_TEST
4061 } else if (os_strcmp(buf, "dump_msk_file") == 0) {4292 } else if (os_strcmp(buf, "dump_msk_file") == 0) {
4062 os_free(bss->dump_msk_file);4293 os_free(bss->dump_msk_file);
@@ -4297,6 +4528,23 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4297 bss->oci_freq_override_fils_assoc = atoi(pos);4528 bss->oci_freq_override_fils_assoc = atoi(pos);
4298 } else if (os_strcmp(buf, "oci_freq_override_wnm_sleep") == 0) {4529 } else if (os_strcmp(buf, "oci_freq_override_wnm_sleep") == 0) {
4299 bss->oci_freq_override_wnm_sleep = atoi(pos);4530 bss->oci_freq_override_wnm_sleep = atoi(pos);
4531 } else if (os_strcmp(buf, "eap_skip_prot_success") == 0) {
4532 bss->eap_skip_prot_success = atoi(pos);
4533 } else if (os_strcmp(buf, "delay_eapol_tx") == 0) {
4534 conf->delay_eapol_tx = atoi(pos);
4535 } else if (os_strcmp(buf, "eapol_m1_elements") == 0) {
4536 if (parse_wpabuf_hex(line, buf, &bss->eapol_m1_elements, pos))
4537 return 1;
4538 } else if (os_strcmp(buf, "eapol_m3_elements") == 0) {
4539 if (parse_wpabuf_hex(line, buf, &bss->eapol_m3_elements, pos))
4540 return 1;
4541 } else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) {
4542 bss->eapol_m3_no_encrypt = atoi(pos);
4543 } else if (os_strcmp(buf, "test_assoc_comeback_type") == 0) {
4544 bss->test_assoc_comeback_type = atoi(pos);
4545 } else if (os_strcmp(buf, "presp_elements") == 0) {
4546 if (parse_wpabuf_hex(line, buf, &bss->presp_elements, pos))
4547 return 1;
4300#endif /* CONFIG_TESTING_OPTIONS */4548#endif /* CONFIG_TESTING_OPTIONS */
4301#ifdef CONFIG_SAE4549#ifdef CONFIG_SAE
4302 } else if (os_strcmp(buf, "sae_password") == 0) {4550 } else if (os_strcmp(buf, "sae_password") == 0) {
@@ -4305,6 +4553,13 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4305 line);4553 line);
4306 return 1;4554 return 1;
4307 }4555 }
4556 } else if (os_strcmp(buf, "sae_password_file") == 0) {
4557 if (parse_sae_password_file(bss, pos) < 0) {
4558 wpa_printf(MSG_ERROR,
4559 "Line %d: Invalid sae_password in file",
4560 line);
4561 return 1;
4562 }
4308#endif /* CONFIG_SAE */4563#endif /* CONFIG_SAE */
4309 } else if (os_strcmp(buf, "vendor_elements") == 0) {4564 } else if (os_strcmp(buf, "vendor_elements") == 0) {
4310 if (parse_wpabuf_hex(line, buf, &bss->vendor_elements, pos))4565 if (parse_wpabuf_hex(line, buf, &bss->vendor_elements, pos))
@@ -4436,6 +4691,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4436 WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |4691 WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
4437 WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |4692 WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
4438 WLAN_RRM_CAPS_BEACON_REPORT_TABLE;4693 WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
4694 } else if (os_strcmp(buf, "rrm_link_measurement_report") == 0) {
4695 if (atoi(pos))
4696 bss->radio_measurements[0] |=
4697 WLAN_RRM_CAPS_LINK_MEASUREMENT;
4439 } else if (os_strcmp(buf, "gas_address3") == 0) {4698 } else if (os_strcmp(buf, "gas_address3") == 0) {
4440 bss->gas_address3 = atoi(pos);4699 bss->gas_address3 = atoi(pos);
4441 } else if (os_strcmp(buf, "stationary_ap") == 0) {4700 } else if (os_strcmp(buf, "stationary_ap") == 0) {
@@ -4480,6 +4739,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4480#endif /* CONFIG_FILS */4739#endif /* CONFIG_FILS */
4481 } else if (os_strcmp(buf, "multicast_to_unicast") == 0) {4740 } else if (os_strcmp(buf, "multicast_to_unicast") == 0) {
4482 bss->multicast_to_unicast = atoi(pos);4741 bss->multicast_to_unicast = atoi(pos);
4742 } else if (os_strcmp(buf, "bridge_multicast_to_unicast") == 0) {
4743 bss->bridge_multicast_to_unicast = atoi(pos);
4483 } else if (os_strcmp(buf, "broadcast_deauth") == 0) {4744 } else if (os_strcmp(buf, "broadcast_deauth") == 0) {
4484 bss->broadcast_deauth = atoi(pos);4745 bss->broadcast_deauth = atoi(pos);
4485 } else if (os_strcmp(buf, "notify_mgmt_frames") == 0) {4746 } else if (os_strcmp(buf, "notify_mgmt_frames") == 0) {
@@ -4491,6 +4752,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4491 } else if (os_strcmp(buf, "dpp_mud_url") == 0) {4752 } else if (os_strcmp(buf, "dpp_mud_url") == 0) {
4492 os_free(bss->dpp_mud_url);4753 os_free(bss->dpp_mud_url);
4493 bss->dpp_mud_url = os_strdup(pos);4754 bss->dpp_mud_url = os_strdup(pos);
4755 } else if (os_strcmp(buf, "dpp_extra_conf_req_name") == 0) {
4756 os_free(bss->dpp_extra_conf_req_name);
4757 bss->dpp_extra_conf_req_name = os_strdup(pos);
4758 } else if (os_strcmp(buf, "dpp_extra_conf_req_value") == 0) {
4759 os_free(bss->dpp_extra_conf_req_value);
4760 bss->dpp_extra_conf_req_value = os_strdup(pos);
4494 } else if (os_strcmp(buf, "dpp_connector") == 0) {4761 } else if (os_strcmp(buf, "dpp_connector") == 0) {
4495 os_free(bss->dpp_connector);4762 os_free(bss->dpp_connector);
4496 bss->dpp_connector = os_strdup(pos);4763 bss->dpp_connector = os_strdup(pos);
@@ -4506,6 +4773,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4506 } else if (os_strcmp(buf, "dpp_controller") == 0) {4773 } else if (os_strcmp(buf, "dpp_controller") == 0) {
4507 if (hostapd_dpp_controller_parse(bss, pos))4774 if (hostapd_dpp_controller_parse(bss, pos))
4508 return 1;4775 return 1;
4776 } else if (os_strcmp(buf, "dpp_relay_port") == 0) {
4777 bss->dpp_relay_port = atoi(pos);
4509 } else if (os_strcmp(buf, "dpp_configurator_connectivity") == 0) {4778 } else if (os_strcmp(buf, "dpp_configurator_connectivity") == 0) {
4510 bss->dpp_configurator_connectivity = atoi(pos);4779 bss->dpp_configurator_connectivity = atoi(pos);
4511 } else if (os_strcmp(buf, "dpp_pfs") == 0) {4780 } else if (os_strcmp(buf, "dpp_pfs") == 0) {
@@ -4566,6 +4835,36 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4566 }4835 }
45674836
4568 bss->multi_ap = val;4837 bss->multi_ap = val;
4838 } else if (os_strcmp(buf, "multi_ap_profile") == 0) {
4839 int val = atoi(pos);
4840
4841 if (val < MULTI_AP_PROFILE_1 || val > MULTI_AP_PROFILE_MAX) {
4842 wpa_printf(MSG_ERROR,
4843 "Line %d: Invalid multi_ap_profile '%s'",
4844 line, buf);
4845 return -1;
4846 }
4847 bss->multi_ap_profile = val;
4848 } else if (os_strcmp(buf, "multi_ap_client_disallow") == 0) {
4849 int val = atoi(pos);
4850
4851 if (val < 0 || val > 3) {
4852 wpa_printf(MSG_ERROR,
4853 "Line %d: Invalid multi_ap_client_allow '%s'",
4854 line, buf);
4855 return -1;
4856 }
4857 bss->multi_ap_client_disallow = val;
4858 } else if (os_strcmp(buf, "multi_ap_vlanid") == 0) {
4859 int val = atoi(pos);
4860
4861 if (val < 0 || val > MAX_VLAN_ID) {
4862 wpa_printf(MSG_ERROR,
4863 "Line %d: Invalid multi_ap_vlan_id '%s'",
4864 line, buf);
4865 return -1;
4866 }
4867 bss->multi_ap_vlanid = val;
4569 } else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) {4868 } else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) {
4570 conf->rssi_reject_assoc_rssi = atoi(pos);4869 conf->rssi_reject_assoc_rssi = atoi(pos);
4571 } else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) {4870 } else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) {
@@ -4641,6 +4940,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4641 bss->macsec_replay_protect = macsec_replay_protect;4940 bss->macsec_replay_protect = macsec_replay_protect;
4642 } else if (os_strcmp(buf, "macsec_replay_window") == 0) {4941 } else if (os_strcmp(buf, "macsec_replay_window") == 0) {
4643 bss->macsec_replay_window = atoi(pos);4942 bss->macsec_replay_window = atoi(pos);
4943 } else if (os_strcmp(buf, "macsec_offload") == 0) {
4944 int macsec_offload = atoi(pos);
4945
4946 if (macsec_offload < 0 || macsec_offload > 2) {
4947 wpa_printf(MSG_ERROR,
4948 "Line %d: invalid macsec_offload (%d): '%s'.",
4949 line, macsec_offload, pos);
4950 return 1;
4951 }
4952 bss->macsec_offload = macsec_offload;
4644 } else if (os_strcmp(buf, "macsec_port") == 0) {4953 } else if (os_strcmp(buf, "macsec_port") == 0) {
4645 int macsec_port = atoi(pos);4954 int macsec_port = atoi(pos);
46464955
@@ -4661,6 +4970,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4661 return 1;4970 return 1;
4662 }4971 }
4663 bss->mka_priority = mka_priority;4972 bss->mka_priority = mka_priority;
4973 } else if (os_strcmp(buf, "macsec_csindex") == 0) {
4974 int macsec_csindex = atoi(pos);
4975
4976 if (macsec_csindex < 0 || macsec_csindex > 1) {
4977 wpa_printf(MSG_ERROR,
4978 "Line %d: invalid macsec_csindex (%d): '%s'.",
4979 line, macsec_csindex, pos);
4980 return 1;
4981 }
4982 bss->macsec_csindex = macsec_csindex;
4664 } else if (os_strcmp(buf, "mka_cak") == 0) {4983 } else if (os_strcmp(buf, "mka_cak") == 0) {
4665 size_t len = os_strlen(pos);4984 size_t len = os_strlen(pos);
46664985
@@ -4697,6 +5016,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4697 bss->disable_11ac = !!atoi(pos);5016 bss->disable_11ac = !!atoi(pos);
4698 } else if (os_strcmp(buf, "disable_11ax") == 0) {5017 } else if (os_strcmp(buf, "disable_11ax") == 0) {
4699 bss->disable_11ax = !!atoi(pos);5018 bss->disable_11ax = !!atoi(pos);
5019 } else if (os_strcmp(buf, "disable_11be") == 0) {
5020 bss->disable_11be = !!atoi(pos);
4700#ifdef CONFIG_PASN5021#ifdef CONFIG_PASN
4701#ifdef CONFIG_TESTING_OPTIONS5022#ifdef CONFIG_TESTING_OPTIONS
4702 } else if (os_strcmp(buf, "force_kdk_derivation") == 0) {5023 } else if (os_strcmp(buf, "force_kdk_derivation") == 0) {
@@ -4713,6 +5034,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4713 }5034 }
4714 } else if (os_strcmp(buf, "pasn_comeback_after") == 0) {5035 } else if (os_strcmp(buf, "pasn_comeback_after") == 0) {
4715 bss->pasn_comeback_after = atoi(pos);5036 bss->pasn_comeback_after = atoi(pos);
5037 } else if (os_strcmp(buf, "pasn_noauth") == 0) {
5038 bss->pasn_noauth = atoi(pos);
4716#endif /* CONFIG_PASN */5039#endif /* CONFIG_PASN */
4717 } else if (os_strcmp(buf, "ext_capa_mask") == 0) {5040 } else if (os_strcmp(buf, "ext_capa_mask") == 0) {
4718 if (get_hex_config(bss->ext_capa_mask, EXT_CAPA_MAX_LEN,5041 if (get_hex_config(bss->ext_capa_mask, EXT_CAPA_MAX_LEN,
@@ -4724,6 +5047,58 @@ static int hostapd_config_fill(struct hostapd_config *conf,
4724 return 1;5047 return 1;
4725 } else if (os_strcmp(buf, "rnr") == 0) {5048 } else if (os_strcmp(buf, "rnr") == 0) {
4726 bss->rnr = atoi(pos);5049 bss->rnr = atoi(pos);
5050 } else if (os_strcmp(buf, "ssid_protection") == 0) {
5051 int val = atoi(pos);
5052
5053 if (val < 0 || val > 1)
5054 return 1;
5055 bss->ssid_protection = val;
5056#ifdef CONFIG_IEEE80211BE
5057 } else if (os_strcmp(buf, "ieee80211be") == 0) {
5058 conf->ieee80211be = atoi(pos);
5059 } else if (os_strcmp(buf, "eht_oper_chwidth") == 0) {
5060 conf->eht_oper_chwidth = atoi(pos);
5061 } else if (os_strcmp(buf, "eht_oper_centr_freq_seg0_idx") == 0) {
5062 conf->eht_oper_centr_freq_seg0_idx = atoi(pos);
5063 } else if (os_strcmp(buf, "eht_su_beamformer") == 0) {
5064 conf->eht_phy_capab.su_beamformer = atoi(pos);
5065 } else if (os_strcmp(buf, "eht_su_beamformee") == 0) {
5066 conf->eht_phy_capab.su_beamformee = atoi(pos);
5067 } else if (os_strcmp(buf, "eht_mu_beamformer") == 0) {
5068 conf->eht_phy_capab.mu_beamformer = atoi(pos);
5069 } else if (os_strcmp(buf, "eht_default_pe_duration") == 0) {
5070 conf->eht_default_pe_duration = atoi(pos);
5071 } else if (os_strcmp(buf, "punct_bitmap") == 0) {
5072 if (get_u16(pos, line, &conf->punct_bitmap))
5073 return 1;
5074 } else if (os_strcmp(buf, "punct_acs_threshold") == 0) {
5075 int val = atoi(pos);
5076
5077 if (val < 0 || val > 100) {
5078 wpa_printf(MSG_ERROR,
5079 "Line %d: punct_acs_threshold must be between 0 and 100",
5080 line);
5081 return 1;
5082 }
5083 conf->punct_acs_threshold = val;
5084 } else if (os_strcmp(buf, "mld_ap") == 0) {
5085 bss->mld_ap = !!atoi(pos);
5086 } else if (os_strcmp(buf, "mld_addr") == 0) {
5087 if (hwaddr_aton(pos, bss->mld_addr)) {
5088 wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr",
5089 line);
5090 return 1;
5091 }
5092 } else if (os_strcmp(buf, "eht_bw320_offset") == 0) {
5093 conf->eht_bw320_offset = atoi(pos);
5094#ifdef CONFIG_TESTING_OPTIONS
5095 } else if (os_strcmp(buf, "eht_oper_puncturing_override") == 0) {
5096 if (get_u16(pos, line, &bss->eht_oper_puncturing_override))
5097 return 1;
5098 } else if (os_strcmp(buf, "mld_indicate_disabled") == 0) {
5099 bss->mld_indicate_disabled = atoi(pos);
5100#endif /* CONFIG_TESTING_OPTIONS */
5101#endif /* CONFIG_IEEE80211BE */
4727 } else {5102 } else {
4728 wpa_printf(MSG_ERROR,5103 wpa_printf(MSG_ERROR,
4729 "Line %d: unknown configuration item '%s'",5104 "Line %d: unknown configuration item '%s'",
diff --git a/hostapd/config_file.h b/hostapd/config_file.h
index 9830f5a..9ef6ac8 100644
--- a/hostapd/config_file.h
+++ b/hostapd/config_file.h
@@ -10,13 +10,10 @@
10#define CONFIG_FILE_H10#define CONFIG_FILE_H
1111
12struct hostapd_config * hostapd_config_read(const char *fname);12struct hostapd_config * hostapd_config_read(const char *fname);
13int hostapd_config_read_rxkh_file(struct hostapd_bss_config *conf,
14 const char *fname);
13int hostapd_set_iface(struct hostapd_config *conf,15int hostapd_set_iface(struct hostapd_config *conf,
14 struct hostapd_bss_config *bss, const char *field,16 struct hostapd_bss_config *bss, const char *field,
15 char *value);17 char *value);
16int hostapd_acl_comp(const void *a, const void *b);
17int hostapd_add_acl_maclist(struct mac_acl_entry **acl, int *num,
18 int vlan_id, const u8 *addr);
19void hostapd_remove_acl_mac(struct mac_acl_entry **acl, int *num,
20 const u8 *addr);
2118
22#endif /* CONFIG_FILE_H */19#endif /* CONFIG_FILE_H */
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 86adf18..39b9ef5 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -38,6 +38,8 @@
38#endif /* CONFIG_DPP */38#endif /* CONFIG_DPP */
39#include "common/wpa_ctrl.h"39#include "common/wpa_ctrl.h"
40#include "common/ptksa_cache.h"40#include "common/ptksa_cache.h"
41#include "common/hw_features_common.h"
42#include "common/nan_de.h"
41#include "crypto/tls.h"43#include "crypto/tls.h"
42#include "drivers/driver.h"44#include "drivers/driver.h"
43#include "eapol_auth/eapol_auth_sm.h"45#include "eapol_auth/eapol_auth_sm.h"
@@ -62,6 +64,7 @@
62#include "ap/rrm.h"64#include "ap/rrm.h"
63#include "ap/dpp_hostapd.h"65#include "ap/dpp_hostapd.h"
64#include "ap/dfs.h"66#include "ap/dfs.h"
67#include "ap/nan_usd_ap.h"
65#include "wps/wps_defs.h"68#include "wps/wps_defs.h"
66#include "wps/wps.h"69#include "wps/wps.h"
67#include "fst/fst_ctrl_iface.h"70#include "fst/fst_ctrl_iface.h"
@@ -772,235 +775,6 @@ static int hostapd_ctrl_iface_send_qos_map_conf(struct hostapd_data *hapd,
772775
773#ifdef CONFIG_WNM_AP776#ifdef CONFIG_WNM_AP
774777
775static int hostapd_ctrl_iface_disassoc_imminent(struct hostapd_data *hapd,
776 const char *cmd)
777{
778 u8 addr[ETH_ALEN];
779 int disassoc_timer;
780 struct sta_info *sta;
781
782 if (hwaddr_aton(cmd, addr))
783 return -1;
784 if (cmd[17] != ' ')
785 return -1;
786 disassoc_timer = atoi(cmd + 17);
787
788 sta = ap_get_sta(hapd, addr);
789 if (sta == NULL) {
790 wpa_printf(MSG_DEBUG, "Station " MACSTR
791 " not found for disassociation imminent message",
792 MAC2STR(addr));
793 return -1;
794 }
795
796 return wnm_send_disassoc_imminent(hapd, sta, disassoc_timer);
797}
798
799
800static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
801 const char *cmd)
802{
803 u8 addr[ETH_ALEN];
804 const char *url, *timerstr;
805 int disassoc_timer;
806 struct sta_info *sta;
807
808 if (hwaddr_aton(cmd, addr))
809 return -1;
810
811 sta = ap_get_sta(hapd, addr);
812 if (sta == NULL) {
813 wpa_printf(MSG_DEBUG, "Station " MACSTR
814 " not found for ESS disassociation imminent message",
815 MAC2STR(addr));
816 return -1;
817 }
818
819 timerstr = cmd + 17;
820 if (*timerstr != ' ')
821 return -1;
822 timerstr++;
823 disassoc_timer = atoi(timerstr);
824 if (disassoc_timer < 0 || disassoc_timer > 65535)
825 return -1;
826
827 url = os_strchr(timerstr, ' ');
828 if (url == NULL)
829 return -1;
830 url++;
831
832 return wnm_send_ess_disassoc_imminent(hapd, sta, url, disassoc_timer);
833}
834
835
836static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
837 const char *cmd)
838{
839 u8 addr[ETH_ALEN];
840 const char *pos, *end;
841 int disassoc_timer = 0;
842 struct sta_info *sta;
843 u8 req_mode = 0, valid_int = 0x01, dialog_token = 0x01;
844 u8 bss_term_dur[12];
845 char *url = NULL;
846 int ret;
847 u8 nei_rep[1000];
848 int nei_len;
849 u8 mbo[10];
850 size_t mbo_len = 0;
851
852 if (hwaddr_aton(cmd, addr)) {
853 wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
854 return -1;
855 }
856
857 sta = ap_get_sta(hapd, addr);
858 if (sta == NULL) {
859 wpa_printf(MSG_DEBUG, "Station " MACSTR
860 " not found for BSS TM Request message",
861 MAC2STR(addr));
862 return -1;
863 }
864
865 pos = os_strstr(cmd, " disassoc_timer=");
866 if (pos) {
867 pos += 16;
868 disassoc_timer = atoi(pos);
869 if (disassoc_timer < 0 || disassoc_timer > 65535) {
870 wpa_printf(MSG_DEBUG, "Invalid disassoc_timer");
871 return -1;
872 }
873 }
874
875 pos = os_strstr(cmd, " valid_int=");
876 if (pos) {
877 pos += 11;
878 valid_int = atoi(pos);
879 }
880
881 pos = os_strstr(cmd, " dialog_token=");
882 if (pos) {
883 pos += 14;
884 dialog_token = atoi(pos);
885 }
886
887 pos = os_strstr(cmd, " bss_term=");
888 if (pos) {
889 pos += 10;
890 req_mode |= WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED;
891 /* TODO: TSF configurable/learnable */
892 bss_term_dur[0] = 4; /* Subelement ID */
893 bss_term_dur[1] = 10; /* Length */
894 os_memset(&bss_term_dur[2], 0, 8);
895 end = os_strchr(pos, ',');
896 if (end == NULL) {
897 wpa_printf(MSG_DEBUG, "Invalid bss_term data");
898 return -1;
899 }
900 end++;
901 WPA_PUT_LE16(&bss_term_dur[10], atoi(end));
902 }
903
904 nei_len = ieee802_11_parse_candidate_list(cmd, nei_rep,
905 sizeof(nei_rep));
906 if (nei_len < 0)
907 return -1;
908
909 pos = os_strstr(cmd, " url=");
910 if (pos) {
911 size_t len;
912 pos += 5;
913 end = os_strchr(pos, ' ');
914 if (end)
915 len = end - pos;
916 else
917 len = os_strlen(pos);
918 url = os_malloc(len + 1);
919 if (url == NULL)
920 return -1;
921 os_memcpy(url, pos, len);
922 url[len] = '\0';
923 req_mode |= WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
924 }
925
926 if (os_strstr(cmd, " pref=1"))
927 req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
928 if (os_strstr(cmd, " abridged=1"))
929 req_mode |= WNM_BSS_TM_REQ_ABRIDGED;
930 if (os_strstr(cmd, " disassoc_imminent=1"))
931 req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
932
933#ifdef CONFIG_MBO
934 pos = os_strstr(cmd, "mbo=");
935 if (pos) {
936 unsigned int mbo_reason, cell_pref, reassoc_delay;
937 u8 *mbo_pos = mbo;
938
939 ret = sscanf(pos, "mbo=%u:%u:%u", &mbo_reason,
940 &reassoc_delay, &cell_pref);
941 if (ret != 3) {
942 wpa_printf(MSG_DEBUG,
943 "MBO requires three arguments: mbo=<reason>:<reassoc_delay>:<cell_pref>");
944 ret = -1;
945 goto fail;
946 }
947
948 if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) {
949 wpa_printf(MSG_DEBUG,
950 "Invalid MBO transition reason code %u",
951 mbo_reason);
952 ret = -1;
953 goto fail;
954 }
955
956 /* Valid values for Cellular preference are: 0, 1, 255 */
957 if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) {
958 wpa_printf(MSG_DEBUG,
959 "Invalid MBO cellular capability %u",
960 cell_pref);
961 ret = -1;
962 goto fail;
963 }
964
965 if (reassoc_delay > 65535 ||
966 (reassoc_delay &&
967 !(req_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT))) {
968 wpa_printf(MSG_DEBUG,
969 "MBO: Assoc retry delay is only valid in disassoc imminent mode");
970 ret = -1;
971 goto fail;
972 }
973
974 *mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON;
975 *mbo_pos++ = 1;
976 *mbo_pos++ = mbo_reason;
977 *mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF;
978 *mbo_pos++ = 1;
979 *mbo_pos++ = cell_pref;
980
981 if (reassoc_delay) {
982 *mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY;
983 *mbo_pos++ = 2;
984 WPA_PUT_LE16(mbo_pos, reassoc_delay);
985 mbo_pos += 2;
986 }
987
988 mbo_len = mbo_pos - mbo;
989 }
990#endif /* CONFIG_MBO */
991
992 ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
993 valid_int, bss_term_dur, dialog_token, url,
994 nei_len ? nei_rep : NULL, nei_len,
995 mbo_len ? mbo : NULL, mbo_len);
996#ifdef CONFIG_MBO
997fail:
998#endif /* CONFIG_MBO */
999 os_free(url);
1000 return ret;
1001}
1002
1003
1004static int hostapd_ctrl_iface_coloc_intf_req(struct hostapd_data *hapd,778static int hostapd_ctrl_iface_coloc_intf_req(struct hostapd_data *hapd,
1005 const char *cmd)779 const char *cmd)
1006{780{
@@ -1090,6 +864,12 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
1090 return pos - buf;864 return pos - buf;
1091 pos += ret;865 pos += ret;
1092 }866 }
867 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
868 ret = os_snprintf(pos, end - pos, "FT-SAE-EXT-KEY ");
869 if (os_snprintf_error(end - pos, ret))
870 return pos - buf;
871 pos += ret;
872 }
1093#endif /* CONFIG_SAE */873#endif /* CONFIG_SAE */
1094#ifdef CONFIG_FILS874#ifdef CONFIG_FILS
1095 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {875 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
@@ -1125,6 +905,12 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
1125 return pos - buf;905 return pos - buf;
1126 pos += ret;906 pos += ret;
1127 }907 }
908 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) {
909 ret = os_snprintf(pos, end - pos, "SAE-EXT-KEY ");
910 if (os_snprintf_error(end - pos, ret))
911 return pos - buf;
912 pos += ret;
913 }
1128#endif /* CONFIG_SAE */914#endif /* CONFIG_SAE */
1129 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {915 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1130 ret = os_snprintf(pos, end - pos, "WPA-EAP-SUITE-B ");916 ret = os_snprintf(pos, end - pos, "WPA-EAP-SUITE-B ");
@@ -1172,6 +958,14 @@ static int hostapd_ctrl_iface_get_key_mgmt(struct hostapd_data *hapd,
1172 pos += ret;958 pos += ret;
1173 }959 }
1174#endif /* CONFIG_DPP */960#endif /* CONFIG_DPP */
961#ifdef CONFIG_SHA384
962 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA384) {
963 ret = os_snprintf(pos, end - pos, "WPA-EAP-SHA384 ");
964 if (os_snprintf_error(end - pos, ret))
965 return pos - buf;
966 pos += ret;
967 }
968#endif /* CONFIG_SHA384 */
1175969
1176 if (pos > buf && *(pos - 1) == ' ') {970 if (pos > buf && *(pos - 1) == ' ') {
1177 *(pos - 1) = '\0';971 *(pos - 1) = '\0';
@@ -1200,6 +994,14 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
1200 return pos - buf;994 return pos - buf;
1201 pos += ret;995 pos += ret;
1202996
997 if ((hapd->conf->config_id)) {
998 ret = os_snprintf(pos, end - pos, "config_id=%s\n",
999 hapd->conf->config_id);
1000 if (os_snprintf_error(end - pos, ret))
1001 return pos - buf;
1002 pos += ret;
1003 }
1004
1203#ifdef CONFIG_WPS1005#ifdef CONFIG_WPS
1204 ret = os_snprintf(pos, end - pos, "wps_state=%s\n",1006 ret = os_snprintf(pos, end - pos, "wps_state=%s\n",
1205 hapd->conf->wps_state == 0 ? "disabled" :1007 hapd->conf->wps_state == 0 ? "disabled" :
@@ -1362,43 +1164,6 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
1362}1164}
13631165
13641166
1365static void hostapd_disassoc_accept_mac(struct hostapd_data *hapd)
1366{
1367 struct sta_info *sta;
1368 struct vlan_description vlan_id;
1369
1370 if (hapd->conf->macaddr_acl != DENY_UNLESS_ACCEPTED)
1371 return;
1372
1373 for (sta = hapd->sta_list; sta; sta = sta->next) {
1374 if (!hostapd_maclist_found(hapd->conf->accept_mac,
1375 hapd->conf->num_accept_mac,
1376 sta->addr, &vlan_id) ||
1377 (vlan_id.notempty &&
1378 vlan_compare(&vlan_id, sta->vlan_desc)))
1379 ap_sta_disconnect(hapd, sta, sta->addr,
1380 WLAN_REASON_UNSPECIFIED);
1381 }
1382}
1383
1384
1385static void hostapd_disassoc_deny_mac(struct hostapd_data *hapd)
1386{
1387 struct sta_info *sta;
1388 struct vlan_description vlan_id;
1389
1390 for (sta = hapd->sta_list; sta; sta = sta->next) {
1391 if (hostapd_maclist_found(hapd->conf->deny_mac,
1392 hapd->conf->num_deny_mac, sta->addr,
1393 &vlan_id) &&
1394 (!vlan_id.notempty ||
1395 !vlan_compare(&vlan_id, sta->vlan_desc)))
1396 ap_sta_disconnect(hapd, sta, sta->addr,
1397 WLAN_REASON_UNSPECIFIED);
1398 }
1399}
1400
1401
1402static int hostapd_ctrl_iface_set_band(struct hostapd_data *hapd,1167static int hostapd_ctrl_iface_set_band(struct hostapd_data *hapd,
1403 const char *bands)1168 const char *bands)
1404{1169{
@@ -1519,6 +1284,9 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
1519 } else if (os_strcasecmp(cmd, "dpp_configurator_params") == 0) {1284 } else if (os_strcasecmp(cmd, "dpp_configurator_params") == 0) {
1520 os_free(hapd->dpp_configurator_params);1285 os_free(hapd->dpp_configurator_params);
1521 hapd->dpp_configurator_params = os_strdup(value);1286 hapd->dpp_configurator_params = os_strdup(value);
1287#ifdef CONFIG_DPP2
1288 dpp_controller_set_params(hapd->iface->interfaces->dpp, value);
1289#endif /* CONFIG_DPP2 */
1522 } else if (os_strcasecmp(cmd, "dpp_init_max_tries") == 0) {1290 } else if (os_strcasecmp(cmd, "dpp_init_max_tries") == 0) {
1523 hapd->dpp_init_max_tries = atoi(value);1291 hapd->dpp_init_max_tries = atoi(value);
1524 } else if (os_strcasecmp(cmd, "dpp_init_retry_time") == 0) {1292 } else if (os_strcasecmp(cmd, "dpp_init_retry_time") == 0) {
@@ -1541,6 +1309,8 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
1541 hostapd_disassoc_deny_mac(hapd);1309 hostapd_disassoc_deny_mac(hapd);
1542 } else if (os_strcasecmp(cmd, "accept_mac_file") == 0) {1310 } else if (os_strcasecmp(cmd, "accept_mac_file") == 0) {
1543 hostapd_disassoc_accept_mac(hapd);1311 hostapd_disassoc_accept_mac(hapd);
1312 } else if (os_strcasecmp(cmd, "ssid") == 0) {
1313 hostapd_neighbor_sync_own_report(hapd);
1544 } else if (os_strncmp(cmd, "wme_ac_", 7) == 0 ||1314 } else if (os_strncmp(cmd, "wme_ac_", 7) == 0 ||
1545 os_strncmp(cmd, "wmm_ac_", 7) == 0) {1315 os_strncmp(cmd, "wmm_ac_", 7) == 0) {
1546 hapd->parameter_set_count++;1316 hapd->parameter_set_count++;
@@ -1627,6 +1397,16 @@ static int hostapd_ctrl_iface_reload(struct hostapd_iface *iface)
1627}1397}
16281398
16291399
1400static int hostapd_ctrl_iface_reload_bss(struct hostapd_data *bss)
1401{
1402 if (hostapd_reload_bss_only(bss) < 0) {
1403 wpa_printf(MSG_ERROR, "Reloading of BSS failed");
1404 return -1;
1405 }
1406 return 0;
1407}
1408
1409
1630static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)1410static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
1631{1411{
1632 if (hostapd_disable_iface(iface) < 0) {1412 if (hostapd_disable_iface(iface) < 0) {
@@ -1655,7 +1435,7 @@ hostapd_ctrl_iface_kick_mismatch_psk_sta_iter(struct hostapd_data *hapd,
1655 pmk_match = PMK_LEN == pmk_len &&1435 pmk_match = PMK_LEN == pmk_len &&
1656 os_memcmp(psk->psk, pmk, pmk_len) == 0;1436 os_memcmp(psk->psk, pmk, pmk_len) == 0;
1657 sta_match = psk->group == 0 &&1437 sta_match = psk->group == 0 &&
1658 os_memcmp(sta->addr, psk->addr, ETH_ALEN) == 0;1438 ether_addr_equal(sta->addr, psk->addr);
1659 bss_match = psk->group == 1;1439 bss_match = psk->group == 1;
16601440
1661 if (pmk_match && (sta_match || bss_match))1441 if (pmk_match && (sta_match || bss_match))
@@ -1694,6 +1474,79 @@ static int hostapd_ctrl_iface_reload_wpa_psk(struct hostapd_data *hapd)
1694}1474}
16951475
16961476
1477#ifdef CONFIG_IEEE80211R_AP
1478
1479static int hostapd_ctrl_iface_get_rxkhs(struct hostapd_data *hapd,
1480 char *buf, size_t buflen)
1481{
1482 int ret, start_pos;
1483 char *pos, *end;
1484 struct ft_remote_r0kh *r0kh;
1485 struct ft_remote_r1kh *r1kh;
1486 struct hostapd_bss_config *conf = hapd->conf;
1487
1488 pos = buf;
1489 end = buf + buflen;
1490
1491 for (r0kh = conf->r0kh_list; r0kh; r0kh=r0kh->next) {
1492 start_pos = pos - buf;
1493 ret = os_snprintf(pos, end - pos, "r0kh=" MACSTR " ",
1494 MAC2STR(r0kh->addr));
1495 if (os_snprintf_error(end - pos, ret))
1496 return start_pos;
1497 pos += ret;
1498 if (r0kh->id_len + 1 >= (size_t) (end - pos))
1499 return start_pos;
1500 os_memcpy(pos, r0kh->id, r0kh->id_len);
1501 pos += r0kh->id_len;
1502 *pos++ = ' ';
1503 pos += wpa_snprintf_hex(pos, end - pos, r0kh->key,
1504 sizeof(r0kh->key));
1505 ret = os_snprintf(pos, end - pos, "\n");
1506 if (os_snprintf_error(end - pos, ret))
1507 return start_pos;
1508 pos += ret;
1509 }
1510
1511 for (r1kh = conf->r1kh_list; r1kh; r1kh=r1kh->next) {
1512 start_pos = pos - buf;
1513 ret = os_snprintf(pos, end - pos, "r1kh=" MACSTR " " MACSTR " ",
1514 MAC2STR(r1kh->addr), MAC2STR(r1kh->id));
1515 if (os_snprintf_error(end - pos, ret))
1516 return start_pos;
1517 pos += ret;
1518 pos += wpa_snprintf_hex(pos, end - pos, r1kh->key,
1519 sizeof(r1kh->key));
1520 ret = os_snprintf(pos, end - pos, "\n");
1521 if (os_snprintf_error(end - pos, ret))
1522 return start_pos;
1523 pos += ret;
1524 }
1525
1526 return pos - buf;
1527}
1528
1529
1530static int hostapd_ctrl_iface_reload_rxkhs(struct hostapd_data *hapd)
1531{
1532 struct hostapd_bss_config *conf = hapd->conf;
1533 int err;
1534
1535 hostapd_config_clear_rxkhs(conf);
1536
1537 err = hostapd_config_read_rxkh_file(conf, conf->rxkh_file);
1538 if (err < 0) {
1539 wpa_printf(MSG_ERROR, "Reloading RxKHs failed: %d",
1540 err);
1541 return -1;
1542 }
1543
1544 return 0;
1545}
1546
1547#endif /* CONFIG_IEEE80211R_AP */
1548
1549
1697#ifdef CONFIG_TESTING_OPTIONS1550#ifdef CONFIG_TESTING_OPTIONS
16981551
1699static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)1552static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
@@ -1945,7 +1798,7 @@ static int hostapd_ctrl_iface_eapol_rx(struct hostapd_data *hapd, char *cmd)
1945 return -1;1798 return -1;
1946 }1799 }
19471800
1948 ieee802_1x_receive(hapd, src, buf, len);1801 ieee802_1x_receive(hapd, src, buf, len, FRAME_ENCRYPTION_UNKNOWN);
1949 os_free(buf);1802 os_free(buf);
19501803
1951 return 0;1804 return 0;
@@ -2068,6 +1921,7 @@ static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
2068 int enabled = atoi(cmd);1921 int enabled = atoi(cmd);
2069 char *pos;1922 char *pos;
2070 const char *ifname;1923 const char *ifname;
1924 const u8 *addr = hapd->own_addr;
20711925
2072 if (!enabled) {1926 if (!enabled) {
2073 if (hapd->l2_test) {1927 if (hapd->l2_test) {
@@ -2088,7 +1942,11 @@ static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
2088 else1942 else
2089 ifname = hapd->conf->iface;1943 ifname = hapd->conf->iface;
20901944
2091 hapd->l2_test = l2_packet_init(ifname, hapd->own_addr,1945#ifdef CONFIG_IEEE80211BE
1946 if (hapd->conf->mld_ap)
1947 addr = hapd->mld->mld_addr;
1948#endif /* CONFIG_IEEE80211BE */
1949 hapd->l2_test = l2_packet_init(ifname, addr,
2092 ETHERTYPE_IP, hostapd_data_test_rx,1950 ETHERTYPE_IP, hostapd_data_test_rx,
2093 hapd, 1);1951 hapd, 1);
2094 if (hapd->l2_test == NULL)1952 if (hapd->l2_test == NULL)
@@ -2225,74 +2083,6 @@ done:
2225}2083}
22262084
22272085
2228static int hostapd_ctrl_test_alloc_fail(struct hostapd_data *hapd, char *cmd)
2229{
2230#ifdef WPA_TRACE_BFD
2231 char *pos;
2232
2233 wpa_trace_fail_after = atoi(cmd);
2234 pos = os_strchr(cmd, ':');
2235 if (pos) {
2236 pos++;
2237 os_strlcpy(wpa_trace_fail_func, pos,
2238 sizeof(wpa_trace_fail_func));
2239 } else {
2240 wpa_trace_fail_after = 0;
2241 }
2242
2243 return 0;
2244#else /* WPA_TRACE_BFD */
2245 return -1;
2246#endif /* WPA_TRACE_BFD */
2247}
2248
2249
2250static int hostapd_ctrl_get_alloc_fail(struct hostapd_data *hapd,
2251 char *buf, size_t buflen)
2252{
2253#ifdef WPA_TRACE_BFD
2254 return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
2255 wpa_trace_fail_func);
2256#else /* WPA_TRACE_BFD */
2257 return -1;
2258#endif /* WPA_TRACE_BFD */
2259}
2260
2261
2262static int hostapd_ctrl_test_fail(struct hostapd_data *hapd, char *cmd)
2263{
2264#ifdef WPA_TRACE_BFD
2265 char *pos;
2266
2267 wpa_trace_test_fail_after = atoi(cmd);
2268 pos = os_strchr(cmd, ':');
2269 if (pos) {
2270 pos++;
2271 os_strlcpy(wpa_trace_test_fail_func, pos,
2272 sizeof(wpa_trace_test_fail_func));
2273 } else {
2274 wpa_trace_test_fail_after = 0;
2275 }
2276
2277 return 0;
2278#else /* WPA_TRACE_BFD */
2279 return -1;
2280#endif /* WPA_TRACE_BFD */
2281}
2282
2283
2284static int hostapd_ctrl_get_fail(struct hostapd_data *hapd,
2285 char *buf, size_t buflen)
2286{
2287#ifdef WPA_TRACE_BFD
2288 return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after,
2289 wpa_trace_test_fail_func);
2290#else /* WPA_TRACE_BFD */
2291 return -1;
2292#endif /* WPA_TRACE_BFD */
2293}
2294
2295
2296static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)2086static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
2297{2087{
2298 struct sta_info *sta;2088 struct sta_info *sta;
@@ -2664,8 +2454,46 @@ static int hostapd_ctrl_register_frame(struct hostapd_data *hapd,
26642454
26652455
2666#ifdef NEED_AP_MLME2456#ifdef NEED_AP_MLME
2667static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)2457static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
2458 u16 punct_bitmap)
2668{2459{
2460 u32 start_freq;
2461
2462 if (is_6ghz_freq(params->freq)) {
2463 const int bw_idx[] = { 20, 40, 80, 160, 320 };
2464 int idx, bw;
2465
2466 /* The 6 GHz band requires HE to be enabled. */
2467 params->he_enabled = 1;
2468
2469 if (params->center_freq1) {
2470 if (params->freq == 5935)
2471 idx = (params->center_freq1 - 5925) / 5;
2472 else
2473 idx = (params->center_freq1 - 5950) / 5;
2474
2475 bw = center_idx_to_bw_6ghz(idx);
2476 if (bw < 0 || bw > (int) ARRAY_SIZE(bw_idx) ||
2477 bw_idx[bw] != params->bandwidth)
2478 return -1;
2479 }
2480 } else { /* Non-6 GHz channel */
2481 /* An EHT STA is also an HE STA as defined in
2482 * IEEE P802.11be/D5.0, 4.3.16a. */
2483 if (params->he_enabled || params->eht_enabled) {
2484 params->he_enabled = 1;
2485 /* An HE STA is also a VHT STA if operating in the 5 GHz
2486 * band and an HE STA is also an HT STA in the 2.4 GHz
2487 * band as defined in IEEE Std 802.11ax-2021, 4.3.15a.
2488 * A VHT STA is an HT STA as defined in IEEE
2489 * Std 802.11, 4.3.15. */
2490 if (IS_5GHZ(params->freq))
2491 params->vht_enabled = 1;
2492
2493 params->ht_enabled = 1;
2494 }
2495 }
2496
2669 switch (params->bandwidth) {2497 switch (params->bandwidth) {
2670 case 0:2498 case 0:
2671 /* bandwidth not specified: use 20 MHz by default */2499 /* bandwidth not specified: use 20 MHz by default */
@@ -2677,11 +2505,17 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
26772505
2678 if (params->center_freq2 || params->sec_channel_offset)2506 if (params->center_freq2 || params->sec_channel_offset)
2679 return -1;2507 return -1;
2680 break;2508
2509 if (punct_bitmap)
2510 return -1;
2511 break;
2681 case 40:2512 case 40:
2682 if (params->center_freq2 || !params->sec_channel_offset)2513 if (params->center_freq2 || !params->sec_channel_offset)
2683 return -1;2514 return -1;
26842515
2516 if (punct_bitmap)
2517 return -1;
2518
2685 if (!params->center_freq1)2519 if (!params->center_freq1)
2686 break;2520 break;
2687 switch (params->sec_channel_offset) {2521 switch (params->sec_channel_offset) {
@@ -2716,6 +2550,9 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
2716 return -1;2550 return -1;
2717 }2551 }
27182552
2553 if (params->center_freq2 && punct_bitmap)
2554 return -1;
2555
2719 /* Adjacent and overlapped are not allowed for 80+80 */2556 /* Adjacent and overlapped are not allowed for 80+80 */
2720 if (params->center_freq2 &&2557 if (params->center_freq2 &&
2721 params->center_freq1 - params->center_freq2 <= 80 &&2558 params->center_freq1 - params->center_freq2 <= 80 &&
@@ -2746,10 +2583,63 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
2746 return -1;2583 return -1;
2747 }2584 }
2748 break;2585 break;
2586 case 320:
2587 if (!params->center_freq1 || params->center_freq2 ||
2588 !params->sec_channel_offset)
2589 return -1;
2590
2591 switch (params->sec_channel_offset) {
2592 case 1:
2593 if (params->freq + 150 != params->center_freq1 &&
2594 params->freq + 110 != params->center_freq1 &&
2595 params->freq + 70 != params->center_freq1 &&
2596 params->freq + 30 != params->center_freq1 &&
2597 params->freq - 10 != params->center_freq1 &&
2598 params->freq - 50 != params->center_freq1 &&
2599 params->freq - 90 != params->center_freq1 &&
2600 params->freq - 130 != params->center_freq1)
2601 return -1;
2602 break;
2603 case -1:
2604 if (params->freq + 130 != params->center_freq1 &&
2605 params->freq + 90 != params->center_freq1 &&
2606 params->freq + 50 != params->center_freq1 &&
2607 params->freq + 10 != params->center_freq1 &&
2608 params->freq - 30 != params->center_freq1 &&
2609 params->freq - 70 != params->center_freq1 &&
2610 params->freq - 110 != params->center_freq1 &&
2611 params->freq - 150 != params->center_freq1)
2612 return -1;
2613 break;
2614 }
2615 break;
2749 default:2616 default:
2750 return -1;2617 return -1;
2751 }2618 }
27522619
2620 if (!punct_bitmap)
2621 return 0;
2622
2623 if (!params->eht_enabled) {
2624 wpa_printf(MSG_ERROR,
2625 "Preamble puncturing supported only in EHT");
2626 return -1;
2627 }
2628
2629 if (params->freq >= 2412 && params->freq <= 2484) {
2630 wpa_printf(MSG_ERROR,
2631 "Preamble puncturing is not supported in 2.4 GHz");
2632 return -1;
2633 }
2634
2635 start_freq = params->center_freq1 - (params->bandwidth / 2);
2636 if (!is_punct_bitmap_valid(params->bandwidth,
2637 (params->freq - start_freq) / 20,
2638 punct_bitmap)) {
2639 wpa_printf(MSG_ERROR, "Invalid preamble puncturing bitmap");
2640 return -1;
2641 }
2642
2753 return 0;2643 return 0;
2754}2644}
2755#endif /* NEED_AP_MLME */2645#endif /* NEED_AP_MLME */
@@ -2765,12 +2655,21 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
2765 unsigned int i;2655 unsigned int i;
2766 int bandwidth;2656 int bandwidth;
2767 u8 chan;2657 u8 chan;
2658 unsigned int num_err = 0;
2659 int err = 0;
27682660
2769 ret = hostapd_parse_csa_settings(pos, &settings);2661 ret = hostapd_parse_csa_settings(pos, &settings);
2770 if (ret)2662 if (ret)
2771 return ret;2663 return ret;
27722664
2773 ret = hostapd_ctrl_check_freq_params(&settings.freq_params);2665 settings.link_id = -1;
2666#ifdef CONFIG_IEEE80211BE
2667 if (iface->num_bss && iface->bss[0]->conf->mld_ap)
2668 settings.link_id = iface->bss[0]->mld_link_id;
2669#endif /* CONFIG_IEEE80211BE */
2670
2671 ret = hostapd_ctrl_check_freq_params(&settings.freq_params,
2672 settings.punct_bitmap);
2774 if (ret) {2673 if (ret) {
2775 wpa_printf(MSG_INFO,2674 wpa_printf(MSG_INFO,
2776 "chanswitch: invalid frequency settings provided");2675 "chanswitch: invalid frequency settings provided");
@@ -2790,6 +2689,9 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
2790 case 160:2689 case 160:
2791 bandwidth = CHAN_WIDTH_160;2690 bandwidth = CHAN_WIDTH_160;
2792 break;2691 break;
2692 case 320:
2693 bandwidth = CHAN_WIDTH_320;
2694 break;
2793 default:2695 default:
2794 bandwidth = CHAN_WIDTH_20;2696 bandwidth = CHAN_WIDTH_20;
2795 break;2697 break;
@@ -2828,29 +2730,271 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
2828 settings.freq_params.center_freq1);2730 settings.freq_params.center_freq1);
28292731
2830 /* Perform CAC and switch channel */2732 /* Perform CAC and switch channel */
2733 iface->is_ch_switch_dfs = true;
2831 hostapd_switch_channel_fallback(iface, &settings.freq_params);2734 hostapd_switch_channel_fallback(iface, &settings.freq_params);
2832 return 0;2735 return 0;
2833 }2736 }
28342737
2835 for (i = 0; i < iface->num_bss; i++) {2738 for (i = 0; i < iface->num_bss; i++) {
28362739
2837 /* Save CHAN_SWITCH VHT and HE config */2740 /* Save CHAN_SWITCH VHT, HE, and EHT config */
2838 hostapd_chan_switch_config(iface->bss[i],2741 hostapd_chan_switch_config(iface->bss[i],
2839 &settings.freq_params);2742 &settings.freq_params);
28402743
2841 ret = hostapd_switch_channel(iface->bss[i], &settings);2744 err = hostapd_switch_channel(iface->bss[i], &settings);
2842 if (ret) {2745 if (err) {
2843 /* FIX: What do we do if CSA fails in the middle of2746 ret = err;
2844 * submitting multi-BSS CSA requests? */2747 num_err++;
2845 return ret;
2846 }2748 }
2847 }2749 }
28482750
2751 return (iface->num_bss == num_err) ? ret : 0;
2752#else /* NEED_AP_MLME */
2753 return -1;
2754#endif /* NEED_AP_MLME */
2755}
2756
2757
2758#ifdef CONFIG_IEEE80211AX
2759static int hostapd_ctrl_iface_color_change(struct hostapd_iface *iface,
2760 const char *pos)
2761{
2762#ifdef NEED_AP_MLME
2763 struct cca_settings settings;
2764 struct hostapd_data *hapd = iface->bss[0];
2765 int ret, color;
2766 unsigned int i;
2767 char *end;
2768
2769 os_memset(&settings, 0, sizeof(settings));
2770
2771 color = strtol(pos, &end, 10);
2772 if (pos == end || color < 0 || color > 63) {
2773 wpa_printf(MSG_ERROR, "color_change: Invalid color provided");
2774 return -1;
2775 }
2776
2777 /* Color value is expected to be [1-63]. If 0 comes, assumption is this
2778 * is to disable the color. In this case no need to do CCA, just
2779 * changing Beacon frames is sufficient. */
2780 if (color == 0) {
2781 if (iface->conf->he_op.he_bss_color_disabled) {
2782 wpa_printf(MSG_ERROR,
2783 "color_change: Color is already disabled");
2784 return -1;
2785 }
2786
2787 iface->conf->he_op.he_bss_color_disabled = 1;
2788
2789 for (i = 0; i < iface->num_bss; i++)
2790 ieee802_11_set_beacon(iface->bss[i]);
2791
2792 return 0;
2793 }
2794
2795 if (color == iface->conf->he_op.he_bss_color) {
2796 if (!iface->conf->he_op.he_bss_color_disabled) {
2797 wpa_printf(MSG_ERROR,
2798 "color_change: Provided color is already set");
2799 return -1;
2800 }
2801
2802 iface->conf->he_op.he_bss_color_disabled = 0;
2803
2804 for (i = 0; i < iface->num_bss; i++)
2805 ieee802_11_set_beacon(iface->bss[i]);
2806
2807 return 0;
2808 }
2809
2810 if (hapd->cca_in_progress) {
2811 wpa_printf(MSG_ERROR,
2812 "color_change: CCA is already in progress");
2813 return -1;
2814 }
2815
2816 iface->conf->he_op.he_bss_color_disabled = 0;
2817
2818 for (i = 0; i < iface->num_bss; i++) {
2819 struct hostapd_data *bss = iface->bss[i];
2820
2821 hostapd_cleanup_cca_params(bss);
2822
2823 bss->cca_color = color;
2824 bss->cca_count = 10;
2825
2826 if (hostapd_fill_cca_settings(bss, &settings)) {
2827 wpa_printf(MSG_DEBUG,
2828 "color_change: Filling CCA settings failed for color: %d\n",
2829 color);
2830 hostapd_cleanup_cca_params(bss);
2831 continue;
2832 }
2833
2834 wpa_printf(MSG_DEBUG, "Setting user selected color: %d", color);
2835 ret = hostapd_drv_switch_color(bss, &settings);
2836 if (ret)
2837 hostapd_cleanup_cca_params(bss);
2838
2839 free_beacon_data(&settings.beacon_cca);
2840 free_beacon_data(&settings.beacon_after);
2841 }
2842
2849 return 0;2843 return 0;
2850#else /* NEED_AP_MLME */2844#else /* NEED_AP_MLME */
2851 return -1;2845 return -1;
2852#endif /* NEED_AP_MLME */2846#endif /* NEED_AP_MLME */
2853}2847}
2848#endif /* CONFIG_IEEE80211AX */
2849
2850
2851static u8 hostapd_maxnss(struct hostapd_data *hapd, struct sta_info *sta)
2852{
2853 u8 *mcs_set = NULL;
2854 u16 mcs_map;
2855 u8 ht_rx_nss = 0;
2856 u8 vht_rx_nss = 1;
2857 u8 mcs;
2858 bool ht_supported = false;
2859 bool vht_supported = false;
2860 int i;
2861
2862 if (sta->ht_capabilities && (sta->flags & WLAN_STA_HT)) {
2863 mcs_set = sta->ht_capabilities->supported_mcs_set;
2864 ht_supported = true;
2865 }
2866
2867 if (sta->vht_capabilities && (sta->flags & WLAN_STA_VHT)) {
2868 mcs_map = le_to_host16(
2869 sta->vht_capabilities->vht_supported_mcs_set.rx_map);
2870 vht_supported = true;
2871 }
2872
2873 if (ht_supported && mcs_set) {
2874 if (mcs_set[0])
2875 ht_rx_nss++;
2876 if (mcs_set[1])
2877 ht_rx_nss++;
2878 if (mcs_set[2])
2879 ht_rx_nss++;
2880 if (mcs_set[3])
2881 ht_rx_nss++;
2882 }
2883 if (vht_supported) {
2884 for (i = 7; i >= 0; i--) {
2885 mcs = (mcs_map >> (2 * i)) & 0x03;
2886 if (mcs != 0x03) {
2887 vht_rx_nss = i + 1;
2888 break;
2889 }
2890 }
2891 }
2892
2893 return ht_rx_nss > vht_rx_nss ? ht_rx_nss : vht_rx_nss;
2894}
2895
2896
2897static char hostapd_ctrl_iface_notify_cw_htaction(struct hostapd_data *hapd,
2898 const u8 *addr, u8 width)
2899{
2900 u8 buf[3];
2901 char ret;
2902
2903 width = width >= 1 ? 1 : 0;
2904
2905 buf[0] = WLAN_ACTION_HT;
2906 buf[1] = WLAN_HT_ACTION_NOTIFY_CHANWIDTH;
2907 buf[2] = width;
2908
2909 ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
2910 buf, sizeof(buf));
2911 if (ret)
2912 wpa_printf(MSG_DEBUG,
2913 "Failed to send Notify Channel Width frame to "
2914 MACSTR, MAC2STR(addr));
2915
2916 return ret;
2917}
2918
2919
2920static char hostapd_ctrl_iface_notify_cw_vhtaction(struct hostapd_data *hapd,
2921 const u8 *addr, u8 width)
2922{
2923 u8 buf[3];
2924 char ret;
2925
2926 buf[0] = WLAN_ACTION_VHT;
2927 buf[1] = WLAN_VHT_ACTION_OPMODE_NOTIF;
2928 buf[2] = width;
2929
2930 ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
2931 buf, sizeof(buf));
2932 if (ret)
2933 wpa_printf(MSG_DEBUG,
2934 "Failed to send Opeating Mode Notification frame to "
2935 MACSTR, MAC2STR(addr));
2936
2937 return ret;
2938}
2939
2940
2941static char hostapd_ctrl_iface_notify_cw_change(struct hostapd_data *hapd,
2942 const char *cmd)
2943{
2944 u8 cw, operating_mode = 0, nss;
2945 struct sta_info *sta;
2946 enum hostapd_hw_mode hw_mode;
2947
2948 if (is_6ghz_freq(hapd->iface->freq)) {
2949 wpa_printf(MSG_ERROR, "20/40 BSS coex not supported in 6 GHz");
2950 return -1;
2951 }
2952
2953 cw = atoi(cmd);
2954 hw_mode = hapd->iface->current_mode->mode;
2955 if ((hw_mode == HOSTAPD_MODE_IEEE80211G ||
2956 hw_mode == HOSTAPD_MODE_IEEE80211B) &&
2957 !(cw == 0 || cw == 1)) {
2958 wpa_printf(MSG_ERROR,
2959 "Channel width should be either 20 MHz or 40 MHz for 2.4 GHz band");
2960 return -1;
2961 }
2962
2963 switch (cw) {
2964 case 0:
2965 operating_mode = 0;
2966 break;
2967 case 1:
2968 operating_mode = VHT_OPMODE_CHANNEL_40MHZ;
2969 break;
2970 case 2:
2971 operating_mode = VHT_OPMODE_CHANNEL_80MHZ;
2972 break;
2973 case 3:
2974 operating_mode = VHT_OPMODE_CHANNEL_160MHZ;
2975 break;
2976 default:
2977 wpa_printf(MSG_ERROR, "Channel width should be between 0 to 3");
2978 return -1;
2979 }
2980
2981 for (sta = hapd->sta_list; sta; sta = sta->next) {
2982 if ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) {
2983 nss = hostapd_maxnss(hapd, sta) - 1;
2984 hostapd_ctrl_iface_notify_cw_vhtaction(hapd, sta->addr,
2985 operating_mode |
2986 (u8) (nss << 4));
2987 continue;
2988 }
2989
2990 if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) ==
2991 WLAN_STA_HT && sta->ht_capabilities)
2992 hostapd_ctrl_iface_notify_cw_htaction(hapd, sta->addr,
2993 cw);
2994 }
2995
2996 return 0;
2997}
28542998
28552999
2856static int hostapd_ctrl_iface_mib(struct hostapd_data *hapd, char *reply,3000static int hostapd_ctrl_iface_mib(struct hostapd_data *hapd, char *reply,
@@ -3171,6 +3315,26 @@ static int hostapd_ctrl_iface_req_beacon(struct hostapd_data *hapd,
3171}3315}
31723316
31733317
3318static int hostapd_ctrl_iface_req_link_measurement(struct hostapd_data *hapd,
3319 const char *cmd, char *reply,
3320 size_t reply_size)
3321{
3322 u8 addr[ETH_ALEN];
3323 int ret;
3324
3325 if (hwaddr_aton(cmd, addr)) {
3326 wpa_printf(MSG_ERROR,
3327 "CTRL: REQ_LINK_MEASUREMENT: Invalid MAC address");
3328 return -1;
3329 }
3330
3331 ret = hostapd_send_link_measurement_req(hapd, addr);
3332 if (ret >= 0)
3333 ret = os_snprintf(reply, reply_size, "%d", ret);
3334 return ret;
3335}
3336
3337
3174static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd,3338static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd,
3175 char *buf, size_t buflen)3339 char *buf, size_t buflen)
3176{3340{
@@ -3379,80 +3543,6 @@ static int hostapd_ctrl_driver_flags2(struct hostapd_iface *iface, char *buf,
3379}3543}
33803544
33813545
3382static int hostapd_ctrl_iface_acl_del_mac(struct mac_acl_entry **acl, int *num,
3383 const char *txtaddr)
3384{
3385 u8 addr[ETH_ALEN];
3386 struct vlan_description vlan_id;
3387
3388 if (!(*num))
3389 return 0;
3390
3391 if (hwaddr_aton(txtaddr, addr))
3392 return -1;
3393
3394 if (hostapd_maclist_found(*acl, *num, addr, &vlan_id))
3395 hostapd_remove_acl_mac(acl, num, addr);
3396
3397 return 0;
3398}
3399
3400
3401static void hostapd_ctrl_iface_acl_clear_list(struct mac_acl_entry **acl,
3402 int *num)
3403{
3404 while (*num)
3405 hostapd_remove_acl_mac(acl, num, (*acl)[0].addr);
3406}
3407
3408
3409static int hostapd_ctrl_iface_acl_show_mac(struct mac_acl_entry *acl, int num,
3410 char *buf, size_t buflen)
3411{
3412 int i = 0, len = 0, ret = 0;
3413
3414 if (!acl)
3415 return 0;
3416
3417 while (i < num) {
3418 ret = os_snprintf(buf + len, buflen - len,
3419 MACSTR " VLAN_ID=%d\n",
3420 MAC2STR(acl[i].addr),
3421 acl[i].vlan_id.untagged);
3422 if (ret < 0 || (size_t) ret >= buflen - len)
3423 return len;
3424 i++;
3425 len += ret;
3426 }
3427 return len;
3428}
3429
3430
3431static int hostapd_ctrl_iface_acl_add_mac(struct mac_acl_entry **acl, int *num,
3432 const char *cmd)
3433{
3434 u8 addr[ETH_ALEN];
3435 struct vlan_description vlan_id;
3436 int ret = 0, vlanid = 0;
3437 const char *pos;
3438
3439 if (hwaddr_aton(cmd, addr))
3440 return -1;
3441
3442 pos = os_strstr(cmd, "VLAN_ID=");
3443 if (pos)
3444 vlanid = atoi(pos + 8);
3445
3446 if (!hostapd_maclist_found(*acl, *num, addr, &vlan_id)) {
3447 ret = hostapd_add_acl_maclist(acl, num, vlanid, addr);
3448 if (ret != -1 && *acl)
3449 qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
3450 }
3451
3452 return ret < 0 ? -1 : 0;
3453}
3454
3455
3456static int hostapd_ctrl_iface_get_capability(struct hostapd_data *hapd,3546static int hostapd_ctrl_iface_get_capability(struct hostapd_data *hapd,
3457 const char *field, char *buf,3547 const char *field, char *buf,
3458 size_t buflen)3548 size_t buflen)
@@ -3500,6 +3590,395 @@ static int hostapd_ctrl_iface_driver_cmd(struct hostapd_data *hapd, char *cmd,
3500#endif /* ANDROID */3590#endif /* ANDROID */
35013591
35023592
3593#ifdef CONFIG_IEEE80211BE
3594
3595static int hostapd_ctrl_iface_enable_mld(struct hostapd_iface *iface)
3596{
3597 unsigned int i;
3598
3599 if (!iface || !iface->bss[0]->conf->mld_ap) {
3600 wpa_printf(MSG_ERROR,
3601 "Trying to enable AP MLD on an interface that is not affiliated with an AP MLD");
3602 return -1;
3603 }
3604
3605 for (i = 0; i < iface->interfaces->count; ++i) {
3606 struct hostapd_iface *h_iface = iface->interfaces->iface[i];
3607 struct hostapd_data *h_hapd = h_iface->bss[0];
3608
3609 if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
3610 continue;
3611
3612 if (hostapd_enable_iface(h_iface)) {
3613 wpa_printf(MSG_ERROR, "Enabling of AP MLD failed");
3614 return -1;
3615 }
3616 }
3617 return 0;
3618}
3619
3620
3621static void hostapd_disable_iface_bss(struct hostapd_iface *iface)
3622{
3623 unsigned int i;
3624
3625 for (i = 0; i < iface->num_bss; i++)
3626 hostapd_bss_deinit_no_free(iface->bss[i]);
3627}
3628
3629
3630static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
3631{
3632 unsigned int i;
3633
3634 if (!iface || !iface->bss[0]->conf->mld_ap) {
3635 wpa_printf(MSG_ERROR,
3636 "Trying to disable AP MLD on an interface that is not affiliated with an AP MLD.");
3637 return -1;
3638 }
3639
3640 /* First, disable BSSs before stopping beaconing and doing driver
3641 * deinit so that the broadcast Deauthentication frames go out. */
3642
3643 for (i = 0; i < iface->interfaces->count; ++i) {
3644 struct hostapd_iface *h_iface = iface->interfaces->iface[i];
3645 struct hostapd_data *h_hapd = h_iface->bss[0];
3646
3647 if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
3648 continue;
3649
3650 hostapd_disable_iface_bss(iface);
3651 }
3652
3653 /* Then, fully disable interfaces */
3654 for (i = 0; i < iface->interfaces->count; ++i) {
3655 struct hostapd_iface *h_iface = iface->interfaces->iface[i];
3656 struct hostapd_data *h_hapd = h_iface->bss[0];
3657
3658 if (!hostapd_is_ml_partner(h_hapd, iface->bss[0]))
3659 continue;
3660
3661 if (hostapd_disable_iface(h_iface)) {
3662 wpa_printf(MSG_ERROR, "Disabling AP MLD failed");
3663 return -1;
3664 }
3665 }
3666
3667 return 0;
3668}
3669
3670
3671#ifdef CONFIG_TESTING_OPTIONS
3672static int hostapd_ctrl_iface_link_remove(struct hostapd_data *hapd, char *cmd,
3673 char *buf, size_t buflen)
3674{
3675 int ret;
3676 u32 count = atoi(cmd);
3677
3678 if (!count)
3679 count = 1;
3680
3681 ret = hostapd_link_remove(hapd, count);
3682 if (ret == 0) {
3683 ret = os_snprintf(buf, buflen, "%s\n", "OK");
3684 if (os_snprintf_error(buflen, ret))
3685 ret = -1;
3686 else
3687 ret = 0;
3688 }
3689
3690 return ret;
3691}
3692#endif /* CONFIG_TESTING_OPTIONS */
3693#endif /* CONFIG_IEEE80211BE */
3694
3695
3696#ifdef CONFIG_NAN_USD
3697
3698static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
3699 char *buf, size_t buflen)
3700{
3701 char *token, *context = NULL;
3702 int publish_id;
3703 struct nan_publish_params params;
3704 const char *service_name = NULL;
3705 struct wpabuf *ssi = NULL;
3706 int ret = -1;
3707 enum nan_service_protocol_type srv_proto_type = 0;
3708
3709 os_memset(&params, 0, sizeof(params));
3710 /* USD shall use both solicited and unsolicited transmissions */
3711 params.unsolicited = true;
3712 params.solicited = true;
3713 /* USD shall require FSD without GAS */
3714 params.fsd = true;
3715
3716 while ((token = str_token(cmd, " ", &context))) {
3717 if (os_strncmp(token, "service_name=", 13) == 0) {
3718 service_name = token + 13;
3719 continue;
3720 }
3721
3722 if (os_strncmp(token, "ttl=", 4) == 0) {
3723 params.ttl = atoi(token + 4);
3724 continue;
3725 }
3726
3727 if (os_strncmp(token, "srv_proto_type=", 15) == 0) {
3728 srv_proto_type = atoi(token + 15);
3729 continue;
3730 }
3731
3732 if (os_strncmp(token, "ssi=", 4) == 0) {
3733 if (ssi)
3734 goto fail;
3735 ssi = wpabuf_parse_bin(token + 4);
3736 if (!ssi)
3737 goto fail;
3738 continue;
3739 }
3740
3741 if (os_strcmp(token, "solicited=0") == 0) {
3742 params.solicited = false;
3743 continue;
3744 }
3745
3746 if (os_strcmp(token, "unsolicited=0") == 0) {
3747 params.unsolicited = false;
3748 continue;
3749 }
3750
3751 if (os_strcmp(token, "fsd=0") == 0) {
3752 params.fsd = false;
3753 continue;
3754 }
3755
3756 wpa_printf(MSG_INFO, "CTRL: Invalid NAN_PUBLISH parameter: %s",
3757 token);
3758 goto fail;
3759 }
3760
3761 publish_id = hostapd_nan_usd_publish(hapd, service_name, srv_proto_type,
3762 ssi, &params);
3763 if (publish_id > 0)
3764 ret = os_snprintf(buf, buflen, "%d", publish_id);
3765fail:
3766 wpabuf_free(ssi);
3767 return ret;
3768}
3769
3770
3771static int hostapd_ctrl_nan_cancel_publish(struct hostapd_data *hapd,
3772 char *cmd)
3773{
3774 char *token, *context = NULL;
3775 int publish_id = 0;
3776
3777 while ((token = str_token(cmd, " ", &context))) {
3778 if (sscanf(token, "publish_id=%i", &publish_id) == 1)
3779 continue;
3780 wpa_printf(MSG_INFO,
3781 "CTRL: Invalid NAN_CANCEL_PUBLISH parameter: %s",
3782 token);
3783 return -1;
3784 }
3785
3786 if (publish_id <= 0) {
3787 wpa_printf(MSG_INFO,
3788 "CTRL: Invalid or missing NAN_CANCEL_PUBLISH publish_id");
3789 return -1;
3790 }
3791
3792 hostapd_nan_usd_cancel_publish(hapd, publish_id);
3793 return 0;
3794}
3795
3796
3797static int hostapd_ctrl_nan_update_publish(struct hostapd_data *hapd,
3798 char *cmd)
3799{
3800 char *token, *context = NULL;
3801 int publish_id = 0;
3802 struct wpabuf *ssi = NULL;
3803 int ret = -1;
3804
3805 while ((token = str_token(cmd, " ", &context))) {
3806 if (sscanf(token, "publish_id=%i", &publish_id) == 1)
3807 continue;
3808 if (os_strncmp(token, "ssi=", 4) == 0) {
3809 if (ssi)
3810 goto fail;
3811 ssi = wpabuf_parse_bin(token + 4);
3812 if (!ssi)
3813 goto fail;
3814 continue;
3815 }
3816 wpa_printf(MSG_INFO,
3817 "CTRL: Invalid NAN_UPDATE_PUBLISH parameter: %s",
3818 token);
3819 goto fail;
3820 }
3821
3822 if (publish_id <= 0) {
3823 wpa_printf(MSG_INFO,
3824 "CTRL: Invalid or missing NAN_UPDATE_PUBLISH publish_id");
3825 goto fail;
3826 }
3827
3828 ret = hostapd_nan_usd_update_publish(hapd, publish_id, ssi);
3829fail:
3830 wpabuf_free(ssi);
3831 return ret;
3832}
3833
3834
3835static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
3836 char *buf, size_t buflen)
3837{
3838 char *token, *context = NULL;
3839 int subscribe_id;
3840 struct nan_subscribe_params params;
3841 const char *service_name = NULL;
3842 struct wpabuf *ssi = NULL;
3843 int ret = -1;
3844 enum nan_service_protocol_type srv_proto_type = 0;
3845
3846 os_memset(&params, 0, sizeof(params));
3847
3848 while ((token = str_token(cmd, " ", &context))) {
3849 if (os_strncmp(token, "service_name=", 13) == 0) {
3850 service_name = token + 13;
3851 continue;
3852 }
3853
3854 if (os_strcmp(token, "active=1") == 0) {
3855 params.active = true;
3856 continue;
3857 }
3858
3859 if (os_strncmp(token, "ttl=", 4) == 0) {
3860 params.ttl = atoi(token + 4);
3861 continue;
3862 }
3863
3864 if (os_strncmp(token, "srv_proto_type=", 15) == 0) {
3865 srv_proto_type = atoi(token + 15);
3866 continue;
3867 }
3868
3869 if (os_strncmp(token, "ssi=", 4) == 0) {
3870 if (ssi)
3871 goto fail;
3872 ssi = wpabuf_parse_bin(token + 4);
3873 if (!ssi)
3874 goto fail;
3875 continue;
3876 }
3877
3878 wpa_printf(MSG_INFO,
3879 "CTRL: Invalid NAN_SUBSCRIBE parameter: %s",
3880 token);
3881 goto fail;
3882 }
3883
3884 subscribe_id = hostapd_nan_usd_subscribe(hapd, service_name,
3885 srv_proto_type, ssi,
3886 &params);
3887 if (subscribe_id > 0)
3888 ret = os_snprintf(buf, buflen, "%d", subscribe_id);
3889fail:
3890 wpabuf_free(ssi);
3891 return ret;
3892}
3893
3894
3895static int hostapd_ctrl_nan_cancel_subscribe(struct hostapd_data *hapd,
3896 char *cmd)
3897{
3898 char *token, *context = NULL;
3899 int subscribe_id = 0;
3900
3901 while ((token = str_token(cmd, " ", &context))) {
3902 if (sscanf(token, "subscribe_id=%i", &subscribe_id) == 1)
3903 continue;
3904 wpa_printf(MSG_INFO,
3905 "CTRL: Invalid NAN_CANCEL_SUBSCRIBE parameter: %s",
3906 token);
3907 return -1;
3908 }
3909
3910 if (subscribe_id <= 0) {
3911 wpa_printf(MSG_INFO,
3912 "CTRL: Invalid or missing NAN_CANCEL_SUBSCRIBE subscribe_id");
3913 return -1;
3914 }
3915
3916 hostapd_nan_usd_cancel_subscribe(hapd, subscribe_id);
3917 return 0;
3918}
3919
3920
3921static int hostapd_ctrl_nan_transmit(struct hostapd_data *hapd, char *cmd)
3922{
3923 char *token, *context = NULL;
3924 int handle = 0;
3925 int req_instance_id = 0;
3926 struct wpabuf *ssi = NULL;
3927 u8 peer_addr[ETH_ALEN];
3928 int ret = -1;
3929
3930 os_memset(peer_addr, 0, ETH_ALEN);
3931
3932 while ((token = str_token(cmd, " ", &context))) {
3933 if (sscanf(token, "handle=%i", &handle) == 1)
3934 continue;
3935
3936 if (sscanf(token, "req_instance_id=%i", &req_instance_id) == 1)
3937 continue;
3938
3939 if (os_strncmp(token, "address=", 8) == 0) {
3940 if (hwaddr_aton(token + 8, peer_addr) < 0)
3941 return -1;
3942 continue;
3943 }
3944
3945 if (os_strncmp(token, "ssi=", 4) == 0) {
3946 if (ssi)
3947 goto fail;
3948 ssi = wpabuf_parse_bin(token + 4);
3949 if (!ssi)
3950 goto fail;
3951 continue;
3952 }
3953
3954 wpa_printf(MSG_INFO,
3955 "CTRL: Invalid NAN_TRANSMIT parameter: %s",
3956 token);
3957 goto fail;
3958 }
3959
3960 if (handle <= 0) {
3961 wpa_printf(MSG_INFO,
3962 "CTRL: Invalid or missing NAN_TRANSMIT handle");
3963 goto fail;
3964 }
3965
3966 if (is_zero_ether_addr(peer_addr)) {
3967 wpa_printf(MSG_INFO,
3968 "CTRL: Invalid or missing NAN_TRANSMIT address");
3969 goto fail;
3970 }
3971
3972 ret = hostapd_nan_usd_transmit(hapd, handle, ssi, NULL, peer_addr,
3973 req_instance_id);
3974fail:
3975 wpabuf_free(ssi);
3976 return ret;
3977}
3978
3979#endif /* CONFIG_NAN_USD */
3980
3981
3503static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,3982static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3504 char *buf, char *reply,3983 char *buf, char *reply,
3505 int reply_size,3984 int reply_size,
@@ -3517,6 +3996,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3517 } else if (os_strncmp(buf, "RELOG", 5) == 0) {3996 } else if (os_strncmp(buf, "RELOG", 5) == 0) {
3518 if (wpa_debug_reopen_file() < 0)3997 if (wpa_debug_reopen_file() < 0)
3519 reply_len = -1;3998 reply_len = -1;
3999 } else if (os_strcmp(buf, "CLOSE_LOG") == 0) {
4000 wpa_debug_stop_log();
3520 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {4001 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
3521 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);4002 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
3522 } else if (os_strcmp(buf, "STATUS") == 0) {4003 } else if (os_strcmp(buf, "STATUS") == 0) {
@@ -3682,16 +4163,30 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3682 } else if (os_strncmp(buf, "GET ", 4) == 0) {4163 } else if (os_strncmp(buf, "GET ", 4) == 0) {
3683 reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply,4164 reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply,
3684 reply_size);4165 reply_size);
3685 } else if (os_strncmp(buf, "ENABLE", 6) == 0) {4166 } else if (os_strcmp(buf, "ENABLE") == 0) {
3686 if (hostapd_ctrl_iface_enable(hapd->iface))4167 if (hostapd_ctrl_iface_enable(hapd->iface))
3687 reply_len = -1;4168 reply_len = -1;
3688 } else if (os_strcmp(buf, "RELOAD_WPA_PSK") == 0) {4169 } else if (os_strcmp(buf, "RELOAD_WPA_PSK") == 0) {
3689 if (hostapd_ctrl_iface_reload_wpa_psk(hapd))4170 if (hostapd_ctrl_iface_reload_wpa_psk(hapd))
3690 reply_len = -1;4171 reply_len = -1;
3691 } else if (os_strncmp(buf, "RELOAD", 6) == 0) {4172#ifdef CONFIG_IEEE80211R_AP
4173 } else if (os_strcmp(buf, "GET_RXKHS") == 0) {
4174 reply_len = hostapd_ctrl_iface_get_rxkhs(hapd, reply,
4175 reply_size);
4176 } else if (os_strcmp(buf, "RELOAD_RXKHS") == 0) {
4177 if (hostapd_ctrl_iface_reload_rxkhs(hapd))
4178 reply_len = -1;
4179#endif /* CONFIG_IEEE80211R_AP */
4180 } else if (os_strcmp(buf, "RELOAD_BSS") == 0) {
4181 if (hostapd_ctrl_iface_reload_bss(hapd))
4182 reply_len = -1;
4183 } else if (os_strcmp(buf, "RELOAD_CONFIG") == 0) {
4184 if (hostapd_reload_config(hapd->iface))
4185 reply_len = -1;
4186 } else if (os_strcmp(buf, "RELOAD") == 0) {
3692 if (hostapd_ctrl_iface_reload(hapd->iface))4187 if (hostapd_ctrl_iface_reload(hapd->iface))
3693 reply_len = -1;4188 reply_len = -1;
3694 } else if (os_strncmp(buf, "DISABLE", 7) == 0) {4189 } else if (os_strcmp(buf, "DISABLE") == 0) {
3695 if (hostapd_ctrl_iface_disable(hapd->iface))4190 if (hostapd_ctrl_iface_disable(hapd->iface))
3696 reply_len = -1;4191 reply_len = -1;
3697 } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {4192 } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
@@ -3727,16 +4222,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3727 if (hostapd_ctrl_iface_data_test_frame(hapd, buf + 16) < 0)4222 if (hostapd_ctrl_iface_data_test_frame(hapd, buf + 16) < 0)
3728 reply_len = -1;4223 reply_len = -1;
3729 } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {4224 } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
3730 if (hostapd_ctrl_test_alloc_fail(hapd, buf + 16) < 0)4225 if (testing_set_fail_pattern(true, buf + 16) < 0)
3731 reply_len = -1;4226 reply_len = -1;
3732 } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {4227 } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
3733 reply_len = hostapd_ctrl_get_alloc_fail(hapd, reply,4228 reply_len = testing_get_fail_pattern(true, reply, reply_size);
3734 reply_size);
3735 } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) {4229 } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) {
3736 if (hostapd_ctrl_test_fail(hapd, buf + 10) < 0)4230 if (testing_set_fail_pattern(false, buf + 10) < 0)
3737 reply_len = -1;4231 reply_len = -1;
3738 } else if (os_strcmp(buf, "GET_FAIL") == 0) {4232 } else if (os_strcmp(buf, "GET_FAIL") == 0) {
3739 reply_len = hostapd_ctrl_get_fail(hapd, reply, reply_size);4233 reply_len = testing_get_fail_pattern(false, reply, reply_size);
3740 } else if (os_strncmp(buf, "RESET_PN ", 9) == 0) {4234 } else if (os_strncmp(buf, "RESET_PN ", 9) == 0) {
3741 if (hostapd_ctrl_reset_pn(hapd, buf + 9) < 0)4235 if (hostapd_ctrl_reset_pn(hapd, buf + 9) < 0)
3742 reply_len = -1;4236 reply_len = -1;
@@ -3768,6 +4262,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3768 } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {4262 } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
3769 if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))4263 if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
3770 reply_len = -1;4264 reply_len = -1;
4265#ifdef CONFIG_IEEE80211AX
4266 } else if (os_strncmp(buf, "COLOR_CHANGE ", 13) == 0) {
4267 if (hostapd_ctrl_iface_color_change(hapd->iface, buf + 13))
4268 reply_len = -1;
4269#endif /* CONFIG_IEEE80211AX */
4270 } else if (os_strncmp(buf, "NOTIFY_CW_CHANGE ", 17) == 0) {
4271 if (hostapd_ctrl_iface_notify_cw_change(hapd, buf + 17))
4272 reply_len = -1;
3771 } else if (os_strncmp(buf, "VENDOR ", 7) == 0) {4273 } else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
3772 reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,4274 reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
3773 reply_size);4275 reply_size);
@@ -3816,6 +4318,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3816 } else if (os_strncmp(buf, "REQ_BEACON ", 11) == 0) {4318 } else if (os_strncmp(buf, "REQ_BEACON ", 11) == 0) {
3817 reply_len = hostapd_ctrl_iface_req_beacon(hapd, buf + 11,4319 reply_len = hostapd_ctrl_iface_req_beacon(hapd, buf + 11,
3818 reply, reply_size);4320 reply, reply_size);
4321 } else if (os_strncmp(buf, "REQ_LINK_MEASUREMENT ", 21) == 0) {
4322 reply_len = hostapd_ctrl_iface_req_link_measurement(
4323 hapd, buf + 21, reply, reply_size);
3819 } else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) {4324 } else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) {
3820 reply_len = hostapd_ctrl_driver_flags(hapd->iface, reply,4325 reply_len = hostapd_ctrl_driver_flags(hapd->iface, reply,
3821 reply_size);4326 reply_size);
@@ -3828,14 +4333,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3828 if (os_strncmp(buf + 11, "ADD_MAC ", 8) == 0) {4333 if (os_strncmp(buf + 11, "ADD_MAC ", 8) == 0) {
3829 if (hostapd_ctrl_iface_acl_add_mac(4334 if (hostapd_ctrl_iface_acl_add_mac(
3830 &hapd->conf->accept_mac,4335 &hapd->conf->accept_mac,
3831 &hapd->conf->num_accept_mac, buf + 19))4336 &hapd->conf->num_accept_mac, buf + 19) ||
4337 hostapd_set_acl(hapd))
3832 reply_len = -1;4338 reply_len = -1;
3833 } else if (os_strncmp((buf + 11), "DEL_MAC ", 8) == 0) {4339 } else if (os_strncmp((buf + 11), "DEL_MAC ", 8) == 0) {
3834 if (!hostapd_ctrl_iface_acl_del_mac(4340 if (hostapd_ctrl_iface_acl_del_mac(
3835 &hapd->conf->accept_mac,4341 &hapd->conf->accept_mac,
3836 &hapd->conf->num_accept_mac, buf + 19))4342 &hapd->conf->num_accept_mac, buf + 19) ||
3837 hostapd_disassoc_accept_mac(hapd);4343 hostapd_set_acl(hapd) ||
3838 else4344 hostapd_disassoc_accept_mac(hapd))
3839 reply_len = -1;4345 reply_len = -1;
3840 } else if (os_strcmp(buf + 11, "SHOW") == 0) {4346 } else if (os_strcmp(buf + 11, "SHOW") == 0) {
3841 reply_len = hostapd_ctrl_iface_acl_show_mac(4347 reply_len = hostapd_ctrl_iface_acl_show_mac(
@@ -3845,20 +4351,25 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3845 hostapd_ctrl_iface_acl_clear_list(4351 hostapd_ctrl_iface_acl_clear_list(
3846 &hapd->conf->accept_mac,4352 &hapd->conf->accept_mac,
3847 &hapd->conf->num_accept_mac);4353 &hapd->conf->num_accept_mac);
3848 hostapd_disassoc_accept_mac(hapd);4354 if (hostapd_set_acl(hapd) ||
4355 hostapd_disassoc_accept_mac(hapd))
4356 reply_len = -1;
4357 } else {
4358 reply_len = -1;
3849 }4359 }
3850 } else if (os_strncmp(buf, "DENY_ACL ", 9) == 0) {4360 } else if (os_strncmp(buf, "DENY_ACL ", 9) == 0) {
3851 if (os_strncmp(buf + 9, "ADD_MAC ", 8) == 0) {4361 if (os_strncmp(buf + 9, "ADD_MAC ", 8) == 0) {
3852 if (!hostapd_ctrl_iface_acl_add_mac(4362 if (hostapd_ctrl_iface_acl_add_mac(
3853 &hapd->conf->deny_mac,4363 &hapd->conf->deny_mac,
3854 &hapd->conf->num_deny_mac, buf + 17))4364 &hapd->conf->num_deny_mac, buf + 17) ||
3855 hostapd_disassoc_deny_mac(hapd);4365 hostapd_set_acl(hapd) ||
3856 else4366 hostapd_disassoc_deny_mac(hapd))
3857 reply_len = -1;4367 reply_len = -1;
3858 } else if (os_strncmp(buf + 9, "DEL_MAC ", 8) == 0) {4368 } else if (os_strncmp(buf + 9, "DEL_MAC ", 8) == 0) {
3859 if (hostapd_ctrl_iface_acl_del_mac(4369 if (hostapd_ctrl_iface_acl_del_mac(
3860 &hapd->conf->deny_mac,4370 &hapd->conf->deny_mac,
3861 &hapd->conf->num_deny_mac, buf + 17))4371 &hapd->conf->num_deny_mac, buf + 17) ||
4372 hostapd_set_acl(hapd))
3862 reply_len = -1;4373 reply_len = -1;
3863 } else if (os_strcmp(buf + 9, "SHOW") == 0) {4374 } else if (os_strcmp(buf + 9, "SHOW") == 0) {
3864 reply_len = hostapd_ctrl_iface_acl_show_mac(4375 reply_len = hostapd_ctrl_iface_acl_show_mac(
@@ -3868,6 +4379,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3868 hostapd_ctrl_iface_acl_clear_list(4379 hostapd_ctrl_iface_acl_clear_list(
3869 &hapd->conf->deny_mac,4380 &hapd->conf->deny_mac,
3870 &hapd->conf->num_deny_mac);4381 &hapd->conf->num_deny_mac);
4382 if (hostapd_set_acl(hapd))
4383 reply_len = -1;
4384 } else {
4385 reply_len = -1;
3871 }4386 }
3872#ifdef CONFIG_DPP4387#ifdef CONFIG_DPP
3873 } else if (os_strncmp(buf, "DPP_QR_CODE ", 12) == 0) {4388 } else if (os_strncmp(buf, "DPP_QR_CODE ", 12) == 0) {
@@ -3959,6 +4474,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3959 if (os_snprintf_error(reply_size, reply_len))4474 if (os_snprintf_error(reply_size, reply_len))
3960 reply_len = -1;4475 reply_len = -1;
3961 }4476 }
4477 } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SET ", 21) == 0) {
4478 if (dpp_configurator_set(hapd->iface->interfaces->dpp,
4479 buf + 20) < 0)
4480 reply_len = -1;
3962 } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {4481 } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
3963 if (dpp_configurator_remove(hapd->iface->interfaces->dpp,4482 if (dpp_configurator_remove(hapd->iface->interfaces->dpp,
3964 buf + 24) < 0)4483 buf + 24) < 0)
@@ -3997,8 +4516,41 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
3997 reply_len = -1;4516 reply_len = -1;
3998 } else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {4517 } else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {
3999 hostapd_dpp_chirp_stop(hapd);4518 hostapd_dpp_chirp_stop(hapd);
4519 } else if (os_strncmp(buf, "DPP_RELAY_ADD_CONTROLLER ", 25) == 0) {
4520 if (hostapd_dpp_add_controller(hapd, buf + 25) < 0)
4521 reply_len = -1;
4522 } else if (os_strncmp(buf, "DPP_RELAY_REMOVE_CONTROLLER ", 28) == 0) {
4523 hostapd_dpp_remove_controller(hapd, buf + 28);
4000#endif /* CONFIG_DPP2 */4524#endif /* CONFIG_DPP2 */
4525#ifdef CONFIG_DPP3
4526 } else if (os_strcmp(buf, "DPP_PUSH_BUTTON") == 0) {
4527 if (hostapd_dpp_push_button(hapd, NULL) < 0)
4528 reply_len = -1;
4529 } else if (os_strncmp(buf, "DPP_PUSH_BUTTON ", 16) == 0) {
4530 if (hostapd_dpp_push_button(hapd, buf + 15) < 0)
4531 reply_len = -1;
4532#endif /* CONFIG_DPP3 */
4001#endif /* CONFIG_DPP */4533#endif /* CONFIG_DPP */
4534#ifdef CONFIG_NAN_USD
4535 } else if (os_strncmp(buf, "NAN_PUBLISH ", 12) == 0) {
4536 reply_len = hostapd_ctrl_nan_publish(hapd, buf + 12, reply,
4537 reply_size);
4538 } else if (os_strncmp(buf, "NAN_CANCEL_PUBLISH ", 19) == 0) {
4539 if (hostapd_ctrl_nan_cancel_publish(hapd, buf + 19) < 0)
4540 reply_len = -1;
4541 } else if (os_strncmp(buf, "NAN_UPDATE_PUBLISH ", 19) == 0) {
4542 if (hostapd_ctrl_nan_update_publish(hapd, buf + 19) < 0)
4543 reply_len = -1;
4544 } else if (os_strncmp(buf, "NAN_SUBSCRIBE ", 14) == 0) {
4545 reply_len = hostapd_ctrl_nan_subscribe(hapd, buf + 14, reply,
4546 reply_size);
4547 } else if (os_strncmp(buf, "NAN_CANCEL_SUBSCRIBE ", 21) == 0) {
4548 if (hostapd_ctrl_nan_cancel_subscribe(hapd, buf + 21) < 0)
4549 reply_len = -1;
4550 } else if (os_strncmp(buf, "NAN_TRANSMIT ", 13) == 0) {
4551 if (hostapd_ctrl_nan_transmit(hapd, buf + 13) < 0)
4552 reply_len = -1;
4553#endif /* CONFIG_NAN_USD */
4002#ifdef RADIUS_SERVER4554#ifdef RADIUS_SERVER
4003 } else if (os_strncmp(buf, "DAC_REQUEST ", 12) == 0) {4555 } else if (os_strncmp(buf, "DAC_REQUEST ", 12) == 0) {
4004 if (radius_server_dac_request(hapd->radius_srv, buf + 12) < 0)4556 if (radius_server_dac_request(hapd->radius_srv, buf + 12) < 0)
@@ -4016,6 +4568,20 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
4016 reply_len = hostapd_ctrl_iface_driver_cmd(hapd, buf + 7, reply,4568 reply_len = hostapd_ctrl_iface_driver_cmd(hapd, buf + 7, reply,
4017 reply_size);4569 reply_size);
4018#endif /* ANDROID */4570#endif /* ANDROID */
4571#ifdef CONFIG_IEEE80211BE
4572 } else if (os_strcmp(buf, "ENABLE_MLD") == 0) {
4573 if (hostapd_ctrl_iface_enable_mld(hapd->iface))
4574 reply_len = -1;
4575 } else if (os_strcmp(buf, "DISABLE_MLD") == 0) {
4576 if (hostapd_ctrl_iface_disable_mld(hapd->iface))
4577 reply_len = -1;
4578#ifdef CONFIG_TESTING_OPTIONS
4579 } else if (os_strncmp(buf, "LINK_REMOVE ", 12) == 0) {
4580 if (hostapd_ctrl_iface_link_remove(hapd, buf + 12,
4581 reply, reply_size))
4582 reply_len = -1;
4583#endif /* CONFIG_TESTING_OPTIONS */
4584#endif /* CONFIG_IEEE80211BE */
4019 } else {4585 } else {
4020 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);4586 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
4021 reply_len = 16;4587 reply_len = 16;
@@ -4506,6 +5072,20 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
45065072
4507#ifdef CONFIG_DPP5073#ifdef CONFIG_DPP
4508 dpp_global_clear(interfaces->dpp);5074 dpp_global_clear(interfaces->dpp);
5075#ifdef CONFIG_DPP3
5076 interfaces->dpp_pb_bi = NULL;
5077 {
5078 int i;
5079
5080 for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
5081 struct dpp_pb_info *info;
5082
5083 info = &interfaces->dpp_pb[i];
5084 info->rx_time.sec = 0;
5085 info->rx_time.usec = 0;
5086 }
5087 }
5088#endif /* CONFIG_DPP3 */
4509#endif /* CONFIG_DPP */5089#endif /* CONFIG_DPP */
4510}5090}
45115091
@@ -4897,7 +5477,7 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
4897 reply_len = -1;5477 reply_len = -1;
4898 } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {5478 } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {
4899 reply_len = hostapd_global_ctrl_iface_interfaces(5479 reply_len = hostapd_global_ctrl_iface_interfaces(
4900 interfaces, buf + 10, reply, sizeof(buffer));5480 interfaces, buf + 10, reply, reply_size);
4901 } else if (os_strcmp(buf, "TERMINATE") == 0) {5481 } else if (os_strcmp(buf, "TERMINATE") == 0) {
4902 eloop_terminate();5482 eloop_terminate();
4903 } else {5483 } else {
diff --git a/hostapd/defconfig b/hostapd/defconfig
index 6b50b6c..550db69 100644
--- a/hostapd/defconfig
+++ b/hostapd/defconfig
@@ -141,6 +141,9 @@ CONFIG_PKCS12=y
141# Build IPv6 support for RADIUS operations141# Build IPv6 support for RADIUS operations
142CONFIG_IPV6=y142CONFIG_IPV6=y
143143
144# Include support fo RADIUS/TLS into the RADIUS client
145#CONFIG_RADIUS_TLS=y
146
144# IEEE Std 802.11r-2008 (Fast BSS Transition)147# IEEE Std 802.11r-2008 (Fast BSS Transition)
145#CONFIG_IEEE80211R=y148#CONFIG_IEEE80211R=y
146149
@@ -156,10 +159,20 @@ CONFIG_IPV6=y
156#CONFIG_IEEE80211AC=y159#CONFIG_IEEE80211AC=y
157160
158# IEEE 802.11ax HE support161# IEEE 802.11ax HE support
162#CONFIG_IEEE80211AX=y
163
164# IEEE 802.11be EHT support
165# CONFIG_IEEE80211AX is mandatory for setting CONFIG_IEEE80211BE.
159# Note: This is experimental and work in progress. The definitions are still166# Note: This is experimental and work in progress. The definitions are still
160# subject to change and this should not be expected to interoperate with the167# subject to change and this should not be expected to interoperate with the
161# final IEEE 802.11ax version.168# final IEEE 802.11be version.
162#CONFIG_IEEE80211AX=y169#CONFIG_IEEE80211BE=y
170
171# Simultaneous Authentication of Equals (SAE), WPA3-Personal
172#CONFIG_SAE=y
173
174# SAE Public Key, WPA3-Personal
175#CONFIG_SAE_PK=y
163176
164# Remove debugging code that is printing out debug messages to stdout.177# Remove debugging code that is printing out debug messages to stdout.
165# This can be used to reduce the size of the hostapd considerably if debugging178# This can be used to reduce the size of the hostapd considerably if debugging
@@ -400,7 +413,6 @@ CONFIG_IPV6=y
400# Experimental implementation based on IEEE P802.11z/D2.6 and the protocol413# Experimental implementation based on IEEE P802.11z/D2.6 and the protocol
401# design is still subject to change. As such, this should not yet be enabled in414# design is still subject to change. As such, this should not yet be enabled in
402# production use.415# production use.
403# This requires CONFIG_IEEE80211W=y to be enabled, too.
404#CONFIG_PASN=y416#CONFIG_PASN=y
405417
406# Device Provisioning Protocol (DPP) (also known as Wi-Fi Easy Connect)418# Device Provisioning Protocol (DPP) (also known as Wi-Fi Easy Connect)
@@ -410,3 +422,6 @@ CONFIG_DPP2=y
410# DPP version 3 support (experimental and still changing; do not enable for422# DPP version 3 support (experimental and still changing; do not enable for
411# production use)423# production use)
412#CONFIG_DPP3=y424#CONFIG_DPP3=y
425
426# Wi-Fi Aware unsynchronized service discovery (NAN USD)
427#CONFIG_NAN_USD=y
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 3c2019f..d875d5f 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -225,6 +225,16 @@ channel=1
225# Default behavior is to include all PSC and non-PSC channels.225# Default behavior is to include all PSC and non-PSC channels.
226#acs_exclude_6ghz_non_psc=1226#acs_exclude_6ghz_non_psc=1
227227
228# Enable background radar feature
229# This feature allows CAC to be run on dedicated radio RF chains while the
230# radio(s) are otherwise running normal AP activities on other channels.
231# This requires that the driver and the radio support it before feature will
232# actually be enabled, i.e., this parameter value is ignored with drivers that
233# do not advertise support for the capability.
234# 0: Leave disabled (default)
235# 1: Enable it.
236#enable_background_radar=1
237
228# Set minimum permitted max TX power (in dBm) for ACS and DFS channel selection.238# Set minimum permitted max TX power (in dBm) for ACS and DFS channel selection.
229# (default 0, i.e., not constraint)239# (default 0, i.e., not constraint)
230#min_tx_power=20240#min_tx_power=20
@@ -512,6 +522,25 @@ wmm_ac_vo_acm=0
512# even if they are still in range of the AP. This can be done by setting522# even if they are still in range of the AP. This can be done by setting
513# skip_inactivity_poll to 1 (default 0).523# skip_inactivity_poll to 1 (default 0).
514#skip_inactivity_poll=0524#skip_inactivity_poll=0
525#
526# BSS max idle period management
527# 0 = disabled (do not advertise and manage BSS max idle period)
528# 1 = enabled (advertise and manage BSS max idle period; default)
529# 2 = enabled requiring protected frames (advertise and manage BSS max idle
530# period and require STAs to use protected keep-alive frames)
531#bss_max_idle=1
532#
533# Maximum acceptable BSS maximum idle period
534# If this is set to a nonzero value, the AP allows STAs to request different
535# maximum idle period values. This is in the units to 1000 TUs (1.024 s)
536#max_acceptable_idle_period=600
537#
538# Allow STA to skip group key handshake without getting disconnection when
539# BSS max idle period management is enabled.
540# 0 = disconnect STA if it does not reply to group key handshake (default)
541# 1 = do not disconnect STA if it does not reply to group key handshake and
542# if BSS max idle period management is enabled
543#no_disconnect_on_group_keyerror=0
515544
516# Disassociate stations based on excessive transmission failures or other545# Disassociate stations based on excessive transmission failures or other
517# indications of connection loss. This depends on the driver capabilities and546# indications of connection loss. This depends on the driver capabilities and
@@ -636,6 +665,12 @@ wmm_ac_vo_acm=0
636# no co-existence issues with neighboring devices are found.665# no co-existence issues with neighboring devices are found.
637#obss_interval=0666#obss_interval=0
638667
668# ht_vht_twt_responder: Whether TWT responder is enabled in HT and VHT modes
669# 0 = disable; Disable TWT responder support in HT and VHT modes (default).
670# 1 = enable; Enable TWT responder support in HT and VHT modes if supported by
671# the driver.
672#ht_vht_twt_responder=0
673
639##### IEEE 802.11ac related configuration #####################################674##### IEEE 802.11ac related configuration #####################################
640675
641# ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled676# ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled
@@ -802,6 +837,9 @@ wmm_ac_vo_acm=0
802# 1 = enabled837# 1 = enabled
803#ieee80211ax=1838#ieee80211ax=1
804839
840# Require stations to support HE PHY (reject association if they do not)
841#require_he=1
842
805# disable_11ax: Boolean (0/1) to disable HE for a specific BSS843# disable_11ax: Boolean (0/1) to disable HE for a specific BSS
806#disable_11ax=0844#disable_11ax=0
807845
@@ -861,7 +899,7 @@ wmm_ac_vo_acm=0
861# he_oper_chwidth is ignored, and the channel width is derived from the899# he_oper_chwidth is ignored, and the channel width is derived from the
862# configured operating class or center frequency indexes (see900# configured operating class or center frequency indexes (see
863# IEEE P802.11ax/D6.1 Annex E, Table E-4).901# IEEE P802.11ax/D6.1 Annex E, Table E-4).
864#he_oper_chwidth902#he_oper_chwidth (see vht_oper_chwidth)
865#he_oper_centr_freq_seg0_idx903#he_oper_centr_freq_seg0_idx
866#he_oper_centr_freq_seg1_idx904#he_oper_centr_freq_seg1_idx
867905
@@ -965,6 +1003,25 @@ wmm_ac_vo_acm=0
965# (default)1003# (default)
966#he_6ghz_tx_ant_pat=11004#he_6ghz_tx_ant_pat=1
9671005
1006# 6 GHz Access Point type
1007# This config is to set the 6 GHz Access Point type. Possible options are:
1008# 0 = Indoor AP
1009# 1 = Standard power AP
1010# 2 = Very low power AP (default)
1011# 3 = Indoor enabled AP
1012# 4 = Indoor standard power AP
1013# This has no impact for operation on other bands.
1014# See IEEE P802.11-REVme/D4.0, Table E-12 (Regulatory Info subfield encoding)
1015# for more details.
1016#he_6ghz_reg_pwr_type=0
1017#
1018# 6 GHz Maximum Tx Power used in Transmit Power Envelope elements, where the
1019# "Transmit Power Interpretation" is set to "Regulatory client EIRP PSD".
1020# For Maximum Transmit Power Category subfield encoding set to default (0):
1021#reg_def_cli_eirp_psd=-1
1022# For Maximum Transmit Power Category subfield encoding set to subordinate (1):
1023#reg_sub_cli_eirp_psd=-1
1024
968# Unsolicited broadcast Probe Response transmission settings1025# Unsolicited broadcast Probe Response transmission settings
969# This is for the 6 GHz band only. If the interval is set to a non-zero value,1026# This is for the 6 GHz band only. If the interval is set to a non-zero value,
970# the AP schedules unsolicited broadcast Probe Response frames to be1027# the AP schedules unsolicited broadcast Probe Response frames to be
@@ -973,6 +1030,78 @@ wmm_ac_vo_acm=0
973# Valid range: 0..20 TUs; default is 0 (disabled)1030# Valid range: 0..20 TUs; default is 0 (disabled)
974#unsol_bcast_probe_resp_interval=01031#unsol_bcast_probe_resp_interval=0
9751032
1033##### IEEE 802.11be related configuration #####################################
1034
1035#ieee80211be: Whether IEEE 802.11be (EHT) is enabled
1036# 0 = disabled (default)
1037# 1 = enabled
1038#ieee80211be=1
1039
1040#disable_11be: Boolean (0/1) to disable EHT for a specific BSS
1041#disable_11be=0
1042
1043#eht_su_beamformer: EHT single user beamformer support
1044# 0 = not supported (default)
1045# 1 = supported
1046#eht_su_beamformer=1
1047
1048#eht_su_beamformee: EHT single user beamformee support
1049# 0 = not supported (default)
1050# 1 = supported
1051#eht_su_beamformee=1
1052
1053#eht_mu_beamformer: EHT multiple user beamformer support
1054# 0 = not supported (default)
1055# 1 = supported
1056#eht_mu_beamformer=1
1057
1058# EHT operating channel information; see matching he_* parameters for details.
1059# The field eht_oper_centr_freq_seg0_idx field is used to indicate center
1060# frequency of 40, 80, and 160 MHz bandwidth operation.
1061# In the 6 GHz band, eht_oper_chwidth is ignored and the channel width is
1062# derived from the configured operating class (IEEE P802.11be/D1.5,
1063# Annex E.1 - Country information and operating classes).
1064#eht_oper_chwidth (see vht_oper_chwidth)
1065#eht_oper_centr_freq_seg0_idx
1066
1067#eht_default_pe_duration: The duration of PE field in EHT TB PPDU
1068# 0 = PE field duration is the same as he_default_pe_duration (default)
1069# 1 = PE field duration is 20 us
1070#eht_default_pe_duration=0
1071
1072#eht_bw320_offset: For automatic channel selection (ACS) to indicate a preferred
1073# 320 MHz channelization in EHT mode.
1074# If the channel is decided or the bandwidth is not 320 MHz, this option is
1075# meaningless.
1076# 0 = auto-detect by hostapd
1077# 1 = 320 MHz-1 (channel center frequency 31, 95, 159)
1078# 2 = 320 MHz-2 (channel center frequency 63, 127, 191)
1079#eht_bw320_offset=0
1080
1081# Disabled subchannel bitmap (16 bits) as per IEEE P802.11be/3.0,
1082# Figure 9-1002c (EHT Operation Information field format). Each bit corresponds
1083# to a 20 MHz channel, the lowest bit corresponds to the lowest frequency. A
1084# bit set to 1 indicates that the channel is punctured (disabled). The default
1085# value is 0 indicating that all channels are active.
1086#punct_bitmap=0
1087
1088# Preamble puncturing threshold in automatic channel selection (ACS).
1089# The value indicates the percentage of ideal channel average interference
1090# factor above which a channel should be punctured.
1091# Default is 0, indicates that ACS algorithm should not puncture any channel.
1092#punct_acs_threshold=75
1093
1094# AP MLD - Whether this AP is a part of an AP MLD
1095# 0 = no (no MLO)
1096# 1 = yes (MLO)
1097#mld_ap=0
1098
1099# AP MLD MAC address
1100# The configured address will be set as the interface hardware address and used
1101# as the AP MLD MAC address. If not set, the current interface hardware address
1102# will be used as the AP MLD MAC address.
1103#mld_addr=02:03:04:05:06:07
1104
976##### IEEE 802.1X-2004 related configuration ##################################1105##### IEEE 802.1X-2004 related configuration ##################################
9771106
978# Require IEEE 802.1X authorization1107# Require IEEE 802.1X authorization
@@ -1063,6 +1192,14 @@ eapol_key_index_workaround=0
1063# 0: No replay window, strict check (default)1192# 0: No replay window, strict check (default)
1064# 1..2^32-1: number of packets that could be misordered1193# 1..2^32-1: number of packets that could be misordered
1065#1194#
1195# macsec_offload: IEEE 802.1X/MACsec hardware offload
1196# This setting applies only when MACsec is in use, i.e.,
1197# - macsec_policy is enabled
1198# - the key server has decided to enable MACsec
1199# 0 = MACSEC_OFFLOAD_OFF (default)
1200# 1 = MACSEC_OFFLOAD_PHY
1201# 2 = MACSEC_OFFLOAD_MAC
1202#
1066# macsec_port: IEEE 802.1X/MACsec port1203# macsec_port: IEEE 802.1X/MACsec port
1067# Port component of the SCI1204# Port component of the SCI
1068# Range: 1-65534 (default: 1)1205# Range: 1-65534 (default: 1)
@@ -1070,6 +1207,10 @@ eapol_key_index_workaround=0
1070# mka_priority (Priority of MKA Actor)1207# mka_priority (Priority of MKA Actor)
1071# Range: 0..255 (default: 255)1208# Range: 0..255 (default: 255)
1072#1209#
1210# macsec_csindex: IEEE 802.1X/MACsec cipher suite
1211# 0 = GCM-AES-128 (default)
1212# 1 = GCM-AES-256 (default)
1213#
1073# mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode1214# mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode
1074# This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair.1215# This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair.
1075# In this mode, instances of hostapd can act as MACsec peers. The peer1216# In this mode, instances of hostapd can act as MACsec peers. The peer
@@ -1243,12 +1384,11 @@ eap_server=0
12431384
1244# dh_file: File path to DH/DSA parameters file (in PEM format)1385# dh_file: File path to DH/DSA parameters file (in PEM format)
1245# This is an optional configuration file for setting parameters for an1386# This is an optional configuration file for setting parameters for an
1246# ephemeral DH key exchange. In most cases, the default RSA authentication does1387# ephemeral DH key exchange. If the file is in DSA parameters format, it will
1247# not use this configuration. However, it is possible setup RSA to use1388# be automatically converted into DH params. If the used TLS library supports
1248# ephemeral DH key exchange. In addition, ciphers with DSA keys always use1389# automatic DH parameter selection, that functionality will be used if this
1249# ephemeral DH keys. This can be used to achieve forward secrecy. If the file1390# parameter is not set. DH parameters are required if anonymous EAP-FAST is
1250# is in DSA parameters format, it will be automatically converted into DH1391# used.
1251# params. This parameter is required if anonymous EAP-FAST is used.
1252# You can generate DH parameters file with OpenSSL, e.g.,1392# You can generate DH parameters file with OpenSSL, e.g.,
1253# "openssl dhparam -out /etc/hostapd.dh.pem 2048"1393# "openssl dhparam -out /etc/hostapd.dh.pem 2048"
1254#dh_file=/etc/hostapd.dh.pem1394#dh_file=/etc/hostapd.dh.pem
@@ -1358,6 +1498,12 @@ eap_server=0
1358# 5 = require both user and machine identity1498# 5 = require both user and machine identity
1359#eap_teap_id=01499#eap_teap_id=0
13601500
1501# EAP-TEAP tunneled EAP method behavior
1502# 0 = minimize roundtrips by merging start of the next EAP method with the
1503# crypto-binding of the previous one.
1504# 1 = complete crypto-binding before starting the next EAP method
1505#eap_teap_method_sequence=0
1506
1361# EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND1507# EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND
1362# (default: 0 = disabled).1508# (default: 0 = disabled).
1363#eap_sim_aka_result_ind=11509#eap_sim_aka_result_ind=1
@@ -1367,8 +1513,25 @@ eap_server=0
1367# 1 = use pseudonyms, but not fast reauthentication1513# 1 = use pseudonyms, but not fast reauthentication
1368# 2 = do not use pseudonyms, but use fast reauthentication1514# 2 = do not use pseudonyms, but use fast reauthentication
1369# 3 = use pseudonyms and use fast reauthentication (default)1515# 3 = use pseudonyms and use fast reauthentication (default)
1516# 4 = do not use pseudonyms or fast reauthentication and allow
1517# EAP-Response/Identity to be used without method specific identity exchange
1518# 5 = use pseudonyms, but not fast reauthentication and allow
1519# EAP-Response/Identity to be used without method specific identity exchange
1520# 6 = do not use pseudonyms, but use fast reauthentication and allow
1521# EAP-Response/Identity to be used without method specific identity exchange
1522# 7 = use pseudonyms and use fast reauthentication and allow
1523# EAP-Response/Identity to be used without method specific identity exchange
1370#eap_sim_id=31524#eap_sim_id=3
13711525
1526# IMSI privacy key (PEM encoded RSA 2048-bit private key) for decrypting
1527# permanent identity when using EAP-SIM/AKA/AKA'.
1528#imsi_privacy_key=imsi-privacy-key.pem
1529
1530# EAP-SIM and EAP-AKA fast re-authentication limit
1531# Maximum number of fast re-authentications allowed after each full
1532# authentication.
1533#eap_sim_aka_fast_reauth_limit=1000
1534
1372# Trusted Network Connect (TNC)1535# Trusted Network Connect (TNC)
1373# If enabled, TNC validation will be required before the peer is allowed to1536# If enabled, TNC validation will be required before the peer is allowed to
1374# connect. Note: This is only used with EAP-TTLS and EAP-FAST. If any other1537# connect. Note: This is only used with EAP-TTLS and EAP-FAST. If any other
@@ -1440,6 +1603,16 @@ own_ip_addr=127.0.0.1
1440#acct_server_port=18131603#acct_server_port=1813
1441#acct_server_shared_secret=secret21604#acct_server_shared_secret=secret2
14421605
1606# RADIUS/TLS instead of RADIUS/UDP
1607#auth_server_addr=127.0.0.1
1608#auth_server_port=2083
1609#auth_server_type=TLS
1610#auth_server_shared_secret=radsec
1611#auth_server_ca_cert=<path to trusted CA certificate(s)>
1612#auth_server_client_cert=<path to client certificate>
1613#auth_server_private_key=<path to private key>
1614#auth_server_private_key_passwd=<password for decrypting private key>
1615
1443# Retry interval for trying to return to the primary RADIUS server (in1616# Retry interval for trying to return to the primary RADIUS server (in
1444# seconds). RADIUS client code will automatically try to use the next server1617# seconds). RADIUS client code will automatically try to use the next server
1445# when the current server is not replying to requests. If this interval is set,1618# when the current server is not replying to requests. If this interval is set,
@@ -1447,6 +1620,17 @@ own_ip_addr=127.0.0.1
1447# currently used secondary server is still working.1620# currently used secondary server is still working.
1448#radius_retry_primary_interval=6001621#radius_retry_primary_interval=600
14491622
1623# Message-Authenticator attribute requirement for non-EAP cases
1624# hostapd requires Message-Authenticator attribute to be included in all cases
1625# where RADIUS is used for EAP authentication. This is also required for cases
1626# where RADIUS is used for MAC ACL (macaddr_acl=2) by default, but that case
1627# can be configured to not require this for compatibility with RADIUS servers
1628# that do not include the attribute. This is not recommended due to potential
1629# security concerns, but can be used as a temporary workaround in networks where
1630# the connection to the RADIUS server is secure.
1631# 0 = Do not require Message-Authenticator in MAC ACL response
1632# 1 = Require Message-Authenticator in all authentication cases (default)
1633#radius_require_message_authenticator=1
14501634
1451# Interim accounting update interval1635# Interim accounting update interval
1452# If this is set (larger than 0) and acct_server is configured, hostapd will1636# If this is set (larger than 0) and acct_server is configured, hostapd will
@@ -1651,12 +1835,19 @@ own_ip_addr=127.0.0.1
1651#wpa_psk_file=/etc/hostapd.wpa_psk1835#wpa_psk_file=/etc/hostapd.wpa_psk
16521836
1653# Optionally, WPA passphrase can be received from RADIUS authentication server1837# Optionally, WPA passphrase can be received from RADIUS authentication server
1654# This requires macaddr_acl to be set to 2 (RADIUS)1838# This requires macaddr_acl to be set to 2 (RADIUS) for wpa_psk_radius values
1839# 1 and 2.
1655# 0 = disabled (default)1840# 0 = disabled (default)
1656# 1 = optional; use default passphrase/psk if RADIUS server does not include1841# 1 = optional; use default passphrase/psk if RADIUS server does not include
1657# Tunnel-Password1842# Tunnel-Password
1658# 2 = required; reject authentication if RADIUS server does not include1843# 2 = required; reject authentication if RADIUS server does not include
1659# Tunnel-Password1844# Tunnel-Password
1845# 3 = ask RADIUS server during 4-way handshake if there is no locally
1846# configured PSK/passphrase for the STA
1847#
1848# The Tunnel-Password attribute in Access-Accept can contain either the
1849# 8..63 character ASCII passphrase or a 64 hex character encoding of the PSK.
1850#
1660#wpa_psk_radius=01851#wpa_psk_radius=0
16611852
1662# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The1853# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
@@ -1914,6 +2105,10 @@ own_ip_addr=127.0.0.1
1914#sae_password=really secret|mac=ff:ff:ff:ff:ff:ff2105#sae_password=really secret|mac=ff:ff:ff:ff:ff:ff
1915#sae_password=example secret|mac=02:03:04:05:06:07|id=pw identifier2106#sae_password=example secret|mac=02:03:04:05:06:07|id=pw identifier
1916#sae_password=example secret|vlanid=3|id=pw identifier2107#sae_password=example secret|vlanid=3|id=pw identifier
2108#
2109# SAE passwords can also be read from a separate file in which each line
2110# contains and entry in the same format as sae_password uses.
2111#sae_password_file=/tc/hostapd.sae_passwords
19172112
1918# SAE threshold for anti-clogging mechanism (dot11RSNASAEAntiCloggingThreshold)2113# SAE threshold for anti-clogging mechanism (dot11RSNASAEAntiCloggingThreshold)
1919# This parameter defines how many open SAE instances can be in progress at the2114# This parameter defines how many open SAE instances can be in progress at the
@@ -1924,7 +2119,7 @@ own_ip_addr=127.0.0.1
1924# Maximum number of SAE synchronization errors (dot11RSNASAESync)2119# Maximum number of SAE synchronization errors (dot11RSNASAESync)
1925# The offending SAE peer will be disconnected if more than this many2120# The offending SAE peer will be disconnected if more than this many
1926# synchronization errors happen.2121# synchronization errors happen.
1927#sae_sync=52122#sae_sync=3
19282123
1929# Enabled SAE finite cyclic groups2124# Enabled SAE finite cyclic groups
1930# SAE implementation are required to support group 19 (ECC group defined over a2125# SAE implementation are required to support group 19 (ECC group defined over a
@@ -2042,6 +2237,8 @@ own_ip_addr=127.0.0.1
2042# If fils_discovery_max_interval is non-zero, the AP enables FILS Discovery2237# If fils_discovery_max_interval is non-zero, the AP enables FILS Discovery
2043# frame transmission. These values use TUs as the unit and have allowed range2238# frame transmission. These values use TUs as the unit and have allowed range
2044# of 0-10000. fils_discovery_min_interval defaults to 20.2239# of 0-10000. fils_discovery_min_interval defaults to 20.
2240# This feature is currently supported only when ieee80211ax is enabled for
2241# the radio and disable_11ax is not set for the BSS.
2045#fils_discovery_min_interval=202242#fils_discovery_min_interval=20
2046#fils_discovery_max_interval=02243#fils_discovery_max_interval=0
20472244
@@ -2077,6 +2274,30 @@ own_ip_addr=127.0.0.1
2077# (default: 10 TUs)2274# (default: 10 TUs)
2078#pasn_comeback_after=102275#pasn_comeback_after=10
20792276
2277# Unauthenticated PASN activated (dot11NoAuthPASNActivated)
2278# This indicates whether PASN without mutual authentication is allowed.
2279# (default: 1 = activated)
2280#pasn_noauth=1
2281
2282# SSID protection in 4-way handshake
2283# The IEEE 802.11i-2004 RSN design did not provide means for protecting the
2284# SSID in the general case. IEEE P802.11REVme/D6.0 added support for this in
2285# 4-way handshake. This capability allows a STA to confirm that the AP has the
2286# same understanding on which SSID is being used for an association in a
2287# protected manner in cases where both the AP and the STA has this capability.
2288# This can be used to mitigate CVE-2023-52424 (a.k.a. the SSID Confusion
2289# Attack).
2290#
2291# Ideally, this capability would be enabled by default on the AP, but since this
2292# is new functionality with limited testing, the default is to disable this for
2293# now and require explicitly configuration to enable. The default behavior is
2294# like to change once this capability has received more testing.
2295#
2296# 0 = SSID protection in 4-way handshake disabled (default)
2297# 1 = SSID protection in 4-way handshake enabled
2298#
2299#ssid_protection=0
2300
2080##### IEEE 802.11r configuration ##############################################2301##### IEEE 802.11r configuration ##############################################
20812302
2082# Mobility Domain identifier (dot11FTMobilityDomainID, MDID)2303# Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
@@ -2136,6 +2357,12 @@ own_ip_addr=127.0.0.1
2136# list and thus will receive push notifications.2357# list and thus will receive push notifications.
2137#r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff2358#r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff
21382359
2360# Optionally, the list of RxKHs can be read from a text file. Format is the same
2361# as specified above. File shall contain both r0kh and r1kh. Once this variable
2362# is set, RxKHs can be reloaded at runtime without bringing down an interface
2363# using the RELOAD_RXKHS command.
2364#rxkh_file=<path>
2365
2139# Timeout (seconds) for newly discovered R0KH/R1KH (see wildcard entries above)2366# Timeout (seconds) for newly discovered R0KH/R1KH (see wildcard entries above)
2140# Special values: 0 -> do not expire2367# Special values: 0 -> do not expire
2141# Warning: do not cache implies no sequence number validation with wildcards2368# Warning: do not cache implies no sequence number validation with wildcards
@@ -2390,6 +2617,23 @@ own_ip_addr=127.0.0.1
2390#multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef2617#multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
2391#multi_ap_backhaul_wpa_passphrase=secret passphrase2618#multi_ap_backhaul_wpa_passphrase=secret passphrase
23922619
2620# Multi-AP Profile
2621# Indicate the supported Multi-AP profile (default: 2)
2622# 1 = Supports Multi-AP profile 1 as defined in Wi-Fi EasyMesh specification
2623# 2 = Supports Multi-AP profile 2 as defined in Wi-Fi EasyMesh specification
2624#multi_ap_profile=2
2625
2626# Multi-AP client disallow
2627# Used to disallow profile specific backhaul STA association
2628# Bitmap of the disallowed Profile-X profiles
2629# 1 = Profile-1 Backhaul STA association disallowed
2630# 2 = Profile-2 Backhaul STA association disallowed
2631#multi_ap_client_disallow=0
2632
2633# Multi-AP VLAN ID
2634# A valid non-zero VLAN ID will be used to update Default IEEE 802.1Q Setting
2635#multi_ap_vlanid=0
2636
2393# WPS UPnP interface2637# WPS UPnP interface
2394# If set, support for external Registrars is enabled.2638# If set, support for external Registrars is enabled.
2395#upnp_iface=br02639#upnp_iface=br0
@@ -2453,12 +2697,24 @@ own_ip_addr=127.0.0.1
2453# MUD URL for Enrollee's DPP Configuration Request (optional)2697# MUD URL for Enrollee's DPP Configuration Request (optional)
2454#dpp_mud_url=https://example.com/mud2698#dpp_mud_url=https://example.com/mud
24552699
2700# JSON node name of additional data for Enrollee's DPP Configuration Request
2701#dpp_extra_conf_req_name=org.example
2702
2703# JSON node data of additional data for Enrollee's DPP Configuration Request
2704#dpp_extra_conf_req_value="abc":123
2705
2456#dpp_connector2706#dpp_connector
2457#dpp_netaccesskey2707#dpp_netaccesskey
2458#dpp_netaccesskey_expiry2708#dpp_netaccesskey_expiry
2459#dpp_csign2709#dpp_csign
2460#dpp_controller2710#dpp_controller
24612711
2712# DPP Relay port number
2713# TCP port to listen to for incoming connections from a Controller. This can be
2714# used to allow Controller initiated exchanges in addition to the
2715# Controller-as-responder cases covered by the dpp_controller parameter.
2716#dpp_relay_port=12345
2717
2462# Configurator Connectivity indication2718# Configurator Connectivity indication
2463# 0: no Configurator is currently connected (default)2719# 0: no Configurator is currently connected (default)
2464# 1: advertise that a Configurator is available2720# 1: advertise that a Configurator is available
@@ -2726,7 +2982,12 @@ own_ip_addr=127.0.0.1
2726# If the RADIUS server indicates that the station is not allowed to connect to2982# If the RADIUS server indicates that the station is not allowed to connect to
2727# the BSS/ESS, the AP can allow the station some time to download a2983# the BSS/ESS, the AP can allow the station some time to download a
2728# notification page (URL included in the message). This parameter sets that2984# notification page (URL included in the message). This parameter sets that
2729# timeout in seconds.2985# timeout in seconds. If the RADIUS server provides no URL, this value is
2986# reduced to two seconds with an additional trigger for immediate
2987# deauthentication when the STA acknowledges reception of the deauthentication
2988# imminent indication. Note that setting this value to 0 will prevent delivery
2989# of the notification to the STA, so a value of at least 1 should be used here
2990# for normal use cases.
2730#hs20_deauth_req_timeout=602991#hs20_deauth_req_timeout=60
27312992
2732# Operator Friendly Name2993# Operator Friendly Name
@@ -2906,6 +3167,9 @@ own_ip_addr=127.0.0.1
2906# Enable neighbor report via radio measurements3167# Enable neighbor report via radio measurements
2907#rrm_neighbor_report=13168#rrm_neighbor_report=1
29083169
3170# Enable link measurement report via radio measurements
3171#rrm_link_measurement_report=1
3172
2909# Enable beacon report via radio measurements3173# Enable beacon report via radio measurements
2910#rrm_beacon_report=13174#rrm_beacon_report=1
29113175
@@ -3002,6 +3266,18 @@ own_ip_addr=127.0.0.1
3002# Include only ECSA IE without CSA IE where possible3266# Include only ECSA IE without CSA IE where possible
3003# (channel switch operating class is needed)3267# (channel switch operating class is needed)
3004#ecsa_ie_only=03268#ecsa_ie_only=0
3269#
3270# Delay EAPOL-Key messages 1/4 and 3/4 by not sending the frame until the last
3271# attempt (wpa_pairwise_update_count). This will trigger a timeout on all
3272# previous attempts and thus delays the frame. (testing only)
3273#delay_eapol_tx=0
3274#
3275# Additional elements for Probe Response frames.
3276# This parameter can be used to add additional element(s) to the end of the
3277# Probe Response frames. The format for these element(s) is a hexdump of the
3278# raw information elements (id+len+payload for one or more elements).
3279# These elements are added after the 'vendor_elements'.
3280#presp_elements=
30053281
3006##### Multiple BSSID support ##################################################3282##### Multiple BSSID support ##################################################
3007#3283#
@@ -3045,3 +3321,63 @@ own_ip_addr=127.0.0.1
3045#bss=wlan0_13321#bss=wlan0_1
3046#bssid=00:13:10:95:fe:0b3322#bssid=00:13:10:95:fe:0b
3047# ...3323# ...
3324#
3325# Multiple BSSID Advertisement in IEEE 802.11ax
3326# IEEE Std 802.11ax-2021 added a feature where instead of multiple interfaces
3327# on a common radio transmitting individual Beacon frames, those interfaces can
3328# form a set with a common Beacon frame transmitted for all. The interface
3329# which is brought up first is called the transmitting profile of the MBSSID
3330# set which transmits the Beacon frames. The remaining interfaces are called
3331# the non-transmitting profiles and these are advertised inside the Multiple
3332# BSSID element in the Beacon and Probe Response frames from the first
3333# interface.
3334#
3335# The transmitting interface is visible to all stations in the vicinity, however
3336# the stations that do not support parsing of the Multiple BSSID element will
3337# not be able to connect to the non-transmitting interfaces.
3338#
3339# Enhanced Multiple BSSID Advertisements (EMA)
3340# When enabled, the non-transmitting interfaces are split into multiple
3341# Beacon frames. The number of Beacon frames required to cover all the
3342# non-transmitting profiles is called the profile periodicity.
3343#
3344# Refer to IEEE Std 802.11-2020 for details regarding the procedure and
3345# required MAC address assignment.
3346#
3347# Following configuration is per radio.
3348# 0 = Disabled (default)
3349# 1 = Multiple BSSID advertisement enabled.
3350# 2 = Enhanced multiple BSSID advertisement enabled.
3351#mbssid=0
3352#
3353# The transmitting interface should be added with the 'interface' option while
3354# the non-transmitting interfaces should be added using the 'bss' option.
3355# Security configuration should be added separately per interface, if required.
3356#
3357# Example:
3358#mbssid=2
3359#interface=wlan2
3360#ctrl_interface=/var/run/hostapd
3361#wpa_passphrase=0123456789
3362#ieee80211w=2
3363#sae_pwe=1
3364#auth_algs=1
3365#wpa=2
3366#wpa_pairwise=CCMP
3367#ssid=<SSID-0>
3368#bridge=br-lan
3369#wpa_key_mgmt=SAE
3370#bssid=00:03:7f:12:84:84
3371#
3372#bss=wlan2-1
3373#ctrl_interface=/var/run/hostapd
3374#wpa_passphrase=0123456789
3375#ieee80211w=2
3376#sae_pwe=1
3377#auth_algs=1
3378#wpa=2
3379#wpa_pairwise=CCMP
3380#ssid=<SSID-1>
3381#bridge=br-lan
3382#wpa_key_mgmt=SAE
3383#bssid=00:03:7f:12:84:85
diff --git a/hostapd/hostapd.eap_user b/hostapd/hostapd.eap_user
index 00edc95..61ef937 100644
--- a/hostapd/hostapd.eap_user
+++ b/hostapd/hostapd.eap_user
@@ -52,8 +52,8 @@
52# Arbitrary RADIUS attributes can be added into Access-Accept packets similarly52# Arbitrary RADIUS attributes can be added into Access-Accept packets similarly
53# to the way radius_auth_req_attr is used for Access-Request packet in53# to the way radius_auth_req_attr is used for Access-Request packet in
54# hostapd.conf. For EAP server, this is configured separately for each user54# hostapd.conf. For EAP server, this is configured separately for each user
55# entry with radius_accept_attr=<value> line(s) following the main user entry55# entry with radius_accept_attr=<attr_id>[:<syntax:value>] line(s) following
56# line.56# the main user entry line.
5757
58# Phase 1 users58# Phase 1 users
59"user" MD5 "password"59"user" MD5 "password"
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 2609121..eb8a383 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -21,7 +21,7 @@
2121
22static const char *const hostapd_cli_version =22static const char *const hostapd_cli_version =
23"hostapd_cli v" VERSION_STR "\n"23"hostapd_cli v" VERSION_STR "\n"
24"Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi> and contributors";24"Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi> and contributors";
2525
26static struct wpa_ctrl *ctrl_conn;26static struct wpa_ctrl *ctrl_conn;
27static int hostapd_cli_quit = 0;27static int hostapd_cli_quit = 0;
@@ -252,6 +252,13 @@ static int hostapd_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
252}252}
253253
254254
255static int hostapd_cli_cmd_close_log(struct wpa_ctrl *ctrl, int argc,
256 char *argv[])
257{
258 return wpa_ctrl_command(ctrl, "CLOSE_LOG");
259}
260
261
255static int hostapd_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])262static int hostapd_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
256{263{
257 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)264 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
@@ -307,6 +314,12 @@ static void hostapd_cli_action_process(char *msg, size_t len)
307}314}
308315
309316
317static void hostapd_cli_action_cb(char *msg, size_t len)
318{
319 hostapd_cli_action_process(msg, len);
320}
321
322
310static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])323static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
311{324{
312 char buf[64];325 char buf[64];
@@ -1155,6 +1168,15 @@ static int hostapd_cli_cmd_fst(struct wpa_ctrl *ctrl, int argc, char *argv[])
1155#endif /* CONFIG_FST */1168#endif /* CONFIG_FST */
11561169
11571170
1171#ifdef CONFIG_IEEE80211AX
1172static int hostapd_cli_cmd_color_change(struct wpa_ctrl *ctrl,
1173 int argc, char *argv[])
1174{
1175 return hostapd_cli_cmd(ctrl, "COLOR_CHANGE", 1, argc, argv);
1176}
1177#endif /* CONFIG_IEEE80211AX */
1178
1179
1158static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,1180static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
1159 int argc, char *argv[])1181 int argc, char *argv[])
1160{1182{
@@ -1169,7 +1191,7 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
1169 "arguments (count and freq)\n"1191 "arguments (count and freq)\n"
1170 "usage: <cs_count> <freq> [sec_channel_offset=] "1192 "usage: <cs_count> <freq> [sec_channel_offset=] "
1171 "[center_freq1=] [center_freq2=] [bandwidth=] "1193 "[center_freq1=] [center_freq2=] [bandwidth=] "
1172 "[blocktx] [ht|vht]\n");1194 "[blocktx] [ht|vht|he|eht]\n");
1173 return -1;1195 return -1;
1174 }1196 }
11751197
@@ -1194,34 +1216,76 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
1194}1216}
11951217
11961218
1219static int hostapd_cli_cmd_notify_cw_change(struct wpa_ctrl *ctrl,
1220 int argc, char *argv[])
1221{
1222 return hostapd_cli_cmd(ctrl, "NOTIFY_CW_CHANGE", 1, argc, argv);
1223}
1224
1225
1197static int hostapd_cli_cmd_enable(struct wpa_ctrl *ctrl, int argc,1226static int hostapd_cli_cmd_enable(struct wpa_ctrl *ctrl, int argc,
1198 char *argv[])1227 char *argv[])
1199{1228{
1200 return wpa_ctrl_command(ctrl, "ENABLE");1229 return wpa_ctrl_command(ctrl, "ENABLE");
1201}1230}
12021231
12031232
1204static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc,1233static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc,
1205 char *argv[])1234 char *argv[])
1206{1235{
1207 return wpa_ctrl_command(ctrl, "RELOAD");1236 return wpa_ctrl_command(ctrl, "RELOAD");
1208}1237}
12091238
12101239
1211static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,1240static int hostapd_cli_cmd_reload_bss(struct wpa_ctrl *ctrl, int argc,
1212 char *argv[])1241 char *argv[])
1213{1242{
1243 return wpa_ctrl_command(ctrl, "RELOAD_BSS");
1244}
1245
1246
1247static int hostapd_cli_cmd_reload_config(struct wpa_ctrl *ctrl, int argc,
1248 char *argv[])
1249{
1250 return wpa_ctrl_command(ctrl, "RELOAD_CONFIG");
1251}
1252
1253
1254static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc,
1255 char *argv[])
1256{
1214 return wpa_ctrl_command(ctrl, "DISABLE");1257 return wpa_ctrl_command(ctrl, "DISABLE");
1215}1258}
12161259
12171260
1218static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,1261static int hostapd_cli_cmd_enable_mld(struct wpa_ctrl *ctrl, int argc,
1219 char *argv[])1262 char *argv[])
1220{1263{
1264 return wpa_ctrl_command(ctrl, "ENABLE_MLD");
1265}
1266
1267
1268static int hostapd_cli_cmd_disable_mld(struct wpa_ctrl *ctrl, int argc,
1269 char *argv[])
1270{
1271 return wpa_ctrl_command(ctrl, "DISABLE_MLD");
1272}
1273
1274
1275static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
1276 char *argv[])
1277{
1221 return wpa_ctrl_command(ctrl, "UPDATE_BEACON");1278 return wpa_ctrl_command(ctrl, "UPDATE_BEACON");
1222}1279}
12231280
12241281
1282static int hostapd_cli_cmd_stop_ap(struct wpa_ctrl *ctrl, int argc,
1283 char *argv[])
1284{
1285 return wpa_ctrl_command(ctrl, "STOP_AP");
1286}
1287
1288
1225static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])1289static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
1226{1290{
1227 char cmd[256];1291 char cmd[256];
@@ -1366,6 +1430,13 @@ static int hostapd_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
1366}1430}
13671431
13681432
1433static int hostapd_cli_cmd_driver_flags2(struct wpa_ctrl *ctrl, int argc,
1434 char *argv[])
1435{
1436 return wpa_ctrl_command(ctrl, "DRIVER_FLAGS2");
1437}
1438
1439
1369#ifdef CONFIG_DPP1440#ifdef CONFIG_DPP
13701441
1371static int hostapd_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc,1442static int hostapd_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc,
@@ -1478,7 +1549,7 @@ static int hostapd_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc,
1478static int hostapd_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,1549static int hostapd_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,
1479 char *argv[])1550 char *argv[])
1480{1551{
1481 return hostapd_cli_cmd(ctrl, "DPP_CONTROLLER_START", 1, argc, argv);1552 return hostapd_cli_cmd(ctrl, "DPP_CONTROLLER_START", 0, argc, argv);
1482}1553}
14831554
14841555
@@ -1503,6 +1574,15 @@ static int hostapd_cli_cmd_dpp_stop_chirp(struct wpa_ctrl *ctrl, int argc,
1503}1574}
15041575
1505#endif /* CONFIG_DPP2 */1576#endif /* CONFIG_DPP2 */
1577
1578
1579#ifdef CONFIG_DPP3
1580static int hostapd_cli_cmd_dpp_push_button(struct wpa_ctrl *ctrl, int argc,
1581 char *argv[])
1582{
1583 return hostapd_cli_cmd(ctrl, "DPP_PUSH_BUTTON", 0, argc, argv);
1584}
1585#endif /* CONFIG_DPP3 */
1506#endif /* CONFIG_DPP */1586#endif /* CONFIG_DPP */
15071587
15081588
@@ -1534,6 +1614,13 @@ static int hostapd_cli_cmd_req_beacon(struct wpa_ctrl *ctrl, int argc,
1534}1614}
15351615
15361616
1617static int hostapd_cli_cmd_req_link_measurement(struct wpa_ctrl *ctrl, int argc,
1618 char *argv[])
1619{
1620 return hostapd_cli_cmd(ctrl, "REQ_LINK_MEASUREMENT", 1, argc, argv);
1621}
1622
1623
1537static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,1624static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
1538 char *argv[])1625 char *argv[])
1539{1626{
@@ -1541,6 +1628,24 @@ static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
1541}1628}
15421629
15431630
1631#ifdef CONFIG_IEEE80211R_AP
1632
1633static int hostapd_cli_cmd_get_rxkhs(struct wpa_ctrl *ctrl, int argc,
1634 char *argv[])
1635{
1636 return wpa_ctrl_command(ctrl, "GET_RXKHS");
1637}
1638
1639
1640static int hostapd_cli_cmd_reload_rxkhs(struct wpa_ctrl *ctrl, int argc,
1641 char *argv[])
1642{
1643 return wpa_ctrl_command(ctrl, "RELOAD_RXKHS");
1644}
1645
1646#endif /* CONFIG_IEEE80211R_AP */
1647
1648
1544#ifdef ANDROID1649#ifdef ANDROID
1545static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])1650static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
1546{1651{
@@ -1563,6 +1668,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
1563 "= get MIB variables (dot1x, dot11, radius)" },1668 "= get MIB variables (dot1x, dot11, radius)" },
1564 { "relog", hostapd_cli_cmd_relog, NULL,1669 { "relog", hostapd_cli_cmd_relog, NULL,
1565 "= reload/truncate debug log output file" },1670 "= reload/truncate debug log output file" },
1671 { "close_log", hostapd_cli_cmd_close_log, NULL,
1672 "= disable debug log output file" },
1566 { "status", hostapd_cli_cmd_status, NULL,1673 { "status", hostapd_cli_cmd_status, NULL,
1567 "= show interface status info" },1674 "= show interface status info" },
1568 { "sta", hostapd_cli_cmd_sta, hostapd_complete_stations,1675 { "sta", hostapd_cli_cmd_sta, hostapd_complete_stations,
@@ -1648,6 +1755,13 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
1648 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]\n"1755 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]\n"
1649 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n"1756 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n"
1650 " = initiate channel switch announcement" },1757 " = initiate channel switch announcement" },
1758#ifdef CONFIG_IEEE80211AX
1759 { "color_change", hostapd_cli_cmd_color_change, NULL,
1760 "<color> = initiate BSS color change to set the specified color\n"
1761 "Value 0 will disable the color.\n"},
1762#endif /* CONFIG_IEEE80211AX */
1763 { "notify_cw_change", hostapd_cli_cmd_notify_cw_change, NULL,
1764 "<channel_width> = 0 - 20 MHz, 1 - 40 MHz, 2 - 80 MHz, 3 - 160 MHz" },
1651 { "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL,1765 { "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL,
1652 "<addr> <url>\n"1766 "<addr> <url>\n"
1653 " = send WNM-Notification Subscription Remediation Request" },1767 " = send WNM-Notification Subscription Remediation Request" },
@@ -1661,10 +1775,20 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
1661 "= enable hostapd on current interface" },1775 "= enable hostapd on current interface" },
1662 { "reload", hostapd_cli_cmd_reload, NULL,1776 { "reload", hostapd_cli_cmd_reload, NULL,
1663 "= reload configuration for current interface" },1777 "= reload configuration for current interface" },
1778 { "reload_bss", hostapd_cli_cmd_reload_bss, NULL,
1779 "= reload configuration for current BSS" },
1780 { "reload_config", hostapd_cli_cmd_reload_config, NULL,
1781 "= reload configuration for current interface" },
1664 { "disable", hostapd_cli_cmd_disable, NULL,1782 { "disable", hostapd_cli_cmd_disable, NULL,
1665 "= disable hostapd on current interface" },1783 "= disable hostapd on current interface" },
1784 { "enable_mld", hostapd_cli_cmd_enable_mld, NULL,
1785 "= enable AP MLD to which the interface is affiliated" },
1786 { "disable_mld", hostapd_cli_cmd_disable_mld, NULL,
1787 "= disable AP MLD to which the interface is affiliated" },
1666 { "update_beacon", hostapd_cli_cmd_update_beacon, NULL,1788 { "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
1667 "= update Beacon frame contents\n"},1789 "= update Beacon frame contents\n"},
1790 { "stop_ap", hostapd_cli_cmd_stop_ap, NULL,
1791 "= stop AP\n"},
1668 { "erp_flush", hostapd_cli_cmd_erp_flush, NULL,1792 { "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
1669 "= drop all ERP keys"},1793 "= drop all ERP keys"},
1670 { "log_level", hostapd_cli_cmd_log_level, NULL,1794 { "log_level", hostapd_cli_cmd_log_level, NULL,
@@ -1686,6 +1810,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
1686 " = send FTM range request"},1810 " = send FTM range request"},
1687 { "driver_flags", hostapd_cli_cmd_driver_flags, NULL,1811 { "driver_flags", hostapd_cli_cmd_driver_flags, NULL,
1688 " = show supported driver flags"},1812 " = show supported driver flags"},
1813 { "driver_flags2", hostapd_cli_cmd_driver_flags2, NULL,
1814 " = show supported driver flags2"},
1689#ifdef CONFIG_DPP1815#ifdef CONFIG_DPP
1690 { "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,1816 { "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
1691 "report a scanned DPP URI from a QR Code" },1817 "report a scanned DPP URI from a QR Code" },
@@ -1729,6 +1855,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
1729 { "dpp_stop_chirp", hostapd_cli_cmd_dpp_stop_chirp, NULL,1855 { "dpp_stop_chirp", hostapd_cli_cmd_dpp_stop_chirp, NULL,
1730 "= stop DPP chirp" },1856 "= stop DPP chirp" },
1731#endif /* CONFIG_DPP2 */1857#endif /* CONFIG_DPP2 */
1858#ifdef CONFIG_DPP3
1859 { "dpp_push_button", hostapd_cli_cmd_dpp_push_button, NULL,
1860 "= press DPP push button" },
1861#endif /* CONFIG_DPP3 */
1732#endif /* CONFIG_DPP */1862#endif /* CONFIG_DPP */
1733 { "accept_acl", hostapd_cli_cmd_accept_macacl, NULL,1863 { "accept_acl", hostapd_cli_cmd_accept_macacl, NULL,
1734 "=Add/Delete/Show/Clear accept MAC ACL" },1864 "=Add/Delete/Show/Clear accept MAC ACL" },
@@ -1738,8 +1868,16 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
1738 "<addr> = poll a STA to check connectivity with a QoS null frame" },1868 "<addr> = poll a STA to check connectivity with a QoS null frame" },
1739 { "req_beacon", hostapd_cli_cmd_req_beacon, NULL,1869 { "req_beacon", hostapd_cli_cmd_req_beacon, NULL,
1740 "<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" },1870 "<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" },
1871 { "req_link_measurement", hostapd_cli_cmd_req_link_measurement, NULL,
1872 "<addr> = send a link measurement report request to a station"},
1741 { "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,1873 { "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,
1742 "= reload wpa_psk_file only" },1874 "= reload wpa_psk_file only" },
1875#ifdef CONFIG_IEEE80211R_AP
1876 { "reload_rxkhs", hostapd_cli_cmd_reload_rxkhs, NULL,
1877 "= reload R0KHs and R1KHs" },
1878 { "get_rxkhs", hostapd_cli_cmd_get_rxkhs, NULL,
1879 "= get R0KHs and R1KHs" },
1880#endif /* CONFIG_IEEE80211R_AP */
1743#ifdef ANDROID1881#ifdef ANDROID
1744 { "driver", hostapd_cli_cmd_driver, NULL,1882 { "driver", hostapd_cli_cmd_driver, NULL,
1745 "<driver sub command> [<hex formatted data>] = send driver command data" },1883 "<driver sub command> [<hex formatted data>] = send driver command data" },
@@ -2002,7 +2140,6 @@ static void hostapd_cli_interactive(void)
2002 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);2140 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
2003 }2141 }
20042142
2005 eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
2006 edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb,2143 edit_init(hostapd_cli_edit_cmd_cb, hostapd_cli_edit_eof_cb,
2007 hostapd_cli_edit_completion_cb, NULL, hfile, NULL);2144 hostapd_cli_edit_completion_cb, NULL, hfile, NULL);
2008 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);2145 eloop_register_timeout(ping_interval, 0, hostapd_cli_ping, NULL, NULL);
@@ -2026,40 +2163,46 @@ static void hostapd_cli_cleanup(void)
2026}2163}
20272164
20282165
2029static void hostapd_cli_action(struct wpa_ctrl *ctrl)2166static void hostapd_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
2030{2167{
2031 fd_set rfds;2168 struct wpa_ctrl *ctrl = eloop_ctx;
2032 int fd, res;
2033 struct timeval tv;
2034 char buf[256];2169 char buf[256];
2035 size_t len;2170 size_t len;
20362171
2037 fd = wpa_ctrl_get_fd(ctrl);2172 /* verify that connection is still working */
2173 len = sizeof(buf) - 1;
2174 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2175 hostapd_cli_action_cb) < 0 ||
2176 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2177 printf("hostapd did not reply to PING command - exiting\n");
2178 eloop_terminate();
2179 return;
2180 }
2181 eloop_register_timeout(ping_interval, 0, hostapd_cli_action_ping,
2182 ctrl, NULL);
2183}
20382184
2039 while (!hostapd_cli_quit) {
2040 FD_ZERO(&rfds);
2041 FD_SET(fd, &rfds);
2042 tv.tv_sec = ping_interval;
2043 tv.tv_usec = 0;
2044 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2045 if (res < 0 && errno != EINTR) {
2046 perror("select");
2047 break;
2048 }
20492185
2050 if (FD_ISSET(fd, &rfds))2186static void hostapd_cli_action_receive(int sock, void *eloop_ctx,
2051 hostapd_cli_recv_pending(ctrl, 0, 1);2187 void *sock_ctx)
2052 else {2188{
2053 len = sizeof(buf) - 1;2189 struct wpa_ctrl *ctrl = eloop_ctx;
2054 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,2190
2055 hostapd_cli_action_process) < 0 ||2191 hostapd_cli_recv_pending(ctrl, 0, 1);
2056 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {2192}
2057 printf("hostapd did not reply to PING "2193
2058 "command - exiting\n");2194
2059 break;2195static void hostapd_cli_action(struct wpa_ctrl *ctrl)
2060 }2196{
2061 }2197 int fd;
2062 }2198
2199 fd = wpa_ctrl_get_fd(ctrl);
2200 eloop_register_timeout(ping_interval, 0, hostapd_cli_action_ping,
2201 ctrl, NULL);
2202 eloop_register_read_sock(fd, hostapd_cli_action_receive, ctrl, NULL);
2203 eloop_run();
2204 eloop_cancel_timeout(hostapd_cli_action_ping, ctrl, NULL);
2205 eloop_unregister_read_sock(fd);
2063}2206}
20642207
20652208
@@ -2162,6 +2305,8 @@ int main(int argc, char *argv[])
2162 continue;2305 continue;
2163 }2306 }
21642307
2308 eloop_register_signal_terminate(hostapd_cli_eloop_terminate, NULL);
2309
2165 if (action_file && !hostapd_cli_attached)2310 if (action_file && !hostapd_cli_attached)
2166 return -1;2311 return -1;
2167 if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())2312 if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
diff --git a/hostapd/main.c b/hostapd/main.c
index c9ec38d..00e02bb 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -15,6 +15,7 @@
15#include "utils/common.h"15#include "utils/common.h"
16#include "utils/eloop.h"16#include "utils/eloop.h"
17#include "utils/uuid.h"17#include "utils/uuid.h"
18#include "crypto/crypto.h"
18#include "crypto/random.h"19#include "crypto/random.h"
19#include "crypto/tls.h"20#include "crypto/tls.h"
20#include "common/version.h"21#include "common/version.h"
@@ -157,14 +158,50 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
157 struct hostapd_bss_config *conf = hapd->conf;158 struct hostapd_bss_config *conf = hapd->conf;
158 u8 *b = conf->bssid;159 u8 *b = conf->bssid;
159 struct wpa_driver_capa capa;160 struct wpa_driver_capa capa;
161#ifdef CONFIG_IEEE80211BE
162 struct hostapd_data *h_hapd = NULL;
163#endif /* CONFIG_IEEE80211BE */
160164
161 if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {165 if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
162 wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");166 wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
163 return -1;167 return -1;
164 }168 }
165169
170#ifdef CONFIG_IEEE80211BE
171 if (conf->mld_ap)
172 h_hapd = hostapd_mld_get_first_bss(hapd);
173
174 if (h_hapd) {
175 hapd->drv_priv = h_hapd->drv_priv;
176 hapd->interface_added = h_hapd->interface_added;
177
178 /*
179 * All interfaces participating in the AP MLD would have
180 * the same MLD address, which is the interface hardware
181 * address, while the interface address would be
182 * derived from the original interface address if BSSID
183 * is not configured, and otherwise it would be the
184 * configured BSSID.
185 */
186 if (is_zero_ether_addr(b)) {
187 os_memcpy(hapd->own_addr, h_hapd->mld->mld_addr,
188 ETH_ALEN);
189 random_mac_addr_keep_oui(hapd->own_addr);
190 } else {
191 os_memcpy(hapd->own_addr, b, ETH_ALEN);
192 }
193
194 hostapd_mld_add_link(hapd);
195 wpa_printf(MSG_DEBUG,
196 "Setup of non first link (%d) BSS of MLD %s",
197 hapd->mld_link_id, hapd->conf->iface);
198
199 goto setup_mld;
200 }
201#endif /* CONFIG_IEEE80211BE */
202
166 /* Initialize the driver interface */203 /* Initialize the driver interface */
167 if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))204 if (is_zero_ether_addr(b))
168 b = NULL;205 b = NULL;
169206
170 os_memset(&params, 0, sizeof(params));207 os_memset(&params, 0, sizeof(params));
@@ -188,6 +225,19 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
188 break;225 break;
189 }226 }
190 params.bssid = b;227 params.bssid = b;
228#ifdef CONFIG_IEEE80211BE
229 /*
230 * Use the configured MLD MAC address as the interface hardware address
231 * if this AP is a part of an AP MLD.
232 */
233 if (hapd->conf->mld_ap) {
234 if (!is_zero_ether_addr(hapd->conf->mld_addr))
235 params.bssid = hapd->conf->mld_addr;
236 else
237 params.bssid = NULL;
238 }
239#endif /* CONFIG_IEEE80211BE */
240
191 params.ifname = hapd->conf->iface;241 params.ifname = hapd->conf->iface;
192 params.driver_params = hapd->iconf->driver_params;242 params.driver_params = hapd->iconf->driver_params;
193 params.use_pae_group_addr = hapd->conf->use_pae_group_addr;243 params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
@@ -213,12 +263,36 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
213 return -1;263 return -1;
214 }264 }
215265
266#ifdef CONFIG_IEEE80211BE
267 /*
268 * This is the first interface added to the AP MLD, so have the
269 * interface hardware address be the MLD address, while the link address
270 * would be derived from the original interface address if BSSID is not
271 * configured, and otherwise it would be the configured BSSID.
272 */
273 if (hapd->conf->mld_ap) {
274 os_memcpy(hapd->mld->mld_addr, hapd->own_addr, ETH_ALEN);
275
276 if (!b)
277 random_mac_addr_keep_oui(hapd->own_addr);
278 else
279 os_memcpy(hapd->own_addr, b, ETH_ALEN);
280
281 hostapd_mld_add_link(hapd);
282 wpa_printf(MSG_DEBUG, "Setup of first link (%d) BSS of MLD %s",
283 hapd->mld_link_id, hapd->conf->iface);
284 }
285
286setup_mld:
287#endif /* CONFIG_IEEE80211BE */
288
216 if (hapd->driver->get_capa &&289 if (hapd->driver->get_capa &&
217 hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {290 hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
218 struct wowlan_triggers *triggs;291 struct wowlan_triggers *triggs;
219292
220 iface->drv_flags = capa.flags;293 iface->drv_flags = capa.flags;
221 iface->drv_flags2 = capa.flags2;294 iface->drv_flags2 = capa.flags2;
295 iface->drv_rrm_flags = capa.rrm_flags;
222 iface->probe_resp_offloads = capa.probe_resp_offloads;296 iface->probe_resp_offloads = capa.probe_resp_offloads;
223 /*297 /*
224 * Use default extended capa values from per-radio information298 * Use default extended capa values from per-radio information
@@ -234,14 +308,41 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
234 */308 */
235 hostapd_get_ext_capa(iface);309 hostapd_get_ext_capa(iface);
236310
311 hostapd_get_mld_capa(iface);
312
237 triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa);313 triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa);
238 if (triggs && hapd->driver->set_wowlan) {314 if (triggs && hapd->driver->set_wowlan) {
239 if (hapd->driver->set_wowlan(hapd->drv_priv, triggs))315 if (hapd->driver->set_wowlan(hapd->drv_priv, triggs))
240 wpa_printf(MSG_ERROR, "set_wowlan failed");316 wpa_printf(MSG_ERROR, "set_wowlan failed");
241 }317 }
242 os_free(triggs);318 os_free(triggs);
319
320 iface->mbssid_max_interfaces = capa.mbssid_max_interfaces;
321 iface->ema_max_periodicity = capa.ema_max_periodicity;
243 }322 }
244323
324#ifdef CONFIG_IEEE80211BE
325 if (hapd->conf->mld_ap) {
326 if (!(iface->drv_flags2 & WPA_DRIVER_FLAGS2_MLO)) {
327 wpa_printf(MSG_INFO,
328 "MLD: Not supported by the driver");
329 return -1;
330 }
331
332 /* Initialize the BSS parameter change to 1 */
333 hapd->eht_mld_bss_param_change = 1;
334
335 wpa_printf(MSG_DEBUG,
336 "MLD: Set link_id=%u, mld_addr=" MACSTR
337 ", own_addr=" MACSTR,
338 hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr),
339 MAC2STR(hapd->own_addr));
340
341 hostapd_drv_link_add(hapd, hapd->mld_link_id,
342 hapd->own_addr);
343 }
344#endif /* CONFIG_IEEE80211BE */
345
245 return 0;346 return 0;
246}347}
247348
@@ -454,7 +555,7 @@ static void show_version(void)
454 "hostapd v%s\n"555 "hostapd v%s\n"
455 "User space daemon for IEEE 802.11 AP management,\n"556 "User space daemon for IEEE 802.11 AP management,\n"
456 "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"557 "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
457 "Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> "558 "Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> "
458 "and contributors\n",559 "and contributors\n",
459 VERSION_STR);560 VERSION_STR);
460}561}
@@ -465,7 +566,7 @@ static void usage(void)
465 show_version();566 show_version();
466 fprintf(stderr,567 fprintf(stderr,
467 "\n"568 "\n"
468 "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] "569 "usage: hostapd [-hdBKtvq] [-P <PID file>] [-e <entropy file>] "
469 "\\\n"570 "\\\n"
470 " [-g <global ctrl_iface>] [-G <group>]\\\n"571 " [-g <global ctrl_iface>] [-G <group>]\\\n"
471 " [-i <comma-separated list of interface names>]\\\n"572 " [-i <comma-separated list of interface names>]\\\n"
@@ -493,7 +594,8 @@ static void usage(void)
493#endif /* CONFIG_DEBUG_SYSLOG */594#endif /* CONFIG_DEBUG_SYSLOG */
494 " -S start all the interfaces synchronously\n"595 " -S start all the interfaces synchronously\n"
495 " -t include timestamps in some debug messages\n"596 " -t include timestamps in some debug messages\n"
496 " -v show hostapd version\n");597 " -v show hostapd version\n"
598 " -q show less debug messages (-qq for even less)\n");
497599
498 exit(1);600 exit(1);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches