]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Add ctrl_iface message for AP mode connection rejection
authorRaja Mani <rmani@qca.qualcomm.com>
Thu, 7 Feb 2013 13:24:53 +0000 (15:24 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 7 Feb 2013 13:24:53 +0000 (15:24 +0200)
When AP mode operation reject the client, nl80211 layer advertises the
connect failed event with the reason for failures (for example, max
client reached, etc.) using NL80211_CMD_CONN_FAILED.

This patch adds some debug messages whenever such an event is received
from the nl80211 layer and also the same event is posted to the upper
layer via wpa_msg().

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
src/ap/drv_callbacks.c
src/ap/hostapd.h
src/common/wpa_ctrl.h
src/drivers/driver.h
src/drivers/driver_common.c
src/drivers/driver_nl80211.c
wpa_supplicant/events.c

index 8980bec03f8b1e1aa3910ec0f13022fc33c4bf84..6d22d495173ef40b9772d10c28b445234088089b 100644 (file)
@@ -13,6 +13,7 @@
 #include "drivers/driver.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
+#include "common/wpa_ctrl.h"
 #include "crypto/random.h"
 #include "p2p/p2p.h"
 #include "wps/wps.h"
@@ -393,6 +394,22 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
 }
 
 
+void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
+                                        const u8 *addr, int reason_code)
+{
+       switch (reason_code) {
+       case MAX_CLIENT_REACHED:
+               wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR,
+                       MAC2STR(addr));
+               break;
+       case BLOCKED_CLIENT:
+               wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR,
+                       MAC2STR(addr));
+               break;
+       }
+}
+
+
 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
                         const u8 *bssid, const u8 *ie, size_t ie_len,
                         int ssi_signal)
@@ -828,6 +845,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                        data->ch_switch.ht_enabled,
                                        data->ch_switch.ch_offset);
                break;
+       case EVENT_CONNECT_FAILED_REASON:
+               if (!data)
+                       break;
+               hostapd_event_connect_failed_reason(
+                       hapd, data->connect_failed_reason.addr,
+                       data->connect_failed_reason.code);
+               break;
        default:
                wpa_printf(MSG_DEBUG, "Unknown event %d", event);
                break;
index 2827232a3865b095178c169e7f77fe8076391da7..8ab4f3e0e76466d98add669faf5a5470a8d973df 100644 (file)
@@ -305,6 +305,8 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
                        const u8 *ie, size_t ielen, int reassoc);
 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
 void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr);
+void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
+                                        const u8 *addr, int reason_code);
 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
                         const u8 *bssid, const u8 *ie, size_t ie_len,
                         int ssi_signal);
index bb9b5587f26b29640a1b520d87cecf82cebbffbf..46e8dc75b0e6fcf22ac90407113711cdc41b8520 100644 (file)
@@ -146,6 +146,8 @@ extern "C" {
 #define AP_STA_CONNECTED "AP-STA-CONNECTED "
 #define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
 
+#define AP_REJECTED_MAX_STA "AP-REJECTED-MAX-STA "
+#define AP_REJECTED_BLOCKED_STA "AP-REJECTED-BLOCKED-STA "
 
 /* BSS command information masks */
 
index b981172b088635d791478bd47f935c5c7c7ca6f8..b57ea7551afdd435b7e9bcd02c27234fbc6ab174 100644 (file)
@@ -3056,7 +3056,16 @@ enum wpa_event_type {
         *
         * This event can be used to request a WNM operation to be performed.
         */
-       EVENT_WNM
+       EVENT_WNM,
+
+       /**
+        * EVENT_CONNECT_FAILED_REASON - Connection failure reason in AP mode
+        *
+        * This event indicates that the driver reported a connection failure
+        * with the specified client (for example, max client reached, etc.) in
+        * AP mode.
+        */
+       EVENT_CONNECT_FAILED_REASON
 };
 
 
@@ -3681,6 +3690,19 @@ union wpa_event_data {
                int ht_enabled;
                int ch_offset;
        } ch_switch;
+
+       /**
+        * struct connect_failed - Data for EVENT_CONNECT_FAILED_REASON
+        * @addr: Remote client address
+        * @code: Reason code for connection failure
+        */
+       struct connect_failed_reason {
+               u8 addr[ETH_ALEN];
+               enum {
+                       MAX_CLIENT_REACHED,
+                       BLOCKED_CLIENT
+               } code;
+       } connect_failed_reason;
 };
 
 /**
index 418cf1a064f7ae299de543fe3a89aeb1b67dd2c2..565a01bdb906df9476da5c21e33c74d3ebc1f8bb 100644 (file)
@@ -79,6 +79,7 @@ const char * event_to_string(enum wpa_event_type event)
        E2S(EAPOL_TX_STATUS);
        E2S(CH_SWITCH);
        E2S(WNM);
+       E2S(CONNECT_FAILED_REASON);
        }
 
        return "UNKNOWN";
index 593bca565c0c4782062c3447927e51e803623916..e4b70fe163ebd7452ede8f8cd08e4cdee9c40fbe 100644 (file)
@@ -2153,6 +2153,43 @@ static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
 }
 
 
+static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
+                                        struct nlattr **tb)
+{
+       union wpa_event_data data;
+       u32 reason;
+
+       wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
+
+       if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
+               return;
+
+       os_memset(&data, 0, sizeof(data));
+       os_memcpy(data.connect_failed_reason.addr,
+                 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
+
+       reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
+       switch (reason) {
+       case NL80211_CONN_FAIL_MAX_CLIENTS:
+               wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
+               data.connect_failed_reason.code = MAX_CLIENT_REACHED;
+               break;
+       case NL80211_CONN_FAIL_BLOCKED_CLIENT:
+               wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
+                          " tried to connect",
+                          MAC2STR(data.connect_failed_reason.addr));
+               data.connect_failed_reason.code = BLOCKED_CLIENT;
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
+                          "%u", reason);
+               return;
+       }
+
+       wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
+}
+
+
 static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
                                   int wds)
 {
@@ -2290,6 +2327,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
        case NL80211_CMD_TDLS_OPER:
                nl80211_tdls_oper_event(drv, tb);
                break;
+       case NL80211_CMD_CONN_FAILED:
+               nl80211_connect_failed_event(drv, tb);
+               break;
        default:
                wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
                           "(cmd=%d)", cmd);
index 3196352bde51f02306cd36669095531124020c12..c3e54d32eec6b09cd097c90654ba94f9a25b47fb 100644 (file)
@@ -2962,6 +2962,16 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                wpas_wps_start_pbc(wpa_s, NULL, 0);
 #endif /* CONFIG_WPS */
                break;
+       case EVENT_CONNECT_FAILED_REASON:
+#ifdef CONFIG_AP
+               if (!wpa_s->ap_iface || !data)
+                       break;
+               hostapd_event_connect_failed_reason(
+                       wpa_s->ap_iface->bss[0],
+                       data->connect_failed_reason.addr,
+                       data->connect_failed_reason.code);
+#endif /* CONFIG_AP */
+               break;
        default:
                wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
                break;