]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/drivers/driver_nl80211.c
Remove the GPL notification from files contributed by Jouni Malinen
[thirdparty/hostap.git] / src / drivers / driver_nl80211.c
index 6af8cc9cb1a22791031920b6ca6ea82b360d593f..07f92b822a298e6a53910413bc71a32876e0416f 100644 (file)
@@ -6,14 +6,8 @@
  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
  * Copyright (c) 2009-2010, Atheros Communications
  *
- * 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
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
  */
 
 #include "includes.h"
@@ -5127,24 +5121,32 @@ static int wpa_driver_nl80211_send_mntr(struct wpa_driver_nl80211_data *drv,
 
 static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
                                         const void *data, size_t len,
-                                        int encrypt, int noack)
+                                        int encrypt, int noack,
+                                        unsigned int freq, int no_cck,
+                                        int offchanok, unsigned int wait_time)
 {
        struct wpa_driver_nl80211_data *drv = bss->drv;
        u64 cookie;
 
+       if (freq == 0)
+               freq = bss->freq;
+
        if (drv->use_monitor)
                return wpa_driver_nl80211_send_mntr(drv, data, len,
                                                    encrypt, noack);
 
-       return nl80211_send_frame_cmd(bss, bss->freq, 0, data, len,
-                                     &cookie, 0, noack, 0);
+       return nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
+                                     &cookie, no_cck, noack, offchanok);
 }
 
 
-static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
-                                       size_t data_len, int noack)
+static int wpa_driver_nl80211_send_mlme_freq(struct i802_bss *bss,
+                                            const u8 *data,
+                                            size_t data_len, int noack,
+                                            unsigned int freq, int no_cck,
+                                            int offchanok,
+                                            unsigned int wait_time)
 {
-       struct i802_bss *bss = priv;
        struct wpa_driver_nl80211_data *drv = bss->drv;
        struct ieee80211_mgmt *mgmt;
        int encrypt = 1;
@@ -5161,15 +5163,20 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
                 * but it works due to the single-threaded nature
                 * of wpa_supplicant.
                 */
-               return nl80211_send_frame_cmd(bss, drv->last_mgmt_freq, 0,
+               if (freq == 0)
+                       freq = drv->last_mgmt_freq;
+               return nl80211_send_frame_cmd(bss, freq, 0,
                                              data, data_len, NULL, 1, noack,
                                              1);
        }
 
        if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
-               return nl80211_send_frame_cmd(bss, bss->freq, 0,
-                                             data, data_len, NULL,
-                                             0, noack, 0);
+               if (freq == 0)
+                       freq = bss->freq;
+               return nl80211_send_frame_cmd(bss, freq, 0,
+                                             data, data_len,
+                                             &drv->send_action_cookie,
+                                             no_cck, noack, offchanok);
        }
 
        if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
@@ -5187,7 +5194,17 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
        }
 
        return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
-                                            noack);
+                                            noack, freq, no_cck, offchanok,
+                                            wait_time);
+}
+
+
+static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
+                                       size_t data_len, int noack)
+{
+       struct i802_bss *bss = priv;
+       return wpa_driver_nl80211_send_mlme_freq(bss, data, data_len, noack,
+                                                0, 0, 0, 0);
 }
 
 
@@ -6232,7 +6249,8 @@ static int wpa_driver_nl80211_hapd_send_eapol(
        pos += 2;
        memcpy(pos, data, data_len);
 
-       res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0);
+       res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
+                                           0, 0, 0, 0);
        if (res < 0) {
                wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
                           "failed: %d (%s)",
@@ -6397,6 +6415,12 @@ retry:
        if (ret)
                goto nla_put_failure;
 
+       if (params->bssid && params->fixed_bssid) {
+               wpa_printf(MSG_DEBUG, "  * BSSID=" MACSTR,
+                          MAC2STR(params->bssid));
+               NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
+       }
+
        if (params->wpa_ie) {
                wpa_hexdump(MSG_DEBUG,
                            "  * Extra IEs for Beacon/Probe Response frames",
@@ -6618,6 +6642,16 @@ skip_auth_type:
                NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
        }
 
+       if (params->disable_ht)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
+
+       if (params->htcaps && params->htcaps_mask) {
+               int sz = sizeof(struct ieee80211_ht_capabilities);
+               NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
+               NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
+                       params->htcaps_mask);
+       }
+
        ret = nl80211_set_conn_keys(params, msg);
        if (ret)
                goto nla_put_failure;
@@ -6765,6 +6799,16 @@ static int wpa_driver_nl80211_associate(
                        params->prev_bssid);
        }
 
+       if (params->disable_ht)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
+
+       if (params->htcaps && params->htcaps_mask) {
+               int sz = sizeof(struct ieee80211_ht_capabilities);
+               NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
+               NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
+                       params->htcaps_mask);
+       }
+
        if (params->p2p)
                wpa_printf(MSG_DEBUG, "  * P2P group");
 
@@ -7778,10 +7822,15 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
                new_bss->ifindex = ifidx;
                new_bss->drv = drv;
                new_bss->next = drv->first_bss.next;
+               new_bss->freq = drv->first_bss.freq;
                drv->first_bss.next = new_bss;
                if (drv_priv)
                        *drv_priv = new_bss;
                nl80211_init_bss(new_bss);
+
+               /* Subscribe management frames for this WPA_IF_AP_BSS */
+               if (nl80211_setup_ap(new_bss))
+                       return -1;
        }
 #endif /* HOSTAPD */
 
@@ -7833,6 +7882,8 @@ static int wpa_driver_nl80211_if_remove(void *priv,
                for (tbss = &drv->first_bss; tbss; tbss = tbss->next) {
                        if (tbss->next == bss) {
                                tbss->next = bss->next;
+                               /* Unsubscribe management frames */
+                               nl80211_teardown_ap(bss);
                                nl80211_destroy_bss(bss);
                                os_free(bss);
                                bss = NULL;
@@ -7928,7 +7979,8 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
        struct ieee80211_hdr *hdr;
 
        wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
-                  "wait=%d ms no_cck=%d)", drv->ifindex, wait_time, no_cck);
+                  "freq=%u MHz wait=%d ms no_cck=%d)",
+                  drv->ifindex, freq, wait_time, no_cck);
 
        buf = os_zalloc(24 + data_len);
        if (buf == NULL)
@@ -7942,8 +7994,10 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
        os_memcpy(hdr->addr3, bssid, ETH_ALEN);
 
        if (is_ap_interface(drv->nlmode))
-               ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len,
-                                                  0);
+               ret = wpa_driver_nl80211_send_mlme_freq(priv, buf,
+                                                       24 + data_len,
+                                                       0, freq, no_cck, 1,
+                                                       wait_time);
        else
                ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
                                             24 + data_len,
@@ -8325,7 +8379,8 @@ static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
                              int encrypt)
 {
        struct i802_bss *bss = priv;
-       return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0);
+       return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
+                                            0, 0, 0, 0);
 }