hostapd: Fix internal crypto build without TLS
[wpasupplicant] / wpa_supplicant / mlme.c
index 82d7897..e894c46 100644 (file)
@@ -20,8 +20,8 @@
 #include "eloop.h"
 #include "config_ssid.h"
 #include "wpa_supplicant_i.h"
+#include "driver_i.h"
 #include "wpa.h"
-#include "drivers/driver.h"
 #include "ieee802_11_defs.h"
 #include "ieee802_11_common.h"
 #include "mlme.h"
@@ -94,14 +94,15 @@ static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s);
 static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s);
 static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx);
 static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx);
+static void ieee80211_build_tspec(struct wpabuf *buf);
 
 
 static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s,
-                                    wpa_hw_mode phymode, int chan,
+                                    hostapd_hw_mode phymode, int chan,
                                     int freq)
 {
        size_t i;
-       struct wpa_hw_modes *mode;
+       struct hostapd_hw_modes *mode;
 
        for (i = 0; i < wpa_s->mlme.num_modes; i++) {
                mode = &wpa_s->mlme.modes[i];
@@ -338,7 +339,7 @@ static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s)
        blen = 0;
 
        capab = wpa_s->mlme.capab;
-       if (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G) {
+       if (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G) {
                capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
                        WLAN_CAPABILITY_SHORT_PREAMBLE;
        }
@@ -669,7 +670,7 @@ static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
        supp_rates[0] = WLAN_EID_SUPP_RATES;
        supp_rates[1] = 0;
        for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) {
-               struct wpa_rate_data *rate = &wpa_s->mlme.curr_rates[i];
+               struct hostapd_rate_data *rate = &wpa_s->mlme.curr_rates[i];
                if (esupp_rates) {
                        pos = buf + len;
                        len++;
@@ -876,12 +877,36 @@ static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s,
        case WLAN_AUTH_FT:
        {
                union wpa_event_data data;
+               struct wpabuf *ric = NULL;
                os_memset(&data, 0, sizeof(data));
                data.ft_ies.ies = mgmt->u.auth.variable;
                data.ft_ies.ies_len = len -
                        (mgmt->u.auth.variable - (u8 *) mgmt);
                os_memcpy(data.ft_ies.target_ap, wpa_s->bssid, ETH_ALEN);
+               if (os_strcmp(wpa_s->driver->name, "test") == 0 &&
+                   wpa_s->mlme.wmm_enabled) {
+                       ric = wpabuf_alloc(200);
+                       if (ric) {
+                               /* Build simple RIC-Request: RDIE | TSPEC */
+
+                               /* RIC Data (RDIE) */
+                               wpabuf_put_u8(ric, WLAN_EID_RIC_DATA);
+                               wpabuf_put_u8(ric, 4);
+                               wpabuf_put_u8(ric, 0); /* RDIE Identifier */
+                               wpabuf_put_u8(ric, 1); /* Resource Descriptor
+                                                       * Count */
+                               wpabuf_put_le16(ric, 0); /* Status Code */
+
+                               /* WMM TSPEC */
+                               ieee80211_build_tspec(ric);
+
+                               data.ft_ies.ric_ies = wpabuf_head(ric);
+                               data.ft_ies.ric_ies_len = wpabuf_len(ric);
+                       }
+               }
+
                wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data);
+               wpabuf_free(ric);
                ieee80211_auth_completed(wpa_s);
                break;
        }
@@ -1012,6 +1037,66 @@ static int ieee80211_ft_assoc_resp(struct wpa_supplicant *wpa_s,
 }
 
 
+static void ieee80211_build_tspec(struct wpabuf *buf)
+{
+       struct wmm_tspec_element *tspec;
+       int tid, up;
+
+       tspec = wpabuf_put(buf, sizeof(*tspec));
+       tspec->eid = WLAN_EID_VENDOR_SPECIFIC;
+       tspec->length = sizeof(*tspec) - 2;
+       tspec->oui[0] = 0x00;
+       tspec->oui[1] = 0x50;
+       tspec->oui[2] = 0xf2;
+       tspec->oui_type = 2;
+       tspec->oui_subtype = 2;
+       tspec->version = 1;
+
+       tid = 1;
+       up = 6; /* Voice */
+       tspec->ts_info[0] = (tid << 1) |
+               (WMM_TSPEC_DIRECTION_BI_DIRECTIONAL << 5) |
+               BIT(7);
+       tspec->ts_info[1] = up << 3;
+       tspec->nominal_msdu_size = host_to_le16(1530);
+       tspec->mean_data_rate = host_to_le32(128000); /* bits per second */
+       tspec->minimum_phy_rate = host_to_le32(6000000);
+       tspec->surplus_bandwidth_allowance = host_to_le16(0x3000); /* 150% */
+}
+
+
+static void ieee80211_tx_addts(struct wpa_supplicant *wpa_s)
+{
+       struct wpabuf *buf;
+       struct ieee80211_mgmt *mgmt;
+       size_t alen;
+
+       wpa_printf(MSG_DEBUG, "MLME: Send ADDTS Request for Voice TSPEC");
+       mgmt = NULL;
+       alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt;
+
+       buf = wpabuf_alloc(alen + sizeof(struct wmm_tspec_element));
+       if (buf == NULL)
+               return;
+
+       mgmt = wpabuf_put(buf, alen);
+       os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
+       os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
+       os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
+       mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+                                          WLAN_FC_STYPE_ACTION);
+       mgmt->u.action.category = WLAN_ACTION_WMM;
+       mgmt->u.action.u.wmm_action.action_code = WMM_ACTION_CODE_ADDTS_REQ;
+       mgmt->u.action.u.wmm_action.dialog_token = 1;
+       mgmt->u.action.u.wmm_action.status_code = 0;
+
+       ieee80211_build_tspec(buf);
+
+       ieee80211_sta_tx(wpa_s, wpabuf_head(buf), wpabuf_len(buf));
+       wpabuf_free(buf);
+}
+
+
 static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
                                         struct ieee80211_mgmt *mgmt,
                                         size_t len,
@@ -1162,6 +1247,13 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
                ieee80211_sta_wmm_params(wpa_s, elems.wmm, elems.wmm_len);
 
        ieee80211_associated(wpa_s);
+
+       if (wpa_s->mlme.auth_alg != WLAN_AUTH_FT &&
+           os_strcmp(wpa_s->driver->name, "test") == 0 &&
+           elems.wmm && wpa_s->mlme.wmm_enabled) {
+               /* Test WMM-AC - send ADDTS for WMM TSPEC */
+               ieee80211_tx_addts(wpa_s);
+       }
 }
 
 
