[PATCH] hostapd: Add runtime testing option for association response
Raga, Gopi
gopiraga at amazon.com
Tue Mar 17 06:23:30 PDT 2026
On 10/03/2026, 2:51 PM, "Benjamin Berg" <benjamin at sipsolutions.net <benjamin at sipsolutions.net>> wrote:
> Could we maybe hook this into the TEST_FAIL infrastructure?
Hi Benjamin,
Thanks for the suggestion and for taking the time to review. I implemented a version using TEST_FAIL with the =value syntax you proposed, and it worked; however, I ran into a limitation.
The TEST_FAIL mechanism follows a countdown model (triggering on the Nth match), which works well for one-time or limited failures but does not support persistent or sticky behaviour by default.
For client robustness testing, we need the AP to consistently return the forced status code on every association attempt until it is explicitly disabled.
Because of this requirement, I chose to keep the simple dedicated control-interface option. It follows the same pattern as sae_commit_status and test_assoc_comeback_type, remains minimal in design, and provides the exact behaviour needed.
Regards,
Gopi Raga
From 5c6f4934c276725b16e73b600880e59a8d1fe88b Mon Sep 17 00:00:00 2001
From: Gopi Raga <gopiraga at amazon.com>
Date: Mon, 9 Mar 2026 18:33:23 +0530
Subject: [PATCH] hostapd: Add runtime testing option for association response
status code
This adds a new testing option that allows overriding the Status Code
in Association and Reassociation Response frames via the control
interface. The value stays active (sticky) for all frames until
explicitly disabled by setting it to -1.
Usage:
hostapd_cli SET test_assoc_response_status_code 17
hostapd_cli SET test_assoc_response_status_code disable # back to normal
This is useful for client robustness testing,
and negative testing of status codes (0, 1, 10, 12, 17, 30, etc.).
Signed-off-by: Gopi Raga <gopiraga at amazon.com>
---
hostapd/ctrl_iface.c | 9 +++++++++
src/ap/ap_config.c | 1 +
src/ap/ap_config.h | 1 +
src/ap/ieee802_11.c | 9 +++++++++
4 files changed, 20 insertions(+)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 248f808bb..2fd4582a3 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -1217,6 +1217,15 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
hapd->ext_mgmt_frame_handling = atoi(value);
} else if (os_strcasecmp(cmd, "ext_eapol_frame_io") == 0) {
hapd->ext_eapol_frame_io = atoi(value);
+ } else if (os_strcasecmp(cmd, "association_response_status_code") == 0) {
+ if (os_strcasecmp(value, "disable") == 0)
+ hapd->conf->association_response_status_code = -1;
+ else
+ hapd->conf->association_response_status_code =
+ atoi(value);
+ wpa_printf(MSG_DEBUG,
+ "TESTING: association_response_status_code=%d",
+ hapd->conf->association_response_status_code);
} else if (os_strcasecmp(cmd, "force_backlog_bytes") == 0) {
hapd->force_backlog_bytes = atoi(value);
#ifdef CONFIG_DPP
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 240a7e95a..c27bf4d06 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -170,6 +170,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
#ifdef CONFIG_TESTING_OPTIONS
bss->sae_commit_status = -1;
bss->test_assoc_comeback_type = -1;
+ bss->association_response_status_code = -1;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_PASN
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 065f43f55..7592db12b 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -709,6 +709,7 @@ struct hostapd_bss_config {
bool eapol_key_reserved_random;
int test_assoc_comeback_type;
struct wpabuf *presp_elements;
+ int association_response_status_code;
#ifdef CONFIG_IEEE80211BE
u16 eht_oper_puncturing_override;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index b768ca664..1dff78799 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -6452,6 +6452,15 @@ static void handle_assoc(struct hostapd_data *hapd,
}
#endif /* CONFIG_FILS */
+#ifdef CONFIG_TESTING_OPTIONS
+ if (hapd->conf->association_response_status_code >= 0) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: Forcing association response status code to %d",
+ hapd->conf->association_response_status_code);
+ resp = hapd->conf->association_response_status_code;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
if (resp >= 0)
reply_res = send_assoc_resp(hapd,
mld_addrs_not_translated ?
--
2.34.1
More information about the Hostap
mailing list