/*
* hostapd / IEEE 802.11 Management
- * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "utils/eloop.h"
#include "crypto/crypto.h"
#include "drivers/driver.h"
+#include "common/ieee802_11_defs.h"
+#include "common/ieee802_11_common.h"
#include "common/wpa_ctrl.h"
#include "radius/radius.h"
#include "radius/radius_client.h"
}
+static void hostapd_sa_query_request(struct hostapd_data *hapd,
+ const struct ieee80211_mgmt *mgmt)
+{
+ struct sta_info *sta;
+ struct ieee80211_mgmt resp;
+ u8 *end;
+
+ wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Request from "
+ MACSTR, MAC2STR(mgmt->sa));
+ wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
+ mgmt->u.action.u.sa_query_resp.trans_id,
+ WLAN_SA_QUERY_TR_ID_LEN);
+
+ sta = ap_get_sta(hapd, mgmt->sa);
+ if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
+ wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignore SA Query Request "
+ "from unassociated STA " MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Response to "
+ MACSTR, MAC2STR(mgmt->sa));
+
+ os_memset(&resp, 0, sizeof(resp));
+ resp.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+ WLAN_FC_STYPE_ACTION);
+ os_memcpy(resp.da, mgmt->sa, ETH_ALEN);
+ os_memcpy(resp.sa, hapd->own_addr, ETH_ALEN);
+ os_memcpy(resp.bssid, hapd->own_addr, ETH_ALEN);
+ resp.u.action.category = WLAN_ACTION_SA_QUERY;
+ resp.u.action.u.sa_query_req.action = WLAN_SA_QUERY_RESPONSE;
+ os_memcpy(resp.u.action.u.sa_query_req.trans_id,
+ mgmt->u.action.u.sa_query_req.trans_id,
+ WLAN_SA_QUERY_TR_ID_LEN);
+ end = resp.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
+ if (hapd->drv.send_mgmt_frame(hapd, &resp, end - (u8 *) &resp) < 0)
+ perror("hostapd_sa_query_request: send");
+}
+
+
static void hostapd_sa_query_action(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt,
size_t len)
return;
}
+ if (mgmt->u.action.u.sa_query_resp.action == WLAN_SA_QUERY_REQUEST) {
+ hostapd_sa_query_request(hapd, mgmt);
+ return;
+ }
+
if (mgmt->u.action.u.sa_query_resp.action != WLAN_SA_QUERY_RESPONSE) {
wpa_printf(MSG_DEBUG, "IEEE 802.11: Unexpected SA Query "
"Action %d", mgmt->u.action.u.sa_query_resp.action);
hostapd_sa_query_action(hapd, mgmt, len);
return;
#endif /* CONFIG_IEEE80211W */
+ case WLAN_ACTION_PUBLIC:
+ if (hapd->public_action_cb) {
+ hapd->public_action_cb(hapd->public_action_cb_ctx,
+ (u8 *) mgmt, len,
+ hapd->iface->freq);
+ return;
+ }
+ break;
}
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
if (sta->flags & WLAN_STA_ASSOC)
new_assoc = 0;
sta->flags |= WLAN_STA_ASSOC;
- if (!hapd->conf->ieee802_1x && !hapd->conf->wpa) {
- /* Open or static WEP; no separate authorization */
+ if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
+ sta->auth_alg == WLAN_AUTH_FT) {
+ /*
+ * Open, static WEP, or FT protocol; no separate authorization
+ * step.
+ */
sta->flags |= WLAN_STA_AUTHORIZED;
wpa_msg(hapd->msg_ctx, MSG_INFO,
AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
#endif /* CONFIG_IEEE80211N */
- if (hapd->drv.sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid,
- sta->capability, sta->supported_rates,
- sta->supported_rates_len, sta->listen_interval,
+ if (hapd->drv.sta_add(hapd, sta->addr, sta->aid, sta->capability,
+ sta->supported_rates, sta->supported_rates_len,
+ sta->listen_interval,
sta->flags & WLAN_STA_HT ? &ht_cap : NULL)) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_NOTICE,