@@ -1508,8 +1600,8 @@ static void ieee80211_bss_info(struct wpa_supplicant *wpa_s,
        bss->channel = channel;
        bss->freq = wpa_s->mlme.freq;
        if (channel != wpa_s->mlme.channel &&
-           (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G ||
-            wpa_s->mlme.phymode == WPA_MODE_IEEE80211B) &&
+           (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G ||
+            wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211B) &&
            channel >= 1 && channel <= 14) {
                static const int freq_list[] = {
                        2412, 2417, 2422, 2427, 2432, 2437, 2442,
@@ -1788,6 +1880,119 @@ static void ieee80211_rx_mgmt_sa_query_action(
 #endif /* CONFIG_IEEE80211W */
 
 
+static void dump_tspec(struct wmm_tspec_element *tspec)
+{
+       int up, psb, dir, tid;
+       u16 val;
+
+       up = (tspec->ts_info[1] >> 3) & 0x07;
+       psb = (tspec->ts_info[1] >> 2) & 0x01;
+       dir = (tspec->ts_info[0] >> 5) & 0x03;
+       tid = (tspec->ts_info[0] >> 1) & 0x0f;
+       wpa_printf(MSG_DEBUG, "WMM: TS Info: UP=%d PSB=%d Direction=%d TID=%d",
+                  up, psb, dir, tid);
+       val = le_to_host16(tspec->nominal_msdu_size);
+       wpa_printf(MSG_DEBUG, "WMM: Nominal MSDU Size: %d%s",
+                  val & 0x7fff, val & 0x8000 ? " (fixed)" : "");
+       wpa_printf(MSG_DEBUG, "WMM: Mean Data Rate: %u bps",
+                  le_to_host32(tspec->mean_data_rate));
+       wpa_printf(MSG_DEBUG, "WMM: Minimum PHY Rate: %u bps",
+                  le_to_host32(tspec->minimum_phy_rate));
+       val = le_to_host16(tspec->surplus_bandwidth_allowance);
+       wpa_printf(MSG_DEBUG, "WMM: Surplus Bandwidth Allowance: %u.%04u",
+                  val >> 13, 10000 * (val & 0x1fff) / 0x2000);
+       val = le_to_host16(tspec->medium_time);
+       wpa_printf(MSG_DEBUG, "WMM: Medium Time: %u (= %u usec/sec)",
+                  val, 32 * val);
+}
+
+
+static int is_wmm_tspec(const u8 *ie, size_t len)
+{
+       const struct wmm_tspec_element *tspec;
+
+       if (len < sizeof(*tspec))
+               return 0;
+
+       tspec = (const struct wmm_tspec_element *) ie;
+       if (tspec->eid != WLAN_EID_VENDOR_SPECIFIC ||
+           tspec->length < sizeof(*tspec) - 2 ||
+           tspec->oui[0] != 0x00 || tspec->oui[1] != 0x50 ||
+           tspec->oui[2] != 0xf2 || tspec->oui_type != 2 ||
+           tspec->oui_subtype != 2 || tspec->version != 1)
+               return 0;
+
+       return 1;
+}
+
+
+static void ieee80211_rx_addts_resp(
+       struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
+       size_t var_len)
+{
+       struct wmm_tspec_element *tspec;
+
+       wpa_printf(MSG_DEBUG, "WMM: Received ADDTS Response");
+       wpa_hexdump(MSG_MSGDUMP, "WMM: ADDTS Response IE(s)",
+                   mgmt->u.action.u.wmm_action.variable, var_len);
+       if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len))
+               return;
+       tspec = (struct wmm_tspec_element *)
+               mgmt->u.action.u.wmm_action.variable;
+       dump_tspec(tspec);
+}
+
+
+static void ieee80211_rx_delts(
+       struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
+       size_t var_len)
+{
+       struct wmm_tspec_element *tspec;
+
+       wpa_printf(MSG_DEBUG, "WMM: Received DELTS");
+       wpa_hexdump(MSG_MSGDUMP, "WMM: DELTS IE(s)",
+                   mgmt->u.action.u.wmm_action.variable, var_len);
+       if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len))
+               return;
+       tspec = (struct wmm_tspec_element *)
+               mgmt->u.action.u.wmm_action.variable;
+       dump_tspec(tspec);
+}
+
+
+static void ieee80211_rx_mgmt_wmm_action(
+       struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
+       struct ieee80211_rx_status *rx_status)
+{
+       size_t alen;
+
+       alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt;
+       if (len < alen) {
+               wpa_printf(MSG_DEBUG, "WMM: Received Action frame too short");
+               return;
+       }
+
+       wpa_printf(MSG_DEBUG, "WMM: Received Action frame: Action Code %d, "
+                  "Dialog Token %d, Status Code %d",
+                  mgmt->u.action.u.wmm_action.action_code,
+                  mgmt->u.action.u.wmm_action.dialog_token,
+                  mgmt->u.action.u.wmm_action.status_code);
+
+       switch (mgmt->u.action.u.wmm_action.action_code) {
+       case WMM_ACTION_CODE_ADDTS_RESP:
+               ieee80211_rx_addts_resp(wpa_s, mgmt, len, len - alen);
+               break;
+       case WMM_ACTION_CODE_DELTS:
+               ieee80211_rx_delts(wpa_s, mgmt, len, len - alen);
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "WMM: Unsupported Action Code %d",
+                          mgmt->u.action.u.wmm_action.action_code);
+               break;
+       }
+}
+
+
 static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s,
                                     struct ieee80211_mgmt *mgmt,
                                     size_t len,
@@ -1809,6 +2014,9 @@ static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s,
                ieee80211_rx_mgmt_sa_query_action(wpa_s, mgmt, len, rx_status);
                break;
 #endif /* CONFIG_IEEE80211W */
+       case WLAN_ACTION_WMM:
+               ieee80211_rx_mgmt_wmm_action(wpa_s, mgmt, len, rx_status);
+               break;
        default:
                wpa_printf(MSG_DEBUG, "MLME: unknown Action Category %d",
                           mgmt->u.action.category);
@@ -2484,14 +2692,14 @@ static int ieee80211_active_scan(struct wpa_supplicant *wpa_s)
        int c;
 
        for (m = 0; m < wpa_s->mlme.num_modes; m++) {
-               struct wpa_hw_modes *mode = &wpa_s->mlme.modes[m];
+               struct hostapd_hw_modes *mode = &wpa_s->mlme.modes[m];
                if ((int) mode->mode != (int) wpa_s->mlme.phymode)
                        continue;
                for (c = 0; c < mode->num_channels; c++) {
-                       struct wpa_channel_data *chan = &mode->channels[c];
-                       if (chan->flag & WPA_CHAN_W_SCAN &&
+                       struct hostapd_channel_data *chan = &mode->channels[c];
+                       if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
                            chan->chan == wpa_s->mlme.channel) {
-                               if (chan->flag & WPA_CHAN_W_ACTIVE_SCAN)
+                               if (!(chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN))
                                        return 1;
                                break;
                        }
@@ -2505,8 +2713,8 @@ static int ieee80211_active_scan(struct wpa_supplicant *wpa_s)
 static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx)
 {
        struct wpa_supplicant *wpa_s = eloop_ctx;
-       struct wpa_hw_modes *mode;
-       struct wpa_channel_data *chan;
+       struct hostapd_hw_modes *mode;
+       struct hostapd_channel_data *chan;
        int skip = 0;
        int timeout = 0;
        struct wpa_ssid *ssid = wpa_s->current_ssid;
@@ -2545,10 +2753,10 @@ static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx)
                }
                skip = !(wpa_s->mlme.hw_modes & (1 << mode->mode));
                chan = &mode->channels[wpa_s->mlme.scan_channel_idx];
-               if (!(chan->flag & WPA_CHAN_W_SCAN) ||
-                   (adhoc && !(chan->flag & WPA_CHAN_W_IBSS)) ||
-                   (wpa_s->mlme.hw_modes & (1 << WPA_MODE_IEEE80211G) &&
-                    mode->mode == WPA_MODE_IEEE80211B &&
+               if ((chan->flag & HOSTAPD_CHAN_DISABLED) ||
+                   (adhoc && (chan->flag & HOSTAPD_CHAN_NO_IBSS)) ||
+                   (wpa_s->mlme.hw_modes & (1 << HOSTAPD_MODE_IEEE80211G) &&
+                    mode->mode == HOSTAPD_MODE_IEEE80211B &&
                     wpa_s->mlme.scan_skip_11b))
                        skip = 1;
 
@@ -2811,7 +3019,7 @@ void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len,
 }
 
 
-void ieee80211_sta_free_hw_features(struct wpa_hw_modes *hw_features,
+void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
                                    size_t num_hw_features)
 {
        size_t i;
@@ -2842,9 +3050,9 @@ int ieee80211_sta_init(struct wpa_supplicant *wpa_s)
 
        wpa_s->mlme.num_modes = num_modes;
 
-       wpa_s->mlme.hw_modes = 1 << WPA_MODE_IEEE80211A;
-       wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211B;
-       wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211G;
+       wpa_s->mlme.hw_modes = 1 << HOSTAPD_MODE_IEEE80211A;
+       wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211B;
+       wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211G;
 
        wpa_s->mlme.wmm_enabled = 1;